factor 0.3.1 → 0.5.04
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +19 -0
 - data/Gemfile +3 -0
 - data/Gemfile.lock +32 -0
 - data/README.md +10 -0
 - data/bin/factor +2 -10
 - data/factor.gemspec +24 -0
 - data/lib/cli.rb +21 -0
 - data/lib/commands/base.rb +106 -0
 - data/lib/commands/workflows.rb +115 -0
 - data/lib/factor.rb +4 -6
 - data/lib/factor/base.rb +17 -0
 - data/lib/factor/version.rb +6 -0
 - data/lib/listener.rb +48 -0
 - data/lib/runtime.rb +192 -0
 - data/lib/websocket_manager.rb +94 -0
 - metadata +57 -39
 - data/lib/channel/activity.rb +0 -10
 - data/lib/channel/channel.rb +0 -8
 - data/lib/channel/event.rb +0 -13
 - data/lib/channel/listener.rb +0 -20
 - data/lib/channel/trigger.rb +0 -16
 - data/lib/cli/channel_task.rb +0 -37
 - data/lib/cli/command.rb +0 -36
 - data/lib/cli/credential_task.rb +0 -39
 - data/lib/cli/factor_task.rb +0 -26
 - data/lib/cli/workflow_task.rb +0 -49
 - data/lib/client/client.rb +0 -151
 
    
        data/.gitignore
    ADDED
    
    
    
        data/Gemfile
    ADDED
    
    
    
        data/Gemfile.lock
    ADDED
    
    | 
         @@ -0,0 +1,32 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            PATH
         
     | 
| 
      
 2 
     | 
    
         
            +
              remote: .
         
     | 
| 
      
 3 
     | 
    
         
            +
              specs:
         
     | 
| 
      
 4 
     | 
    
         
            +
                factor (0.5.04)
         
     | 
| 
      
 5 
     | 
    
         
            +
                  colored (~> 1.2)
         
     | 
| 
      
 6 
     | 
    
         
            +
                  commander (~> 4.1.5)
         
     | 
| 
      
 7 
     | 
    
         
            +
                  configatron (~> 4.2.0)
         
     | 
| 
      
 8 
     | 
    
         
            +
                  faye-websocket (~> 0.7.2)
         
     | 
| 
      
 9 
     | 
    
         
            +
                  rest_client (~> 1.7.3)
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            GEM
         
     | 
| 
      
 12 
     | 
    
         
            +
              remote: https://rubygems.org/
         
     | 
| 
      
 13 
     | 
    
         
            +
              specs:
         
     | 
| 
      
 14 
     | 
    
         
            +
                colored (1.2)
         
     | 
| 
      
 15 
     | 
    
         
            +
                commander (4.1.6)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  highline (~> 1.6.11)
         
     | 
| 
      
 17 
     | 
    
         
            +
                configatron (4.2.0)
         
     | 
| 
      
 18 
     | 
    
         
            +
                eventmachine (1.0.3)
         
     | 
| 
      
 19 
     | 
    
         
            +
                faye-websocket (0.7.2)
         
     | 
| 
      
 20 
     | 
    
         
            +
                  eventmachine (>= 0.12.0)
         
     | 
| 
      
 21 
     | 
    
         
            +
                  websocket-driver (>= 0.3.1)
         
     | 
| 
      
 22 
     | 
    
         
            +
                highline (1.6.20)
         
     | 
| 
      
 23 
     | 
    
         
            +
                netrc (0.7.7)
         
     | 
| 
      
 24 
     | 
    
         
            +
                rest_client (1.7.3)
         
     | 
| 
      
 25 
     | 
    
         
            +
                  netrc (~> 0.7.7)
         
     | 
| 
      
 26 
     | 
    
         
            +
                websocket-driver (0.3.2)
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            PLATFORMS
         
     | 
| 
      
 29 
     | 
    
         
            +
              ruby
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            DEPENDENCIES
         
     | 
| 
      
 32 
     | 
    
         
            +
              factor!
         
     | 
    
        data/README.md
    ADDED
    
    | 
         @@ -0,0 +1,10 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            [](https://codeclimate.com/github/factor-io/factor)
         
     | 
| 
      
 2 
     | 
    
         
            +
            [](https://codeclimate.com/github/factor-io/factor)
         
     | 
| 
      
 3 
     | 
    
         
            +
            [](https://travis-ci.org/factor-io/factor)
         
     | 
| 
      
 4 
     | 
    
         
            +
            Factor.io Server Runtime
         
     | 
| 
      
 5 
     | 
    
         
            +
            ==========
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                gem install factor
         
     | 
| 
      
 8 
     | 
    
         
            +
                git clone git@github.com/factor-io/example-workflows.git
         
     | 
| 
      
 9 
     | 
    
         
            +
                cd example-workflows
         
     | 
| 
      
 10 
     | 
    
         
            +
                factor s
         
     | 
    
        data/bin/factor
    CHANGED
    
    | 
         @@ -1,12 +1,4 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            #!/usr/bin/env ruby
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
      
 2 
     | 
    
         
            +
            # -*- mode: ruby -*-
         
     | 
| 
       3 
3 
     | 
    
         | 
| 
       4 
     | 
    
         
            -
            require  
     | 
| 
       5 
     | 
    
         
            -
            bin_file = Pathname.new(__FILE__).realpath
         
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
            # add self to libpath
         
     | 
| 
       8 
     | 
    
         
            -
            $:.unshift File.expand_path("../../lib", bin_file)
         
     | 
| 
       9 
     | 
    
         
            -
            require 'factor'
         
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
            Factor::CLI::FactorTask.start
         
     | 
| 
      
 4 
     | 
    
         
            +
            require File.expand_path('../../lib/factor', __FILE__)
         
     | 
    
        data/factor.gemspec
    ADDED
    
    | 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
             $:.push File.expand_path("../lib", __FILE__)
         
     | 
| 
      
 2 
     | 
    
         
            +
             require 'factor/version'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
             Gem::Specification.new do |s|
         
     | 
| 
      
 5 
     | 
    
         
            +
              s.name          = "factor"
         
     | 
| 
      
 6 
     | 
    
         
            +
              s.version       = Factor::VERSION
         
     | 
| 
      
 7 
     | 
    
         
            +
              s.platform      = Gem::Platform::RUBY
         
     | 
| 
      
 8 
     | 
    
         
            +
              s.authors       = ["Maciej Skierkowski"]
         
     | 
| 
      
 9 
     | 
    
         
            +
              s.email         = ["maciej@factor.io"]
         
     | 
| 
      
 10 
     | 
    
         
            +
              s.homepage      = "https://factor.io"
         
     | 
| 
      
 11 
     | 
    
         
            +
              s.summary       = %q{CLI to manager workflows on Factor.io}
         
     | 
| 
      
 12 
     | 
    
         
            +
              s.description   = %q{CLI to manager workflows on Factor.io}
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              s.files         = %x{git ls-files}.split("\n")
         
     | 
| 
      
 15 
     | 
    
         
            +
              s.test_files    = %x{git ls-files -- {test,spec,features}/*}.split("\n")
         
     | 
| 
      
 16 
     | 
    
         
            +
              s.executables   = %x{git ls-files -- bin/*}.split("\n").map{ |f| File.basename(f) }
         
     | 
| 
      
 17 
     | 
    
         
            +
              s.require_paths = ["lib"]
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
              s.add_runtime_dependency 'commander', '~> 4.1.5'
         
     | 
| 
      
 20 
     | 
    
         
            +
              s.add_runtime_dependency 'rest_client', '~> 1.7.3'
         
     | 
| 
      
 21 
     | 
    
         
            +
              s.add_runtime_dependency 'faye-websocket', '~> 0.7.2'
         
     | 
| 
      
 22 
     | 
    
         
            +
              s.add_runtime_dependency 'colored', '~> 1.2'
         
     | 
| 
      
 23 
     | 
    
         
            +
              s.add_runtime_dependency 'configatron', '~> 4.2.0'
         
     | 
| 
      
 24 
     | 
    
         
            +
             end
         
     | 
    
        data/lib/cli.rb
    ADDED
    
    | 
         @@ -0,0 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # encoding: UTF-8
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'commander/import'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            require 'commands/workflows'
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            program :name, 'Factor.io Server'
         
     | 
| 
      
 8 
     | 
    
         
            +
            program :version, Factor::VERSION
         
     | 
| 
      
 9 
     | 
    
         
            +
            program :description, 'Factor.io Server to run workflows'
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            command 'server' do |c|
         
     | 
| 
      
 12 
     | 
    
         
            +
              c.syntax = 'factor server [options]'
         
     | 
| 
      
 13 
     | 
    
         
            +
              c.description = 'Start the Factor.io Server in the current local directory'
         
     | 
| 
      
 14 
     | 
    
         
            +
              c.option '--log FILE', String, 'Log file path. Default is stdout.'
         
     | 
| 
      
 15 
     | 
    
         
            +
              c.option '--credentials FILE', String, 'credentials.yml file path.'
         
     | 
| 
      
 16 
     | 
    
         
            +
              c.option '--connectors FILE', String, 'connectors.yml file path'
         
     | 
| 
      
 17 
     | 
    
         
            +
              c.option '--path FILE', String, 'Path to workflows'
         
     | 
| 
      
 18 
     | 
    
         
            +
              c.when_called Factor::Commands::Workflow, :server
         
     | 
| 
      
 19 
     | 
    
         
            +
            end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            alias_command 's', 'server'
         
     | 
| 
         @@ -0,0 +1,106 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # encoding: UTF-8
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'colored'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'configatron'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'yaml'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require 'fileutils'
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            module Factor
         
     | 
| 
      
 9 
     | 
    
         
            +
              module Commands
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                # Base command with common methods used by all commands
         
     | 
| 
      
 12 
     | 
    
         
            +
                class Command
         
     | 
| 
      
 13 
     | 
    
         
            +
                  DEFAULT_FILENAME = {
         
     | 
| 
      
 14 
     | 
    
         
            +
                    connectors:   File.expand_path('./connectors.yml'),
         
     | 
| 
      
 15 
     | 
    
         
            +
                    credentials:  File.expand_path('./credentials.yml')
         
     | 
| 
      
 16 
     | 
    
         
            +
                  }
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  attr_accessor :destination_stream
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                  def info(options = {})
         
     | 
| 
      
 21 
     | 
    
         
            +
                    log_line :info, options
         
     | 
| 
      
 22 
     | 
    
         
            +
                  end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                  def error(options = {})
         
     | 
| 
      
 25 
     | 
    
         
            +
                    log_line :error, options
         
     | 
| 
      
 26 
     | 
    
         
            +
                  end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                  def warn(options = {})
         
     | 
| 
      
 29 
     | 
    
         
            +
                    log_line :warn, options
         
     | 
| 
      
 30 
     | 
    
         
            +
                  end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                  def success(options = {})
         
     | 
| 
      
 33 
     | 
    
         
            +
                    log_line :success, options
         
     | 
| 
      
 34 
     | 
    
         
            +
                  end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                  def debug(options = {})
         
     | 
| 
      
 37 
     | 
    
         
            +
                  end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                  def exception(message, exception)
         
     | 
| 
      
 40 
     | 
    
         
            +
                    error 'message' => message
         
     | 
| 
      
 41 
     | 
    
         
            +
                    error 'message' => "  #{exception.message}"
         
     | 
| 
      
 42 
     | 
    
         
            +
                    exception.backtrace.each do |line|
         
     | 
| 
      
 43 
     | 
    
         
            +
                      error 'message' => "    #{line}"
         
     | 
| 
      
 44 
     | 
    
         
            +
                    end
         
     | 
| 
      
 45 
     | 
    
         
            +
                  end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                  def load_config(options = {})
         
     | 
| 
      
 48 
     | 
    
         
            +
                    load_config_data :credentials, options
         
     | 
| 
      
 49 
     | 
    
         
            +
                    load_config_data :connectors, options
         
     | 
| 
      
 50 
     | 
    
         
            +
                  end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                  private
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                  def load_config_data(config_type, options = {})
         
     | 
| 
      
 55 
     | 
    
         
            +
                    relative_path = options[config_type] || DEFAULT_FILENAME[config_type]
         
     | 
| 
      
 56 
     | 
    
         
            +
                    absolute_path = File.expand_path(relative_path)
         
     | 
| 
      
 57 
     | 
    
         
            +
                    info message: "Loading #{config_type.to_s} from #{absolute_path}"
         
     | 
| 
      
 58 
     | 
    
         
            +
                    data = YAML.load(File.read(absolute_path))
         
     | 
| 
      
 59 
     | 
    
         
            +
                    configatron[config_type].configure_from_hash(data)
         
     | 
| 
      
 60 
     | 
    
         
            +
                  rescue => ex
         
     | 
| 
      
 61 
     | 
    
         
            +
                    exception "Couldn't load #{config_type.to_s} from #{absolute_path}", ex
         
     | 
| 
      
 62 
     | 
    
         
            +
                  end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                  def log_line(section, options = {})
         
     | 
| 
      
 65 
     | 
    
         
            +
                    options       = { message: options } if options.is_a?(String)
         
     | 
| 
      
 66 
     | 
    
         
            +
                    tag           = tag(options)
         
     | 
| 
      
 67 
     | 
    
         
            +
                    message       = options['message'] || options[:message]
         
     | 
| 
      
 68 
     | 
    
         
            +
                    section_text  = format_section(section)
         
     | 
| 
      
 69 
     | 
    
         
            +
                    write "[ #{section_text} ] [#{time}]#{tag} #{message}" if message
         
     | 
| 
      
 70 
     | 
    
         
            +
                  end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                  def format_section(section)
         
     | 
| 
      
 73 
     | 
    
         
            +
                    formated_section = section.to_s.upcase.center(10)
         
     | 
| 
      
 74 
     | 
    
         
            +
                    case section
         
     | 
| 
      
 75 
     | 
    
         
            +
                    when :error then formated_section.red
         
     | 
| 
      
 76 
     | 
    
         
            +
                    when :info then formated_section.bold
         
     | 
| 
      
 77 
     | 
    
         
            +
                    when :warn then formated_section.yellow
         
     | 
| 
      
 78 
     | 
    
         
            +
                    when :success then formated_section.green
         
     | 
| 
      
 79 
     | 
    
         
            +
                    else formated_section
         
     | 
| 
      
 80 
     | 
    
         
            +
                    end
         
     | 
| 
      
 81 
     | 
    
         
            +
                  end
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                  def tag(options)
         
     | 
| 
      
 84 
     | 
    
         
            +
                    tag = ''
         
     | 
| 
      
 85 
     | 
    
         
            +
                    if options['workflow_id'] && options['instance_id']
         
     | 
| 
      
 86 
     | 
    
         
            +
                      tag = "[#{options['workflow_id']}:#{options['instance_id']}]"
         
     | 
| 
      
 87 
     | 
    
         
            +
                    elsif options['workflow_id'] && !options['instance_id']
         
     | 
| 
      
 88 
     | 
    
         
            +
                      tag = "[#{options['workflow_id']}]"
         
     | 
| 
      
 89 
     | 
    
         
            +
                    elsif !options['workflow_id'] && options['instance_id']
         
     | 
| 
      
 90 
     | 
    
         
            +
                      tag = "[#{options['instance_id']}]"
         
     | 
| 
      
 91 
     | 
    
         
            +
                    end
         
     | 
| 
      
 92 
     | 
    
         
            +
                    tag
         
     | 
| 
      
 93 
     | 
    
         
            +
                  end
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
                  def time
         
     | 
| 
      
 96 
     | 
    
         
            +
                     Time.now.localtime.strftime('%m/%d/%y %T.%L')
         
     | 
| 
      
 97 
     | 
    
         
            +
                  end
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
                  def write(message)
         
     | 
| 
      
 100 
     | 
    
         
            +
                    stream = @destination_stream || $stdout
         
     | 
| 
      
 101 
     | 
    
         
            +
                    stream.puts(message)
         
     | 
| 
      
 102 
     | 
    
         
            +
                    stream.flush
         
     | 
| 
      
 103 
     | 
    
         
            +
                  end
         
     | 
| 
      
 104 
     | 
    
         
            +
                end
         
     | 
| 
      
 105 
     | 
    
         
            +
              end
         
     | 
| 
      
 106 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,115 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # encoding: UTF-8
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'configatron'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            require 'commands/base'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require 'runtime'
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            module Factor
         
     | 
| 
      
 9 
     | 
    
         
            +
              module Commands
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                # Workflow is a Command to start the factor runtime from the CLI
         
     | 
| 
      
 12 
     | 
    
         
            +
                class Workflow < Factor::Commands::Command
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  def initialize
         
     | 
| 
      
 15 
     | 
    
         
            +
                    @workflows = {}
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  def server(args, options)
         
     | 
| 
      
 19 
     | 
    
         
            +
                    config_settings = {}
         
     | 
| 
      
 20 
     | 
    
         
            +
                    config_settings[:credentials] = options.credentials
         
     | 
| 
      
 21 
     | 
    
         
            +
                    config_settings[:connectors]  = options.connectors
         
     | 
| 
      
 22 
     | 
    
         
            +
                    workflow_filename = File.expand_path(options.path || '.')
         
     | 
| 
      
 23 
     | 
    
         
            +
                    @destination_stream = File.new(options.log, 'w+') if options.log
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                    load_config(config_settings)
         
     | 
| 
      
 26 
     | 
    
         
            +
                    load_all_workflows(workflow_filename)
         
     | 
| 
      
 27 
     | 
    
         
            +
                    block_until_interupt
         
     | 
| 
      
 28 
     | 
    
         
            +
                    log_message 'status' => 'info', 'message' => 'Good bye!'
         
     | 
| 
      
 29 
     | 
    
         
            +
                  end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                  private
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                  def load_all_workflows(workflow_filename)
         
     | 
| 
      
 34 
     | 
    
         
            +
                    glob_ending = workflow_filename[-1] == '/' ? '' : '/'
         
     | 
| 
      
 35 
     | 
    
         
            +
                    glob = "#{workflow_filename}#{glob_ending}*.rb"
         
     | 
| 
      
 36 
     | 
    
         
            +
                    file_list = Dir.glob(glob)
         
     | 
| 
      
 37 
     | 
    
         
            +
                    if !file_list.all? { |file| File.file?(file) }
         
     | 
| 
      
 38 
     | 
    
         
            +
                      error "#{workflow_filename} is neither a file or directory"
         
     | 
| 
      
 39 
     | 
    
         
            +
                    elsif file_list.count == 0
         
     | 
| 
      
 40 
     | 
    
         
            +
                      error 'No workflows in this directory to run'
         
     | 
| 
      
 41 
     | 
    
         
            +
                    else
         
     | 
| 
      
 42 
     | 
    
         
            +
                      file_list.each { |filename| load_workflow(filename) }
         
     | 
| 
      
 43 
     | 
    
         
            +
                    end
         
     | 
| 
      
 44 
     | 
    
         
            +
                  end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                  def block_until_interupt
         
     | 
| 
      
 47 
     | 
    
         
            +
                    log_message 'status' => 'info', 'message' => 'Ctrl-c to exit'
         
     | 
| 
      
 48 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 49 
     | 
    
         
            +
                      while true
         
     | 
| 
      
 50 
     | 
    
         
            +
                        sleep 1
         
     | 
| 
      
 51 
     | 
    
         
            +
                      end
         
     | 
| 
      
 52 
     | 
    
         
            +
                    rescue Interrupt
         
     | 
| 
      
 53 
     | 
    
         
            +
                      log_message 'status' => 'info', 'message' => 'Exiting app...'
         
     | 
| 
      
 54 
     | 
    
         
            +
                    ensure
         
     | 
| 
      
 55 
     | 
    
         
            +
                      @workflows.keys.each { |filename| unload_workflow(filename) }
         
     | 
| 
      
 56 
     | 
    
         
            +
                    end
         
     | 
| 
      
 57 
     | 
    
         
            +
                  end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                  def load_workflow(filename)
         
     | 
| 
      
 60 
     | 
    
         
            +
                    workflow_filename = File.expand_path(filename)
         
     | 
| 
      
 61 
     | 
    
         
            +
                    log_message(
         
     | 
| 
      
 62 
     | 
    
         
            +
                      'status' => 'info',
         
     | 
| 
      
 63 
     | 
    
         
            +
                      'message' =>  "Loading workflow from #{workflow_filename}")
         
     | 
| 
      
 64 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 65 
     | 
    
         
            +
                      workflow_definition = File.read(workflow_filename)
         
     | 
| 
      
 66 
     | 
    
         
            +
                    rescue => ex
         
     | 
| 
      
 67 
     | 
    
         
            +
                      exception "Couldn't read file #{workflow_filename}", ex
         
     | 
| 
      
 68 
     | 
    
         
            +
                      return
         
     | 
| 
      
 69 
     | 
    
         
            +
                    end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                    log_message(
         
     | 
| 
      
 72 
     | 
    
         
            +
                      'status' => 'info',
         
     | 
| 
      
 73 
     | 
    
         
            +
                      'message' =>  'Setting up workflow processor')
         
     | 
| 
      
 74 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 75 
     | 
    
         
            +
                      connector_settings = configatron.connectors.to_hash
         
     | 
| 
      
 76 
     | 
    
         
            +
                      credential_settings = configatron.credentials.to_hash
         
     | 
| 
      
 77 
     | 
    
         
            +
                      runtime = Runtime.new(connector_settings, credential_settings)
         
     | 
| 
      
 78 
     | 
    
         
            +
                      runtime.logger = self.method(:log_message)
         
     | 
| 
      
 79 
     | 
    
         
            +
                    rescue => ex
         
     | 
| 
      
 80 
     | 
    
         
            +
                      message = "Couldn't setup workflow process for #{workflow_filename}"
         
     | 
| 
      
 81 
     | 
    
         
            +
                      exception message, ex
         
     | 
| 
      
 82 
     | 
    
         
            +
                    end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                    @workflows[workflow_filename] = fork do
         
     | 
| 
      
 85 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 86 
     | 
    
         
            +
                        log_message(
         
     | 
| 
      
 87 
     | 
    
         
            +
                          'status' => 'info',
         
     | 
| 
      
 88 
     | 
    
         
            +
                          'message' => "Starting #{workflow_filename}")
         
     | 
| 
      
 89 
     | 
    
         
            +
                        runtime.load(workflow_definition)
         
     | 
| 
      
 90 
     | 
    
         
            +
                      rescue => ex
         
     | 
| 
      
 91 
     | 
    
         
            +
                        exception "Couldn't load #{workflow_filename}", ex
         
     | 
| 
      
 92 
     | 
    
         
            +
                      end
         
     | 
| 
      
 93 
     | 
    
         
            +
                    end
         
     | 
| 
      
 94 
     | 
    
         
            +
                  end
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
                  def unload_workflow(filename)
         
     | 
| 
      
 97 
     | 
    
         
            +
                    workflow_filename = File.expand_path(filename)
         
     | 
| 
      
 98 
     | 
    
         
            +
                    log_message(
         
     | 
| 
      
 99 
     | 
    
         
            +
                      'status' => 'info',
         
     | 
| 
      
 100 
     | 
    
         
            +
                      'message' =>  "Stopping #{workflow_filename}")
         
     | 
| 
      
 101 
     | 
    
         
            +
                    Process.kill('SIGINT', @workflows[workflow_filename])
         
     | 
| 
      
 102 
     | 
    
         
            +
                  end
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
                  def log_message(message_info)
         
     | 
| 
      
 105 
     | 
    
         
            +
                    case message_info['status']
         
     | 
| 
      
 106 
     | 
    
         
            +
                    when 'info' then info message_info
         
     | 
| 
      
 107 
     | 
    
         
            +
                    when 'success' then success message_info
         
     | 
| 
      
 108 
     | 
    
         
            +
                    when 'warn' then warn message_info
         
     | 
| 
      
 109 
     | 
    
         
            +
                    when 'debug' then debug message_info
         
     | 
| 
      
 110 
     | 
    
         
            +
                    else error message_info
         
     | 
| 
      
 111 
     | 
    
         
            +
                    end
         
     | 
| 
      
 112 
     | 
    
         
            +
                  end
         
     | 
| 
      
 113 
     | 
    
         
            +
                end
         
     | 
| 
      
 114 
     | 
    
         
            +
              end
         
     | 
| 
      
 115 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/factor.rb
    CHANGED
    
    
    
        data/lib/factor/base.rb
    ADDED
    
    | 
         @@ -0,0 +1,17 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # encoding: UTF-8
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            # Primary Factor.io module
         
     | 
| 
      
 4 
     | 
    
         
            +
            module Factor
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              String.send :define_method, :classify do
         
     | 
| 
      
 7 
     | 
    
         
            +
                self.split('_').collect! { |w| w.capitalize }.join
         
     | 
| 
      
 8 
     | 
    
         
            +
              end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
              String.send :define_method, :underscore do
         
     | 
| 
      
 11 
     | 
    
         
            +
                self.gsub(/::/, '/')
         
     | 
| 
      
 12 
     | 
    
         
            +
                .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
         
     | 
| 
      
 13 
     | 
    
         
            +
                .gsub(/([a-z\d])([A-Z])/, '\1_\2')
         
     | 
| 
      
 14 
     | 
    
         
            +
                .tr('-', '_')
         
     | 
| 
      
 15 
     | 
    
         
            +
                .downcase
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/listener.rb
    ADDED
    
    | 
         @@ -0,0 +1,48 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # encoding: UTF-8
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'rest_client'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'websocket_manager'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            module Factor
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
              # Class Listener for integrating with connector service
         
     | 
| 
      
 9 
     | 
    
         
            +
              class Listener
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                def initialize(url)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @url = url
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                def definition
         
     | 
| 
      
 16 
     | 
    
         
            +
                  get("#{@url}/definition")
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                def listener(listener_id, &block)
         
     | 
| 
      
 20 
     | 
    
         
            +
                  ws = listen("#{@url}/listeners/#{listener_id}")
         
     | 
| 
      
 21 
     | 
    
         
            +
                  ws
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                def action(action_id, &block)
         
     | 
| 
      
 25 
     | 
    
         
            +
                  ws = listen("#{@url}/actions/#{action_id}")
         
     | 
| 
      
 26 
     | 
    
         
            +
                  ws
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                private
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                def post(uri_path, payload)
         
     | 
| 
      
 32 
     | 
    
         
            +
                  content = { 'payload' => MultiJson.dump(payload) }
         
     | 
| 
      
 33 
     | 
    
         
            +
                  JSON.parse(RestClient.post(uri_path, content))
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                def get(uri_path)
         
     | 
| 
      
 37 
     | 
    
         
            +
                  JSON.parse(RestClient.get(uri_path))
         
     | 
| 
      
 38 
     | 
    
         
            +
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                def delete(uri_path)
         
     | 
| 
      
 41 
     | 
    
         
            +
                  JSON.parse(RestClient.delete(uri_path))
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                def listen(uri_path)
         
     | 
| 
      
 45 
     | 
    
         
            +
                  WebSocketManager.new(uri_path)
         
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
              end
         
     | 
| 
      
 48 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/runtime.rb
    ADDED
    
    | 
         @@ -0,0 +1,192 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # encoding: UTF-8
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'json'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'securerandom'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'yaml'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require 'eventmachine'
         
     | 
| 
      
 7 
     | 
    
         
            +
            require 'uri'
         
     | 
| 
      
 8 
     | 
    
         
            +
            require 'faye/websocket'
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            require 'listener'
         
     | 
| 
      
 11 
     | 
    
         
            +
            require 'commands/base'
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            module Factor
         
     | 
| 
      
 14 
     | 
    
         
            +
              # Runtime class is the magic of the server
         
     | 
| 
      
 15 
     | 
    
         
            +
              class Runtime
         
     | 
| 
      
 16 
     | 
    
         
            +
                attr_accessor :logger, :name, :description, :id, :instance_id, :connectors, :credentials
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                def initialize(connectors, credentials)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  @workflow_spec  = {}
         
     | 
| 
      
 20 
     | 
    
         
            +
                  @sockets        = []
         
     | 
| 
      
 21 
     | 
    
         
            +
                  @instance_id    = SecureRandom.hex(3)
         
     | 
| 
      
 22 
     | 
    
         
            +
                  @reconnect      = true
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                  trap 'SIGINT' do
         
     | 
| 
      
 25 
     | 
    
         
            +
                    info "Exiting '#{@instance_id}'"
         
     | 
| 
      
 26 
     | 
    
         
            +
                    @reconnect = false
         
     | 
| 
      
 27 
     | 
    
         
            +
                    @sockets.each { |s| s.close }
         
     | 
| 
      
 28 
     | 
    
         
            +
                    exit
         
     | 
| 
      
 29 
     | 
    
         
            +
                  end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                  @connectors = {}
         
     | 
| 
      
 32 
     | 
    
         
            +
                  connectors.each do |connector_id, connector_url|
         
     | 
| 
      
 33 
     | 
    
         
            +
                    @connectors[connector_id] = Listener.new(connector_url)
         
     | 
| 
      
 34 
     | 
    
         
            +
                  end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                  @credentials = {}
         
     | 
| 
      
 37 
     | 
    
         
            +
                  credentials.each do |connector_id, credential_settings|
         
     | 
| 
      
 38 
     | 
    
         
            +
                    @credentials[connector_id] = credential_settings
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
                end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                def load(workflow_definition)
         
     | 
| 
      
 43 
     | 
    
         
            +
                  EM.run do
         
     | 
| 
      
 44 
     | 
    
         
            +
                    self.instance_eval(workflow_definition)
         
     | 
| 
      
 45 
     | 
    
         
            +
                  end
         
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                def workflow(key, value)
         
     | 
| 
      
 49 
     | 
    
         
            +
                  @workflow_spec[key] = value
         
     | 
| 
      
 50 
     | 
    
         
            +
                  @name               = value if @key == 'name'
         
     | 
| 
      
 51 
     | 
    
         
            +
                  @id                 = value if @key == 'id'
         
     | 
| 
      
 52 
     | 
    
         
            +
                  @description        = value if @key == 'description'
         
     | 
| 
      
 53 
     | 
    
         
            +
                end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                def listen(service_id, listener_id, params = {}, &block)
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                  ws = @connectors[service_id.to_sym].listener(listener_id)
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                  handle_on_open(service_id, listener_id, 'Listener', ws, params)
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                  ws.on :close do |event|
         
     | 
| 
      
 62 
     | 
    
         
            +
                    error 'Listener disconnected'
         
     | 
| 
      
 63 
     | 
    
         
            +
                    if @reconnect
         
     | 
| 
      
 64 
     | 
    
         
            +
                      warn 'Reconnecting...'
         
     | 
| 
      
 65 
     | 
    
         
            +
                      sleep 3
         
     | 
| 
      
 66 
     | 
    
         
            +
                      ws.open
         
     | 
| 
      
 67 
     | 
    
         
            +
                    end
         
     | 
| 
      
 68 
     | 
    
         
            +
                  end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                  ws.on :message do |event|
         
     | 
| 
      
 71 
     | 
    
         
            +
                    listener_response = JSON.parse(event.data)
         
     | 
| 
      
 72 
     | 
    
         
            +
                    case listener_response['type']
         
     | 
| 
      
 73 
     | 
    
         
            +
                    when'start_workflow'
         
     | 
| 
      
 74 
     | 
    
         
            +
                      success "Workflow '#{service_id}::#{listener_id}' triggered"
         
     | 
| 
      
 75 
     | 
    
         
            +
                      error_handle_call(listener_response, &block)
         
     | 
| 
      
 76 
     | 
    
         
            +
                    when 'started'
         
     | 
| 
      
 77 
     | 
    
         
            +
                      success "Workflow '#{service_id}::#{listener_id}' started"
         
     | 
| 
      
 78 
     | 
    
         
            +
                    when 'fail'
         
     | 
| 
      
 79 
     | 
    
         
            +
                      error "Workflow '#{service_id}::#{listener_id}' failed to start"
         
     | 
| 
      
 80 
     | 
    
         
            +
                    when 'log'
         
     | 
| 
      
 81 
     | 
    
         
            +
                      listener_response['message'] = "  #{listener_response['message']}"
         
     | 
| 
      
 82 
     | 
    
         
            +
                      log_message(listener_response)
         
     | 
| 
      
 83 
     | 
    
         
            +
                    else
         
     | 
| 
      
 84 
     | 
    
         
            +
                      error "Unknown listener response: #{listener_response}"
         
     | 
| 
      
 85 
     | 
    
         
            +
                    end
         
     | 
| 
      
 86 
     | 
    
         
            +
                  end
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
                  ws.on :retry do |event|
         
     | 
| 
      
 89 
     | 
    
         
            +
                    warn event[:message]
         
     | 
| 
      
 90 
     | 
    
         
            +
                  end
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
                  ws.on :error do |event|
         
     | 
| 
      
 93 
     | 
    
         
            +
                    err = 'Error during WebSocket handshake: Unexpected response code: 401'
         
     | 
| 
      
 94 
     | 
    
         
            +
                    if event.message == err
         
     | 
| 
      
 95 
     | 
    
         
            +
                      error "Sorry but you don't have access to this listener,
         
     | 
| 
      
 96 
     | 
    
         
            +
                        | either because your token is invalid or your plan doesn't
         
     | 
| 
      
 97 
     | 
    
         
            +
                        | support this listener"
         
     | 
| 
      
 98 
     | 
    
         
            +
                    else
         
     | 
| 
      
 99 
     | 
    
         
            +
                      error 'Failure in WebSocket connection to connector service'
         
     | 
| 
      
 100 
     | 
    
         
            +
                    end
         
     | 
| 
      
 101 
     | 
    
         
            +
                  end
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
                  ws.open
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
      
 105 
     | 
    
         
            +
                  @sockets << ws
         
     | 
| 
      
 106 
     | 
    
         
            +
                end
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
                def run(service_id, action_id, params = {}, &block)
         
     | 
| 
      
 109 
     | 
    
         
            +
                  ws = @connectors[service_id.to_sym].action(action_id)
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
                  handle_on_open(service_id, action_id, 'Action', ws, params)
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
                  ws.on :error do |event|
         
     | 
| 
      
 114 
     | 
    
         
            +
                    error 'Connection dropped while calling action'
         
     | 
| 
      
 115 
     | 
    
         
            +
                  end
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
                  ws.on :message do |event|
         
     | 
| 
      
 118 
     | 
    
         
            +
                    action_response = JSON.parse(event.data)
         
     | 
| 
      
 119 
     | 
    
         
            +
                    case action_response['type']
         
     | 
| 
      
 120 
     | 
    
         
            +
                    when 'return'
         
     | 
| 
      
 121 
     | 
    
         
            +
                      ws.close
         
     | 
| 
      
 122 
     | 
    
         
            +
                      success "Action '#{service_id}::#{action_id}' responded"
         
     | 
| 
      
 123 
     | 
    
         
            +
                      error_handle_call(action_response, &block)
         
     | 
| 
      
 124 
     | 
    
         
            +
                    when 'fail'
         
     | 
| 
      
 125 
     | 
    
         
            +
                      ws.close
         
     | 
| 
      
 126 
     | 
    
         
            +
                      error "  #{action_response['message']}"
         
     | 
| 
      
 127 
     | 
    
         
            +
                      error "Action '#{service_id}::#{action_id}' failed"
         
     | 
| 
      
 128 
     | 
    
         
            +
                    when 'log'
         
     | 
| 
      
 129 
     | 
    
         
            +
                      action_response['message'] = "  #{action_response['message']}"
         
     | 
| 
      
 130 
     | 
    
         
            +
                      log_message(action_response)
         
     | 
| 
      
 131 
     | 
    
         
            +
                    else
         
     | 
| 
      
 132 
     | 
    
         
            +
                      error "Unknown action response: #{action_response}"
         
     | 
| 
      
 133 
     | 
    
         
            +
                    end
         
     | 
| 
      
 134 
     | 
    
         
            +
                  end
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
                  ws.open
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
                  @sockets << ws
         
     | 
| 
      
 139 
     | 
    
         
            +
                end
         
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
                private
         
     | 
| 
      
 142 
     | 
    
         
            +
             
     | 
| 
      
 143 
     | 
    
         
            +
                def handle_on_open(service_id, action_id, dsl_type, ws, params)
         
     | 
| 
      
 144 
     | 
    
         
            +
                  ws.on :open do |event|
         
     | 
| 
      
 145 
     | 
    
         
            +
                    params.merge!(@credentials[service_id.to_sym] || {})
         
     | 
| 
      
 146 
     | 
    
         
            +
                    success "#{dsl_type.capitalize} '#{service_id}::#{action_id}' called"
         
     | 
| 
      
 147 
     | 
    
         
            +
                    ws.send(params.to_json)
         
     | 
| 
      
 148 
     | 
    
         
            +
                  end
         
     | 
| 
      
 149 
     | 
    
         
            +
                end
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
                def error_handle_call(listener_response, &block)
         
     | 
| 
      
 152 
     | 
    
         
            +
                  block.call(listener_response['payload']) if block
         
     | 
| 
      
 153 
     | 
    
         
            +
                rescue => ex
         
     | 
| 
      
 154 
     | 
    
         
            +
                  error "Error in workflow definition: #{ex.message}"
         
     | 
| 
      
 155 
     | 
    
         
            +
                  ex.backtrace.each do |line|
         
     | 
| 
      
 156 
     | 
    
         
            +
                    error "  #{line}"
         
     | 
| 
      
 157 
     | 
    
         
            +
                  end
         
     | 
| 
      
 158 
     | 
    
         
            +
                end
         
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
      
 160 
     | 
    
         
            +
                def success(msg)
         
     | 
| 
      
 161 
     | 
    
         
            +
                  log_message('type' => 'log', 'status' => 'success', 'message' => msg)
         
     | 
| 
      
 162 
     | 
    
         
            +
                end
         
     | 
| 
      
 163 
     | 
    
         
            +
             
     | 
| 
      
 164 
     | 
    
         
            +
                def warn(msg)
         
     | 
| 
      
 165 
     | 
    
         
            +
                  log_message('type' => 'log', 'status' => 'warn', 'message' => msg)
         
     | 
| 
      
 166 
     | 
    
         
            +
                end
         
     | 
| 
      
 167 
     | 
    
         
            +
             
     | 
| 
      
 168 
     | 
    
         
            +
                def error(msg)
         
     | 
| 
      
 169 
     | 
    
         
            +
                  log_message('type' => 'log', 'status' => 'error', 'message' => msg)
         
     | 
| 
      
 170 
     | 
    
         
            +
                end
         
     | 
| 
      
 171 
     | 
    
         
            +
             
     | 
| 
      
 172 
     | 
    
         
            +
                def info(msg)
         
     | 
| 
      
 173 
     | 
    
         
            +
                  log_message('type' => 'log', 'status' => 'info', 'message' => msg)
         
     | 
| 
      
 174 
     | 
    
         
            +
                end
         
     | 
| 
      
 175 
     | 
    
         
            +
             
     | 
| 
      
 176 
     | 
    
         
            +
                def log_message(message_info)
         
     | 
| 
      
 177 
     | 
    
         
            +
                  message_info['instance_id'] = @instance_id
         
     | 
| 
      
 178 
     | 
    
         
            +
                  message_info['workflow_id'] = @id
         
     | 
| 
      
 179 
     | 
    
         
            +
                  @logger.call(message_info) if @logger
         
     | 
| 
      
 180 
     | 
    
         
            +
                end
         
     | 
| 
      
 181 
     | 
    
         
            +
             
     | 
| 
      
 182 
     | 
    
         
            +
                def define_method_in_class(class_ref, class_id, method_id, &block)
         
     | 
| 
      
 183 
     | 
    
         
            +
                  class_name  = class_id.classify
         
     | 
| 
      
 184 
     | 
    
         
            +
                  method_name = method_id.underscore
         
     | 
| 
      
 185 
     | 
    
         
            +
                  class_ref.class.instance_eval do
         
     | 
| 
      
 186 
     | 
    
         
            +
                    define_method(method_name) do |params = {}, &passed_block|
         
     | 
| 
      
 187 
     | 
    
         
            +
                      block.call(class_name, method_name, params, &passed_block)
         
     | 
| 
      
 188 
     | 
    
         
            +
                    end
         
     | 
| 
      
 189 
     | 
    
         
            +
                  end
         
     | 
| 
      
 190 
     | 
    
         
            +
                end
         
     | 
| 
      
 191 
     | 
    
         
            +
              end
         
     | 
| 
      
 192 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,94 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # encoding: UTF-8
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'faye/websocket'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'uri'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            # class for managing the web socket connections
         
     | 
| 
      
 7 
     | 
    
         
            +
            class WebSocketManager
         
     | 
| 
      
 8 
     | 
    
         
            +
              attr_accessor :keep_open, :events, :state
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
              def initialize(uri, headers = {})
         
     | 
| 
      
 11 
     | 
    
         
            +
                u                     = URI(uri)
         
     | 
| 
      
 12 
     | 
    
         
            +
                u.scheme              = 'wss' if u.scheme == 'https'
         
     | 
| 
      
 13 
     | 
    
         
            +
                @uri                  = u.to_s
         
     | 
| 
      
 14 
     | 
    
         
            +
                @settings             = { ping: 10, retry: 5 }
         
     | 
| 
      
 15 
     | 
    
         
            +
                @settings[:headers]   = headers if headers && headers != {}
         
     | 
| 
      
 16 
     | 
    
         
            +
                @state                = :closed
         
     | 
| 
      
 17 
     | 
    
         
            +
                @events               = {}
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
              def open
         
     | 
| 
      
 21 
     | 
    
         
            +
                if closed?
         
     | 
| 
      
 22 
     | 
    
         
            +
                  @state = :opening
         
     | 
| 
      
 23 
     | 
    
         
            +
                  connect
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
                @state
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
              def close
         
     | 
| 
      
 29 
     | 
    
         
            +
                if open?
         
     | 
| 
      
 30 
     | 
    
         
            +
                  @state = :closing
         
     | 
| 
      
 31 
     | 
    
         
            +
                  @ws.close
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
                @state
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
              def on(event, &block)
         
     | 
| 
      
 37 
     | 
    
         
            +
                @events[event] = block
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
              def open?
         
     | 
| 
      
 41 
     | 
    
         
            +
                @state == :open
         
     | 
| 
      
 42 
     | 
    
         
            +
              end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
              def opening?
         
     | 
| 
      
 45 
     | 
    
         
            +
                @state == :opening
         
     | 
| 
      
 46 
     | 
    
         
            +
              end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
              def closed?
         
     | 
| 
      
 49 
     | 
    
         
            +
                @state == :closed
         
     | 
| 
      
 50 
     | 
    
         
            +
              end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
              def closing?
         
     | 
| 
      
 53 
     | 
    
         
            +
                @state == :closing
         
     | 
| 
      
 54 
     | 
    
         
            +
              end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
              def send(msg)
         
     | 
| 
      
 57 
     | 
    
         
            +
                @ws.send(msg)
         
     | 
| 
      
 58 
     | 
    
         
            +
              end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
              private
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
              def call_event(event, data)
         
     | 
| 
      
 63 
     | 
    
         
            +
                @events[event].call(data) if @events[event]
         
     | 
| 
      
 64 
     | 
    
         
            +
              end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
              def connect
         
     | 
| 
      
 67 
     | 
    
         
            +
                EM.run do
         
     | 
| 
      
 68 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 69 
     | 
    
         
            +
                    @ws = Faye::WebSocket::Client.new(@uri, nil, @settings)
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                    @ws.on :close do |event|
         
     | 
| 
      
 72 
     | 
    
         
            +
                      @state = :closed
         
     | 
| 
      
 73 
     | 
    
         
            +
                      call_event :close, event
         
     | 
| 
      
 74 
     | 
    
         
            +
                    end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                    @ws.on :message do |msg|
         
     | 
| 
      
 77 
     | 
    
         
            +
                      call_event :message, msg
         
     | 
| 
      
 78 
     | 
    
         
            +
                    end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                    @ws.on :open do |event|
         
     | 
| 
      
 81 
     | 
    
         
            +
                      @state = :open
         
     | 
| 
      
 82 
     | 
    
         
            +
                      call_event :open, event
         
     | 
| 
      
 83 
     | 
    
         
            +
                    end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
                    @ws.on :error do |event|
         
     | 
| 
      
 86 
     | 
    
         
            +
                      call_event :error, event
         
     | 
| 
      
 87 
     | 
    
         
            +
                    end
         
     | 
| 
      
 88 
     | 
    
         
            +
                  rescue => ex
         
     | 
| 
      
 89 
     | 
    
         
            +
                    call_event :fail, ex.message
         
     | 
| 
      
 90 
     | 
    
         
            +
                  end
         
     | 
| 
      
 91 
     | 
    
         
            +
                end
         
     | 
| 
      
 92 
     | 
    
         
            +
              end
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
            end
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: factor
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 0. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.5.04
         
     | 
| 
       5 
5 
     | 
    
         
             
              prerelease: 
         
     | 
| 
       6 
6 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       7 
7 
     | 
    
         
             
            authors:
         
     | 
| 
         @@ -9,99 +9,117 @@ authors: 
     | 
|
| 
       9 
9 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       10 
10 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       11 
11 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       12 
     | 
    
         
            -
            date:  
     | 
| 
      
 12 
     | 
    
         
            +
            date: 2014-07-23 00:00:00.000000000 Z
         
     | 
| 
       13 
13 
     | 
    
         
             
            dependencies:
         
     | 
| 
       14 
14 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       15 
     | 
    
         
            -
              name:  
     | 
| 
      
 15 
     | 
    
         
            +
              name: commander
         
     | 
| 
       16 
16 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
       17 
17 
     | 
    
         
             
                none: false
         
     | 
| 
       18 
18 
     | 
    
         
             
                requirements:
         
     | 
| 
       19 
     | 
    
         
            -
                - -  
     | 
| 
      
 19 
     | 
    
         
            +
                - - ~>
         
     | 
| 
       20 
20 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       21 
     | 
    
         
            -
                    version:  
     | 
| 
      
 21 
     | 
    
         
            +
                    version: 4.1.5
         
     | 
| 
       22 
22 
     | 
    
         
             
              type: :runtime
         
     | 
| 
       23 
23 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       24 
24 
     | 
    
         
             
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       25 
25 
     | 
    
         
             
                none: false
         
     | 
| 
       26 
26 
     | 
    
         
             
                requirements:
         
     | 
| 
       27 
     | 
    
         
            -
                - -  
     | 
| 
      
 27 
     | 
    
         
            +
                - - ~>
         
     | 
| 
       28 
28 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       29 
     | 
    
         
            -
                    version:  
     | 
| 
      
 29 
     | 
    
         
            +
                    version: 4.1.5
         
     | 
| 
       30 
30 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       31 
     | 
    
         
            -
              name:  
     | 
| 
      
 31 
     | 
    
         
            +
              name: rest_client
         
     | 
| 
       32 
32 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
       33 
33 
     | 
    
         
             
                none: false
         
     | 
| 
       34 
34 
     | 
    
         
             
                requirements:
         
     | 
| 
       35 
     | 
    
         
            -
                - -  
     | 
| 
      
 35 
     | 
    
         
            +
                - - ~>
         
     | 
| 
       36 
36 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       37 
     | 
    
         
            -
                    version: 1. 
     | 
| 
      
 37 
     | 
    
         
            +
                    version: 1.7.3
         
     | 
| 
       38 
38 
     | 
    
         
             
              type: :runtime
         
     | 
| 
       39 
39 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       40 
40 
     | 
    
         
             
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       41 
41 
     | 
    
         
             
                none: false
         
     | 
| 
       42 
42 
     | 
    
         
             
                requirements:
         
     | 
| 
       43 
     | 
    
         
            -
                - -  
     | 
| 
      
 43 
     | 
    
         
            +
                - - ~>
         
     | 
| 
       44 
44 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       45 
     | 
    
         
            -
                    version: 1. 
     | 
| 
      
 45 
     | 
    
         
            +
                    version: 1.7.3
         
     | 
| 
       46 
46 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       47 
     | 
    
         
            -
              name:  
     | 
| 
      
 47 
     | 
    
         
            +
              name: faye-websocket
         
     | 
| 
       48 
48 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
       49 
49 
     | 
    
         
             
                none: false
         
     | 
| 
       50 
50 
     | 
    
         
             
                requirements:
         
     | 
| 
       51 
     | 
    
         
            -
                - -  
     | 
| 
      
 51 
     | 
    
         
            +
                - - ~>
         
     | 
| 
       52 
52 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       53 
     | 
    
         
            -
                    version:  
     | 
| 
      
 53 
     | 
    
         
            +
                    version: 0.7.2
         
     | 
| 
       54 
54 
     | 
    
         
             
              type: :runtime
         
     | 
| 
       55 
55 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       56 
56 
     | 
    
         
             
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       57 
57 
     | 
    
         
             
                none: false
         
     | 
| 
       58 
58 
     | 
    
         
             
                requirements:
         
     | 
| 
       59 
     | 
    
         
            -
                - -  
     | 
| 
      
 59 
     | 
    
         
            +
                - - ~>
         
     | 
| 
       60 
60 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       61 
     | 
    
         
            -
                    version:  
     | 
| 
      
 61 
     | 
    
         
            +
                    version: 0.7.2
         
     | 
| 
       62 
62 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       63 
     | 
    
         
            -
              name:  
     | 
| 
      
 63 
     | 
    
         
            +
              name: colored
         
     | 
| 
       64 
64 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
       65 
65 
     | 
    
         
             
                none: false
         
     | 
| 
       66 
66 
     | 
    
         
             
                requirements:
         
     | 
| 
       67 
     | 
    
         
            -
                - -  
     | 
| 
      
 67 
     | 
    
         
            +
                - - ~>
         
     | 
| 
       68 
68 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       69 
     | 
    
         
            -
                    version: 1. 
     | 
| 
      
 69 
     | 
    
         
            +
                    version: '1.2'
         
     | 
| 
       70 
70 
     | 
    
         
             
              type: :runtime
         
     | 
| 
       71 
71 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       72 
72 
     | 
    
         
             
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       73 
73 
     | 
    
         
             
                none: false
         
     | 
| 
       74 
74 
     | 
    
         
             
                requirements:
         
     | 
| 
       75 
     | 
    
         
            -
                - -  
     | 
| 
      
 75 
     | 
    
         
            +
                - - ~>
         
     | 
| 
       76 
76 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       77 
     | 
    
         
            -
                    version: 1. 
     | 
| 
       78 
     | 
    
         
            -
             
     | 
| 
       79 
     | 
    
         
            -
             
     | 
| 
      
 77 
     | 
    
         
            +
                    version: '1.2'
         
     | 
| 
      
 78 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 79 
     | 
    
         
            +
              name: configatron
         
     | 
| 
      
 80 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 81 
     | 
    
         
            +
                none: false
         
     | 
| 
      
 82 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 83 
     | 
    
         
            +
                - - ~>
         
     | 
| 
      
 84 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 85 
     | 
    
         
            +
                    version: 4.2.0
         
     | 
| 
      
 86 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 87 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 88 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 89 
     | 
    
         
            +
                none: false
         
     | 
| 
      
 90 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 91 
     | 
    
         
            +
                - - ~>
         
     | 
| 
      
 92 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 93 
     | 
    
         
            +
                    version: 4.2.0
         
     | 
| 
      
 94 
     | 
    
         
            +
            description: CLI to manager workflows on Factor.io
         
     | 
| 
      
 95 
     | 
    
         
            +
            email:
         
     | 
| 
      
 96 
     | 
    
         
            +
            - maciej@factor.io
         
     | 
| 
       80 
97 
     | 
    
         
             
            executables:
         
     | 
| 
       81 
98 
     | 
    
         
             
            - factor
         
     | 
| 
       82 
99 
     | 
    
         
             
            extensions: []
         
     | 
| 
       83 
100 
     | 
    
         
             
            extra_rdoc_files: []
         
     | 
| 
       84 
101 
     | 
    
         
             
            files:
         
     | 
| 
       85 
     | 
    
         
            -
            -  
     | 
| 
       86 
     | 
    
         
            -
            -  
     | 
| 
       87 
     | 
    
         
            -
            -  
     | 
| 
       88 
     | 
    
         
            -
            -  
     | 
| 
       89 
     | 
    
         
            -
            - lib/channel/trigger.rb
         
     | 
| 
       90 
     | 
    
         
            -
            - lib/cli/channel_task.rb
         
     | 
| 
       91 
     | 
    
         
            -
            - lib/cli/command.rb
         
     | 
| 
       92 
     | 
    
         
            -
            - lib/cli/credential_task.rb
         
     | 
| 
       93 
     | 
    
         
            -
            - lib/cli/factor_task.rb
         
     | 
| 
       94 
     | 
    
         
            -
            - lib/cli/workflow_task.rb
         
     | 
| 
       95 
     | 
    
         
            -
            - lib/client/client.rb
         
     | 
| 
       96 
     | 
    
         
            -
            - lib/factor.rb
         
     | 
| 
      
 102 
     | 
    
         
            +
            - .gitignore
         
     | 
| 
      
 103 
     | 
    
         
            +
            - Gemfile
         
     | 
| 
      
 104 
     | 
    
         
            +
            - Gemfile.lock
         
     | 
| 
      
 105 
     | 
    
         
            +
            - README.md
         
     | 
| 
       97 
106 
     | 
    
         
             
            - bin/factor
         
     | 
| 
       98 
     | 
    
         
            -
             
     | 
| 
      
 107 
     | 
    
         
            +
            - factor.gemspec
         
     | 
| 
      
 108 
     | 
    
         
            +
            - lib/cli.rb
         
     | 
| 
      
 109 
     | 
    
         
            +
            - lib/commands/base.rb
         
     | 
| 
      
 110 
     | 
    
         
            +
            - lib/commands/workflows.rb
         
     | 
| 
      
 111 
     | 
    
         
            +
            - lib/factor.rb
         
     | 
| 
      
 112 
     | 
    
         
            +
            - lib/factor/base.rb
         
     | 
| 
      
 113 
     | 
    
         
            +
            - lib/factor/version.rb
         
     | 
| 
      
 114 
     | 
    
         
            +
            - lib/listener.rb
         
     | 
| 
      
 115 
     | 
    
         
            +
            - lib/runtime.rb
         
     | 
| 
      
 116 
     | 
    
         
            +
            - lib/websocket_manager.rb
         
     | 
| 
      
 117 
     | 
    
         
            +
            homepage: https://factor.io
         
     | 
| 
       99 
118 
     | 
    
         
             
            licenses: []
         
     | 
| 
       100 
119 
     | 
    
         
             
            post_install_message: 
         
     | 
| 
       101 
120 
     | 
    
         
             
            rdoc_options: []
         
     | 
| 
       102 
121 
     | 
    
         
             
            require_paths:
         
     | 
| 
       103 
122 
     | 
    
         
             
            - lib
         
     | 
| 
       104 
     | 
    
         
            -
            - lib
         
     | 
| 
       105 
123 
     | 
    
         
             
            required_ruby_version: !ruby/object:Gem::Requirement
         
     | 
| 
       106 
124 
     | 
    
         
             
              none: false
         
     | 
| 
       107 
125 
     | 
    
         
             
              requirements:
         
     | 
| 
         @@ -119,5 +137,5 @@ rubyforge_project: 
     | 
|
| 
       119 
137 
     | 
    
         
             
            rubygems_version: 1.8.25
         
     | 
| 
       120 
138 
     | 
    
         
             
            signing_key: 
         
     | 
| 
       121 
139 
     | 
    
         
             
            specification_version: 3
         
     | 
| 
       122 
     | 
    
         
            -
            summary: Factor.io 
     | 
| 
      
 140 
     | 
    
         
            +
            summary: CLI to manager workflows on Factor.io
         
     | 
| 
       123 
141 
     | 
    
         
             
            test_files: []
         
     | 
    
        data/lib/channel/activity.rb
    DELETED
    
    
    
        data/lib/channel/channel.rb
    DELETED
    
    
    
        data/lib/channel/event.rb
    DELETED
    
    
    
        data/lib/channel/listener.rb
    DELETED
    
    | 
         @@ -1,20 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require 'rubygems'
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            module Factor  
         
     | 
| 
       4 
     | 
    
         
            -
              module Channel
         
     | 
| 
       5 
     | 
    
         
            -
                class Listener
         
     | 
| 
       6 
     | 
    
         
            -
                  attr_accessor :workflow_id, :event
         
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
                  def start(user_id,channel_name,listener_name,event,workflow_name,params,&code)
         
     | 
| 
       9 
     | 
    
         
            -
                  end
         
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
                  def stop()
         
     | 
| 
       12 
     | 
    
         
            -
                  end
         
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
                  def initialize(workflow_id,event)
         
     | 
| 
       15 
     | 
    
         
            -
                    @workflow_id=workflow_id
         
     | 
| 
       16 
     | 
    
         
            -
                    @event=event
         
     | 
| 
       17 
     | 
    
         
            -
                  end
         
     | 
| 
       18 
     | 
    
         
            -
                end
         
     | 
| 
       19 
     | 
    
         
            -
              end
         
     | 
| 
       20 
     | 
    
         
            -
            end
         
     | 
    
        data/lib/channel/trigger.rb
    DELETED
    
    
    
        data/lib/cli/channel_task.rb
    DELETED
    
    | 
         @@ -1,37 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require 'rubygems'
         
     | 
| 
       2 
     | 
    
         
            -
            require 'cli/command'
         
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
            module Factor
         
     | 
| 
       5 
     | 
    
         
            -
              module CLI
         
     | 
| 
       6 
     | 
    
         
            -
                class ChannelTask < Command
         
     | 
| 
       7 
     | 
    
         
            -
                  desc "list", "list all the channels"
         
     | 
| 
       8 
     | 
    
         
            -
                  #method_option :key, :alias=>"-k", :type=>:string, :desc=>"key reference"
         
     | 
| 
       9 
     | 
    
         
            -
                  def list
         
     | 
| 
       10 
     | 
    
         
            -
                    @client.get_channels().each do |channel|
         
     | 
| 
       11 
     | 
    
         
            -
                      puts "#{channel['name']} (#{channel['slug']})"
         
     | 
| 
       12 
     | 
    
         
            -
                      puts "  Listeners:" if channel['listeners'].count>0
         
     | 
| 
       13 
     | 
    
         
            -
                      channel['listeners'].each do |listener|
         
     | 
| 
       14 
     | 
    
         
            -
                        puts "    #{listener['name']}: #{listener['description']}"
         
     | 
| 
       15 
     | 
    
         
            -
                      end
         
     | 
| 
       16 
     | 
    
         
            -
                      puts "  Actions:" if channel['actions'].count>0
         
     | 
| 
       17 
     | 
    
         
            -
                      channel['actions'].each do |action|
         
     | 
| 
       18 
     | 
    
         
            -
                        puts "    #{action['name']}: #{action['description']}"
         
     | 
| 
       19 
     | 
    
         
            -
                      end
         
     | 
| 
       20 
     | 
    
         
            -
                    end
         
     | 
| 
       21 
     | 
    
         
            -
                  end
         
     | 
| 
       22 
     | 
    
         
            -
                
         
     | 
| 
       23 
     | 
    
         
            -
                  desc "create DIRECTORY DEFINITION", "add a key and value for the credential"
         
     | 
| 
       24 
     | 
    
         
            -
                  method_option :organization, :alias=>"-o", :type=>:string, :desc=>"Organizoation to which this workflow belongs"
         
     | 
| 
       25 
     | 
    
         
            -
                  def create(directory,definition_file)
         
     | 
| 
       26 
     | 
    
         
            -
                    puts @client.create_channel(directory,definition_file,options[:organization])["notice"]
         
     | 
| 
       27 
     | 
    
         
            -
                  end
         
     | 
| 
       28 
     | 
    
         
            -
                
         
     | 
| 
       29 
     | 
    
         
            -
                  desc "delete NAME", "remove a workflow"
         
     | 
| 
       30 
     | 
    
         
            -
                  def delete(name)
         
     | 
| 
       31 
     | 
    
         
            -
                    puts @client.delete_channel(name)["notice"]
         
     | 
| 
       32 
     | 
    
         
            -
                  end
         
     | 
| 
       33 
     | 
    
         
            -
              
         
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
                end
         
     | 
| 
       36 
     | 
    
         
            -
              end
         
     | 
| 
       37 
     | 
    
         
            -
            end
         
     | 
    
        data/lib/cli/command.rb
    DELETED
    
    | 
         @@ -1,36 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require 'rubygems'
         
     | 
| 
       2 
     | 
    
         
            -
            require 'thor'
         
     | 
| 
       3 
     | 
    
         
            -
            require 'thor/group'
         
     | 
| 
       4 
     | 
    
         
            -
            require 'yaml'
         
     | 
| 
       5 
     | 
    
         
            -
            require 'rest_client'
         
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
            module Factor
         
     | 
| 
       9 
     | 
    
         
            -
              module CLI
         
     | 
| 
       10 
     | 
    
         
            -
                class Command < Thor
         
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
                  
         
     | 
| 
       14 
     | 
    
         
            -
                  no_tasks do
         
     | 
| 
       15 
     | 
    
         
            -
                    
         
     | 
| 
       16 
     | 
    
         
            -
                    def initialize(*vals)
         
     | 
| 
       17 
     | 
    
         
            -
                      @config_file_dir = File.expand_path("~/.factor") 
         
     | 
| 
       18 
     | 
    
         
            -
                      @client = Factor::Client::Client.new
         
     | 
| 
       19 
     | 
    
         
            -
                      @client.login_token(get_config['token'])
         
     | 
| 
       20 
     | 
    
         
            -
                      super(*vals)
         
     | 
| 
       21 
     | 
    
         
            -
                    end
         
     | 
| 
       22 
     | 
    
         
            -
                    
         
     | 
| 
       23 
     | 
    
         
            -
                    def save_config(config)
         
     | 
| 
       24 
     | 
    
         
            -
                      File.open(@config_file_dir,'w') do |file|
         
     | 
| 
       25 
     | 
    
         
            -
                        YAML::dump(config,file)
         
     | 
| 
       26 
     | 
    
         
            -
                      end
         
     | 
| 
       27 
     | 
    
         
            -
                      @client.login_token(get_config['token'])
         
     | 
| 
       28 
     | 
    
         
            -
                    end
         
     | 
| 
       29 
     | 
    
         
            -
                
         
     | 
| 
       30 
     | 
    
         
            -
                    def get_config
         
     | 
| 
       31 
     | 
    
         
            -
                      File.exists?(@config_file_dir) ? YAML::load_file(@config_file_dir) : {}
         
     | 
| 
       32 
     | 
    
         
            -
                    end
         
     | 
| 
       33 
     | 
    
         
            -
                  end
         
     | 
| 
       34 
     | 
    
         
            -
                end
         
     | 
| 
       35 
     | 
    
         
            -
              end
         
     | 
| 
       36 
     | 
    
         
            -
            end
         
     | 
    
        data/lib/cli/credential_task.rb
    DELETED
    
    | 
         @@ -1,39 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require 'rubygems'
         
     | 
| 
       2 
     | 
    
         
            -
            require 'cli/command'
         
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
            module Factor
         
     | 
| 
       5 
     | 
    
         
            -
              module CLI
         
     | 
| 
       6 
     | 
    
         
            -
                class CredentialTask < Command
         
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
                
         
     | 
| 
       9 
     | 
    
         
            -
                  desc "create SERVICE NAME VALUE", "add a key and value for the credential"
         
     | 
| 
       10 
     | 
    
         
            -
                  method_option :key, :type=>:string, :desc=>"File reference containing the symmetric key for encryption"
         
     | 
| 
       11 
     | 
    
         
            -
                  method_option :organization, :type=>:string, :desc=>"Organizoation to which this credential belongs"
         
     | 
| 
       12 
     | 
    
         
            -
                  def create(service,name,value)
         
     | 
| 
       13 
     | 
    
         
            -
                    secret=nil
         
     | 
| 
       14 
     | 
    
         
            -
                    if options[:key]
         
     | 
| 
       15 
     | 
    
         
            -
                      secret=File.read(options[:key])
         
     | 
| 
       16 
     | 
    
         
            -
                    end
         
     | 
| 
       17 
     | 
    
         
            -
                    puts @client.create_credential(service,name,value,secret,options[:organization])
         
     | 
| 
       18 
     | 
    
         
            -
                  end
         
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
                  desc "list", "get all of the credential"
         
     | 
| 
       21 
     | 
    
         
            -
                  def list()
         
     | 
| 
       22 
     | 
    
         
            -
                    @client.get_credentials["value"].each do |service,values|
         
     | 
| 
       23 
     | 
    
         
            -
                      # puts "#{credential['service']} : #{credential['name']} (#{credential['slug']}): #{credential['value']}"
         
     | 
| 
       24 
     | 
    
         
            -
                      puts "#{service}:"
         
     | 
| 
       25 
     | 
    
         
            -
                      values.each do |key,values|
         
     | 
| 
       26 
     | 
    
         
            -
                      #   puts "#{key['value']} (#{value['slug']}) : #{value}"
         
     | 
| 
       27 
     | 
    
         
            -
                        puts "  #{key} (#{values['slug']}): ***"
         
     | 
| 
       28 
     | 
    
         
            -
                      end
         
     | 
| 
       29 
     | 
    
         
            -
                    end
         
     | 
| 
       30 
     | 
    
         
            -
                  end
         
     | 
| 
       31 
     | 
    
         
            -
                
         
     | 
| 
       32 
     | 
    
         
            -
                  desc "delete SERVICE NAME", "remove a value from the credentials bag"
         
     | 
| 
       33 
     | 
    
         
            -
                  def delete(service,name)
         
     | 
| 
       34 
     | 
    
         
            -
                    puts @client.delete_credential(service,name)
         
     | 
| 
       35 
     | 
    
         
            -
                  end
         
     | 
| 
       36 
     | 
    
         
            -
                
         
     | 
| 
       37 
     | 
    
         
            -
                end
         
     | 
| 
       38 
     | 
    
         
            -
              end
         
     | 
| 
       39 
     | 
    
         
            -
            end
         
     | 
    
        data/lib/cli/factor_task.rb
    DELETED
    
    | 
         @@ -1,26 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require 'rubygems'
         
     | 
| 
       2 
     | 
    
         
            -
            require 'cli/command'
         
     | 
| 
       3 
     | 
    
         
            -
            require 'cli/workflow_task'
         
     | 
| 
       4 
     | 
    
         
            -
            require 'cli/credential_task'
         
     | 
| 
       5 
     | 
    
         
            -
            require 'cli/channel_task'
         
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
            module Factor
         
     | 
| 
       8 
     | 
    
         
            -
              module CLI
         
     | 
| 
       9 
     | 
    
         
            -
                class FactorTask < Command
         
     | 
| 
       10 
     | 
    
         
            -
              
         
     | 
| 
       11 
     | 
    
         
            -
                  desc "login EMAIL TOKEN", "login with token"
         
     | 
| 
       12 
     | 
    
         
            -
                  # method_option :email, :alias=>"-e", :type=>:string, :desc=>"Email address for Factor account", :required=>true
         
     | 
| 
       13 
     | 
    
         
            -
                  # method_option :token, :alias=>"-t", :type=>:string, :desc=>"Token value to set", :required=>true
         
     | 
| 
       14 
     | 
    
         
            -
                  def login(email,token)
         
     | 
| 
       15 
     | 
    
         
            -
                    config = get_config
         
     | 
| 
       16 
     | 
    
         
            -
                    config['email']=email
         
     | 
| 
       17 
     | 
    
         
            -
                    config['token']=token
         
     | 
| 
       18 
     | 
    
         
            -
                    save_config(config)
         
     | 
| 
       19 
     | 
    
         
            -
                  end
         
     | 
| 
       20 
     | 
    
         
            -
                end
         
     | 
| 
       21 
     | 
    
         
            -
              end
         
     | 
| 
       22 
     | 
    
         
            -
            end
         
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
            Factor::CLI::FactorTask.register(Factor::CLI::WorkflowTask,"workflow","workflow","start and list workflows")
         
     | 
| 
       25 
     | 
    
         
            -
            Factor::CLI::FactorTask.register(Factor::CLI::ChannelTask,"channel","channel","install,uninstall, list channels")
         
     | 
| 
       26 
     | 
    
         
            -
            Factor::CLI::FactorTask.register(Factor::CLI::CredentialTask,"credential","credential","manage remote credential store")
         
     | 
    
        data/lib/cli/workflow_task.rb
    DELETED
    
    | 
         @@ -1,49 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require 'rubygems'
         
     | 
| 
       2 
     | 
    
         
            -
            require 'cli/command'
         
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
            module Factor
         
     | 
| 
       5 
     | 
    
         
            -
              module CLI
         
     | 
| 
       6 
     | 
    
         
            -
                class WorkflowTask < Command
         
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
                  desc "start WORKFLOW","start listener for workflow"
         
     | 
| 
       9 
     | 
    
         
            -
                  def start(workflow_name)
         
     | 
| 
       10 
     | 
    
         
            -
                    puts @client.start_workflow(workflow_name)["notice"]
         
     | 
| 
       11 
     | 
    
         
            -
                  end
         
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
                  desc "stop WORKFLOW","stop listener for workflow"
         
     | 
| 
       14 
     | 
    
         
            -
                  def stop(workflow_name)
         
     | 
| 
       15 
     | 
    
         
            -
                    puts @client.stop_workflow(workflow_name)["notice"]
         
     | 
| 
       16 
     | 
    
         
            -
                  end
         
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
                  desc "call WORKFLOW","call workflow"
         
     | 
| 
       19 
     | 
    
         
            -
                  method_option :parameters, :type=>:hash, :default=>{}, :required=>false
         
     | 
| 
       20 
     | 
    
         
            -
                  def call(workflow_name)
         
     | 
| 
       21 
     | 
    
         
            -
                    puts @client.call_workflow(workflow_name,options[:parameters])["notice"]
         
     | 
| 
       22 
     | 
    
         
            -
                  end
         
     | 
| 
       23 
     | 
    
         
            -
                  
         
     | 
| 
       24 
     | 
    
         
            -
                  
         
     | 
| 
       25 
     | 
    
         
            -
                  desc "list", "list all the workflows"
         
     | 
| 
       26 
     | 
    
         
            -
                  def list
         
     | 
| 
       27 
     | 
    
         
            -
                    @client.get_workflows().each do |workflow|
         
     | 
| 
       28 
     | 
    
         
            -
                      puts "#{workflow['name']} (#{workflow['slug']})"
         
     | 
| 
       29 
     | 
    
         
            -
                    end
         
     | 
| 
       30 
     | 
    
         
            -
                  end
         
     | 
| 
       31 
     | 
    
         
            -
                
         
     | 
| 
       32 
     | 
    
         
            -
                  desc "create NAME FILENAME", "add a key and value for the credential"
         
     | 
| 
       33 
     | 
    
         
            -
                  #method_option :key, :alias=>"-k", :type=>:string, :desc=>"key reference"
         
     | 
| 
       34 
     | 
    
         
            -
                  method_option :organization, :alias=>"-v", :type=>:string, :desc=>"Organizoation to which this workflow belongs"
         
     | 
| 
       35 
     | 
    
         
            -
                  def create(name,filename)
         
     | 
| 
       36 
     | 
    
         
            -
                    contents=File.open(File.expand_path(filename), "rb") {|f| f.read}
         
     | 
| 
       37 
     | 
    
         
            -
                    puts @client.create_workflow(name,contents,options[:organization])["notice"]
         
     | 
| 
       38 
     | 
    
         
            -
                  end
         
     | 
| 
       39 
     | 
    
         
            -
                
         
     | 
| 
       40 
     | 
    
         
            -
                  desc "delete NAME", "remove a workflow"
         
     | 
| 
       41 
     | 
    
         
            -
                  def delete(name)
         
     | 
| 
       42 
     | 
    
         
            -
                    puts @client.delete_workflow(name)
         
     | 
| 
       43 
     | 
    
         
            -
                  end
         
     | 
| 
       44 
     | 
    
         
            -
                  
         
     | 
| 
       45 
     | 
    
         
            -
                  
         
     | 
| 
       46 
     | 
    
         
            -
                  
         
     | 
| 
       47 
     | 
    
         
            -
                end
         
     | 
| 
       48 
     | 
    
         
            -
              end
         
     | 
| 
       49 
     | 
    
         
            -
            end
         
     | 
    
        data/lib/client/client.rb
    DELETED
    
    | 
         @@ -1,151 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require 'rubygems'
         
     | 
| 
       2 
     | 
    
         
            -
            require 'rest_client'
         
     | 
| 
       3 
     | 
    
         
            -
            require 'zip'
         
     | 
| 
       4 
     | 
    
         
            -
            require 'zip/zipfilesystem'
         
     | 
| 
       5 
     | 
    
         
            -
            require 'zip/zip'
         
     | 
| 
       6 
     | 
    
         
            -
            require 'open-uri'
         
     | 
| 
       7 
     | 
    
         
            -
            require 'digest/sha2'
         
     | 
| 
       8 
     | 
    
         
            -
            require 'openssl'
         
     | 
| 
       9 
     | 
    
         
            -
            require 'base64'
         
     | 
| 
       10 
     | 
    
         
            -
            require 'json'
         
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
            module Factor
         
     | 
| 
       14 
     | 
    
         
            -
              module Client
         
     | 
| 
       15 
     | 
    
         
            -
                class Client
         
     | 
| 
       16 
     | 
    
         
            -
                  attr_accessor :host
         
     | 
| 
       17 
     | 
    
         
            -
                  FACTOR_HOST = ENV["FACTOR_HOST"] || "factor.io"
         
     | 
| 
       18 
     | 
    
         
            -
                
         
     | 
| 
       19 
     | 
    
         
            -
                  def initialize(host=FACTOR_HOST)
         
     | 
| 
       20 
     | 
    
         
            -
                    @host=host
         
     | 
| 
       21 
     | 
    
         
            -
                  end
         
     | 
| 
       22 
     | 
    
         
            -
                
         
     | 
| 
       23 
     | 
    
         
            -
                  def login_token(token)
         
     | 
| 
       24 
     | 
    
         
            -
                    @token=token
         
     | 
| 
       25 
     | 
    
         
            -
                  end
         
     | 
| 
       26 
     | 
    
         
            -
                
         
     | 
| 
       27 
     | 
    
         
            -
                  def create_credential(service,name,value,secret=nil,organization=nil)
         
     | 
| 
       28 
     | 
    
         
            -
                    # this is a PUT not POST because it is technically editing, not creating a new one
         
     | 
| 
       29 
     | 
    
         
            -
                    credential = {:service=>service,:name=>name,:value=>value}
         
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
                    if secret
         
     | 
| 
       32 
     | 
    
         
            -
                      payload=value
         
     | 
| 
       33 
     | 
    
         
            -
                      sha256= Digest::SHA2.new(256)
         
     | 
| 
       34 
     | 
    
         
            -
                      encrypter = OpenSSL::Cipher.new("AES-256-CFB")
         
     | 
| 
       35 
     | 
    
         
            -
                      encrypter.encrypt
         
     | 
| 
       36 
     | 
    
         
            -
                      encrypter.key=Base64.encode64(sha256.digest(secret))
         
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
                      encrypted = Base64.encode64(encrypter.update(value) + encrypter.final)
         
     | 
| 
       39 
     | 
    
         
            -
                      credential[:value]=encrypted
         
     | 
| 
       40 
     | 
    
         
            -
                      credential[:encrypted]=true
         
     | 
| 
       41 
     | 
    
         
            -
                    end
         
     | 
| 
       42 
     | 
    
         
            -
                    path = !!organization ? "organizations/#{organization}/credentials" : "credentials"
         
     | 
| 
       43 
     | 
    
         
            -
                    rest_post(path,credential)
         
     | 
| 
       44 
     | 
    
         
            -
                  end
         
     | 
| 
       45 
     | 
    
         
            -
                  
         
     | 
| 
       46 
     | 
    
         
            -
                  def get_credentials()
         
     | 
| 
       47 
     | 
    
         
            -
                    rest_get("credentials")
         
     | 
| 
       48 
     | 
    
         
            -
                  end
         
     | 
| 
       49 
     | 
    
         
            -
                  
         
     | 
| 
       50 
     | 
    
         
            -
                  def delete_credential(service,name)
         
     | 
| 
       51 
     | 
    
         
            -
                    rest_delete("credentials",{:service=>service,:name=>name})
         
     | 
| 
       52 
     | 
    
         
            -
                  end
         
     | 
| 
       53 
     | 
    
         
            -
                
         
     | 
| 
       54 
     | 
    
         
            -
                
         
     | 
| 
       55 
     | 
    
         
            -
                
         
     | 
| 
       56 
     | 
    
         
            -
                
         
     | 
| 
       57 
     | 
    
         
            -
                  # untested
         
     | 
| 
       58 
     | 
    
         
            -
                  def create_workflow(key,definition,organization=nil)
         
     | 
| 
       59 
     | 
    
         
            -
                    path = !!organization ? "organizations/#{organization}/workflows" : "workflows"
         
     | 
| 
       60 
     | 
    
         
            -
                    rest_post(path,{:workflow=>{:name=>key,:definition=>definition}})
         
     | 
| 
       61 
     | 
    
         
            -
                  end
         
     | 
| 
       62 
     | 
    
         
            -
                  
         
     | 
| 
       63 
     | 
    
         
            -
                  def get_workflows()
         
     | 
| 
       64 
     | 
    
         
            -
                    rest_get("workflows")
         
     | 
| 
       65 
     | 
    
         
            -
                  end
         
     | 
| 
       66 
     | 
    
         
            -
                  
         
     | 
| 
       67 
     | 
    
         
            -
                  def delete_workflow(workflow_name)
         
     | 
| 
       68 
     | 
    
         
            -
                    rest_delete("workflows/#{workflow_name}")
         
     | 
| 
       69 
     | 
    
         
            -
                  end
         
     | 
| 
       70 
     | 
    
         
            -
             
     | 
| 
       71 
     | 
    
         
            -
                  def start_workflow(workflow_name)
         
     | 
| 
       72 
     | 
    
         
            -
                    rest_get("workflows/#{workflow_name}/state")
         
     | 
| 
       73 
     | 
    
         
            -
                  end
         
     | 
| 
       74 
     | 
    
         
            -
             
     | 
| 
       75 
     | 
    
         
            -
                  def stop_workflow(workflow_name)
         
     | 
| 
       76 
     | 
    
         
            -
                    rest_delete("workflows/#{workflow_name}/state")
         
     | 
| 
       77 
     | 
    
         
            -
                  end
         
     | 
| 
       78 
     | 
    
         
            -
             
     | 
| 
       79 
     | 
    
         
            -
                  def call_workflow(workflow_name,params)
         
     | 
| 
       80 
     | 
    
         
            -
                    rest_get("workflows/#{workflow_name}/call",params)
         
     | 
| 
       81 
     | 
    
         
            -
                  end
         
     | 
| 
       82 
     | 
    
         
            -
             
     | 
| 
       83 
     | 
    
         
            -
                  
         
     | 
| 
       84 
     | 
    
         
            -
                  
         
     | 
| 
       85 
     | 
    
         
            -
                  # channels
         
     | 
| 
       86 
     | 
    
         
            -
                  def create_channel(path,definition_file,organization=nil)
         
     | 
| 
       87 
     | 
    
         
            -
                    file=zip(File.expand_path(path))
         
     | 
| 
       88 
     | 
    
         
            -
                    definition = File.read(definition_file)
         
     | 
| 
       89 
     | 
    
         
            -
             
     | 
| 
       90 
     | 
    
         
            -
                    path = !!organization ? "organizations/#{organization}/channels" : "channels"
         
     | 
| 
       91 
     | 
    
         
            -
                    rest_post(path,{:zip=>file,:channel=>{:definition=>definition}})
         
     | 
| 
       92 
     | 
    
         
            -
                  end
         
     | 
| 
       93 
     | 
    
         
            -
                  
         
     | 
| 
       94 
     | 
    
         
            -
                  def get_channels()
         
     | 
| 
       95 
     | 
    
         
            -
                    rest_get("channels")
         
     | 
| 
       96 
     | 
    
         
            -
                  end
         
     | 
| 
       97 
     | 
    
         
            -
                  
         
     | 
| 
       98 
     | 
    
         
            -
                  def delete_channel(channel_name)
         
     | 
| 
       99 
     | 
    
         
            -
                    rest_delete("channels/#{channel_name}")
         
     | 
| 
       100 
     | 
    
         
            -
                  end
         
     | 
| 
       101 
     | 
    
         
            -
                  
         
     | 
| 
       102 
     | 
    
         
            -
                  
         
     | 
| 
       103 
     | 
    
         
            -
                
         
     | 
| 
       104 
     | 
    
         
            -
             
     | 
| 
       105 
     | 
    
         
            -
                
         
     | 
| 
       106 
     | 
    
         
            -
                
         
     | 
| 
       107 
     | 
    
         
            -
                  private
         
     | 
| 
       108 
     | 
    
         
            -
                
         
     | 
| 
       109 
     | 
    
         
            -
                  def zip(directory)
         
     | 
| 
       110 
     | 
    
         
            -
                    path=directory.dup
         
     | 
| 
       111 
     | 
    
         
            -
                    path.sub!(%r[/$],'')
         
     | 
| 
       112 
     | 
    
         
            -
                    zip_path = File.join(path,"..",File.basename(path))+'.zip'
         
     | 
| 
       113 
     | 
    
         
            -
                    FileUtils.rm zip_path, :force=>true
         
     | 
| 
       114 
     | 
    
         
            -
                    Zip::ZipFile.open(zip_path, 'w') do |zip|
         
     | 
| 
       115 
     | 
    
         
            -
                      Dir["#{path}/**/**"].reject{|f|f==zip_path}.each do |file|
         
     | 
| 
       116 
     | 
    
         
            -
                        zip.add(file.sub(path+'/',''),file)
         
     | 
| 
       117 
     | 
    
         
            -
                      end
         
     | 
| 
       118 
     | 
    
         
            -
                    end
         
     | 
| 
       119 
     | 
    
         
            -
                    File.open(zip_path,'r')
         
     | 
| 
       120 
     | 
    
         
            -
                  end
         
     | 
| 
       121 
     | 
    
         
            -
             
     | 
| 
       122 
     | 
    
         
            -
                  def rest_get(path,params={})
         
     | 
| 
       123 
     | 
    
         
            -
                    params["auth_token"]=@token
         
     | 
| 
       124 
     | 
    
         
            -
                    
         
     | 
| 
       125 
     | 
    
         
            -
                    param_string=params.map{|key,value| "#{key}=#{value}"}.join("&")
         
     | 
| 
       126 
     | 
    
         
            -
                    response=RestClient.get("http://#{@host}/#{path}.json?#{param_string}")
         
     | 
| 
       127 
     | 
    
         
            -
                    JSON.parse(response)
         
     | 
| 
       128 
     | 
    
         
            -
                  end
         
     | 
| 
       129 
     | 
    
         
            -
                  
         
     | 
| 
       130 
     | 
    
         
            -
                  def rest_put(path,params={})
         
     | 
| 
       131 
     | 
    
         
            -
                    params["auth_token"]=@token
         
     | 
| 
       132 
     | 
    
         
            -
                    response=RestClient.put("http://#{@host}/#{path}.json",params)
         
     | 
| 
       133 
     | 
    
         
            -
                    JSON.parse(response)
         
     | 
| 
       134 
     | 
    
         
            -
                  end
         
     | 
| 
       135 
     | 
    
         
            -
                  
         
     | 
| 
       136 
     | 
    
         
            -
                  def rest_post(path,params={})
         
     | 
| 
       137 
     | 
    
         
            -
                    response=RestClient.post("http://#{@host}/#{path}.json?auth_token=#{@token}",params)
         
     | 
| 
       138 
     | 
    
         
            -
                    JSON.parse(response)
         
     | 
| 
       139 
     | 
    
         
            -
                  end
         
     | 
| 
       140 
     | 
    
         
            -
                  
         
     | 
| 
       141 
     | 
    
         
            -
                  def rest_delete(path,params={})
         
     | 
| 
       142 
     | 
    
         
            -
                    params["auth_token"]=@token
         
     | 
| 
       143 
     | 
    
         
            -
                    
         
     | 
| 
       144 
     | 
    
         
            -
                    param_string=params.map{|key,value| "#{key}=#{value}"}.join("&")
         
     | 
| 
       145 
     | 
    
         
            -
                    response=RestClient.delete("http://#{@host}/#{path}.json?#{param_string}")
         
     | 
| 
       146 
     | 
    
         
            -
                    JSON.parse(response)
         
     | 
| 
       147 
     | 
    
         
            -
                  end
         
     | 
| 
       148 
     | 
    
         
            -
                
         
     | 
| 
       149 
     | 
    
         
            -
                end
         
     | 
| 
       150 
     | 
    
         
            -
              end
         
     | 
| 
       151 
     | 
    
         
            -
            end
         
     |