clienteer 1.3.0
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.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +41 -0
- data/Rakefile +6 -0
- data/bin/console +11 -0
- data/bin/setup +7 -0
- data/clienteer.gemspec +28 -0
- data/lib/clienteer.rb +37 -0
- data/lib/clienteer/digester.rb +8 -0
- data/lib/clienteer/digesters/address_creation.rb +14 -0
- data/lib/clienteer/digesters/ideal_protein_cross_reference.rb +62 -0
- data/lib/clienteer/digesters/indexes_clean_up.rb +32 -0
- data/lib/clienteer/digesters/phase_creation.rb +16 -0
- data/lib/clienteer/ingester.rb +6 -0
- data/lib/clienteer/ingesters/mindbody.rb +24 -0
- data/lib/clienteer/outgester.rb +6 -0
- data/lib/clienteer/outgesters/maliero.rb +51 -0
- data/lib/clienteer/sanitizer.rb +7 -0
- data/lib/clienteer/sanitizers/address.rb +22 -0
- data/lib/clienteer/sanitizers/name.rb +16 -0
- data/lib/clienteer/sanitizers/nil_finder.rb +18 -0
- data/lib/clienteer/version.rb +3 -0
- data/rakelib/ideal_protein.rake +78 -0
- metadata +154 -0
    
        checksums.yaml
    ADDED
    
    | @@ -0,0 +1,7 @@ | |
| 1 | 
            +
            ---
         | 
| 2 | 
            +
            SHA1:
         | 
| 3 | 
            +
              metadata.gz: 2edb0404572927c398532476a1367032e1b7d487
         | 
| 4 | 
            +
              data.tar.gz: 716b3eababc36336e5db4ee815f10b362c74cb93
         | 
| 5 | 
            +
            SHA512:
         | 
| 6 | 
            +
              metadata.gz: 64d7a8920971e53c17fabc8a6ffa357b227ddb9c2d8641e95b31e9207bb44430bf7d75ccb81d82e1990b2a8a65ac3ebab9907b437bac6018be2415c5f8c49056
         | 
| 7 | 
            +
              data.tar.gz: cc8764bad98d4c5a373d28bed56d459c60205c55e60303ebc4d0621eefa4448c1384dee5ab95f83245f75565b0179170d41434ef4ecb627b598cff010d6211bd
         | 
    
        data/.gitignore
    ADDED
    
    
    
        data/.rspec
    ADDED
    
    
    
        data/.travis.yml
    ADDED
    
    
    
        data/Gemfile
    ADDED
    
    
    
        data/LICENSE.txt
    ADDED
    
    | @@ -0,0 +1,21 @@ | |
| 1 | 
            +
            The MIT License (MIT)
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            Copyright (c) 2015 Patrick Metcalfe
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            Permission is hereby granted, free of charge, to any person obtaining a copy
         | 
| 6 | 
            +
            of this software and associated documentation files (the "Software"), to deal
         | 
| 7 | 
            +
            in the Software without restriction, including without limitation the rights
         | 
| 8 | 
            +
            to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
         | 
| 9 | 
            +
            copies of the Software, and to permit persons to whom the Software is
         | 
| 10 | 
            +
            furnished to do so, subject to the following conditions:
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            The above copyright notice and this permission notice shall be included in
         | 
| 13 | 
            +
            all copies or substantial portions of the Software.
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
         | 
| 16 | 
            +
            IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
         | 
| 17 | 
            +
            FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
         | 
| 18 | 
            +
            AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
         | 
| 19 | 
            +
            LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
         | 
| 20 | 
            +
            OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
         | 
| 21 | 
            +
            THE SOFTWARE.
         | 
    
        data/README.md
    ADDED
    
    | @@ -0,0 +1,41 @@ | |
| 1 | 
            +
            # Clienteer
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/clienteer`. To experiment with that code, run `bin/console` for an interactive prompt.
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            TODO: Delete this and the text above, and describe your gem
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            ## Installation
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            Add this line to your application's Gemfile:
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            ```ruby
         | 
| 12 | 
            +
            gem 'clienteer'
         | 
| 13 | 
            +
            ```
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            And then execute:
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                $ bundle
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            Or install it yourself as:
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                $ gem install clienteer
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            ## Usage
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            TODO: Write usage instructions here
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            ## Development
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
         | 
| 30 | 
            +
             | 
| 31 | 
            +
            To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
         | 
| 32 | 
            +
             | 
| 33 | 
            +
            ## Contributing
         | 
| 34 | 
            +
             | 
| 35 | 
            +
            Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/clienteer.
         | 
| 36 | 
            +
             | 
| 37 | 
            +
             | 
| 38 | 
            +
            ## License
         | 
| 39 | 
            +
             | 
| 40 | 
            +
            The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
         | 
| 41 | 
            +
             | 
    
        data/Rakefile
    ADDED
    
    
    
        data/bin/console
    ADDED
    
    | @@ -0,0 +1,11 @@ | |
| 1 | 
            +
            #!/usr/bin/env ruby
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require "bundler/setup"
         | 
| 4 | 
            +
            require "clienteer"
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            # You can add fixtures and/or initialization code here to make experimenting
         | 
| 7 | 
            +
            # with your gem easier. You can also use a different console, if you like.
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            # (If you use this, don't forget to add pry to your Gemfile!)
         | 
| 10 | 
            +
            require "pry"
         | 
| 11 | 
            +
            Pry.start
         | 
    
        data/bin/setup
    ADDED
    
    
    
        data/clienteer.gemspec
    ADDED
    
    | @@ -0,0 +1,28 @@ | |
| 1 | 
            +
            # coding: utf-8
         | 
| 2 | 
            +
            lib = File.expand_path('../lib', __FILE__)
         | 
| 3 | 
            +
            $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
         | 
| 4 | 
            +
            require 'clienteer/version'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            Gem::Specification.new do |spec|
         | 
| 7 | 
            +
              spec.name          = "clienteer"
         | 
| 8 | 
            +
              spec.version       = Clienteer::VERSION
         | 
| 9 | 
            +
              spec.authors       = ["Patrick Metcalfe"]
         | 
| 10 | 
            +
              spec.email         = ["git@patrickmetcalfe.com"]
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              spec.summary       = %q{Kiba for a legacy client system.}
         | 
| 13 | 
            +
              spec.homepage      = "http://maliero.herokuapp.com"
         | 
| 14 | 
            +
              spec.license       = "MIT"
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              spec.files         = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
         | 
| 17 | 
            +
              spec.bindir        = "exe"
         | 
| 18 | 
            +
              spec.executables   = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
         | 
| 19 | 
            +
              spec.require_paths = ["lib"]
         | 
| 20 | 
            +
             | 
| 21 | 
            +
              spec.add_dependency "kiba"
         | 
| 22 | 
            +
              spec.add_dependency "ruby-progressbar"
         | 
| 23 | 
            +
             | 
| 24 | 
            +
              spec.add_development_dependency "bundler", "~> 1.10"
         | 
| 25 | 
            +
              spec.add_development_dependency "rake", "~> 10.0"
         | 
| 26 | 
            +
              spec.add_development_dependency "rspec"
         | 
| 27 | 
            +
              spec.add_development_dependency "pry"
         | 
| 28 | 
            +
            end
         | 
    
        data/lib/clienteer.rb
    ADDED
    
    | @@ -0,0 +1,37 @@ | |
| 1 | 
            +
            require "clienteer/version"
         | 
| 2 | 
            +
            require "clienteer/ingester"
         | 
| 3 | 
            +
            require "clienteer/outgester"
         | 
| 4 | 
            +
            require "clienteer/digester"
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            require "kiba"
         | 
| 7 | 
            +
            require "mindbody-api"
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            module Clienteer
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              ::MindBody.configure do |config|
         | 
| 12 | 
            +
                config.site_ids    = ENV["MINDBODY_SITE_IDS"]
         | 
| 13 | 
            +
                config.source_key  = ENV["MINDBODY_SOURCE_KEY"]
         | 
| 14 | 
            +
                config.source_name = ENV["MINDBODY_SOURCE_NAME"]
         | 
| 15 | 
            +
                config.log_level   = :debug # Savon logging level. Default is :debug, options are [:debug, :info, :warn, :error, :fatal]
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              def self.call
         | 
| 19 | 
            +
                $count = 0
         | 
| 20 | 
            +
                $skipped_people = []
         | 
| 21 | 
            +
                job_definition = Kiba.parse do
         | 
| 22 | 
            +
                  source Ingester::Mindbody
         | 
| 23 | 
            +
                  transform Digester::IdealProteinCrossReference
         | 
| 24 | 
            +
                  transform Digester::AddressCreation
         | 
| 25 | 
            +
                  transform Digester::PhaseCreation
         | 
| 26 | 
            +
                  destination Outgester::Maliero
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                Kiba.run job_definition
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                File.open("data/skipped_people", "a+") do |f|
         | 
| 32 | 
            +
                  f.write $skipped_people.join(",")
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
              end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
            end
         | 
| @@ -0,0 +1,14 @@ | |
| 1 | 
            +
             | 
| 2 | 
            +
            module Clienteer
         | 
| 3 | 
            +
              module Digester
         | 
| 4 | 
            +
                class AddressCreation
         | 
| 5 | 
            +
                  def initialize
         | 
| 6 | 
            +
                  end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                  def process(row)
         | 
| 9 | 
            +
                    row["address"] = Address.new(first_line: row[:raw].address_line1, second_line: row[:raw].address_line2, city: row[:raw].city, state: row[:raw].state, zip_code: row[:raw].postal_code)
         | 
| 10 | 
            +
                    row
         | 
| 11 | 
            +
                  end
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
            end
         | 
| @@ -0,0 +1,62 @@ | |
| 1 | 
            +
            require "json"
         | 
| 2 | 
            +
            require "pry"
         | 
| 3 | 
            +
            module Clienteer
         | 
| 4 | 
            +
              module Digester
         | 
| 5 | 
            +
                class IdealProteinCrossReference
         | 
| 6 | 
            +
                  def initialize
         | 
| 7 | 
            +
                    @data = JSON.parse File.read("data/ideal_protein.clean.json")
         | 
| 8 | 
            +
                    optimized_data
         | 
| 9 | 
            +
                  end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                  def optimized_data
         | 
| 12 | 
            +
                    @optimized_data ||= @data.group_by do |c|
         | 
| 13 | 
            +
                      ln = c["last_name"]
         | 
| 14 | 
            +
                    end
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  def process(row)
         | 
| 18 | 
            +
                    person = find_ideal_protein_client(row)
         | 
| 19 | 
            +
                    return nil if person.nil?
         | 
| 20 | 
            +
                    row.tap do |r|
         | 
| 21 | 
            +
                      r["ideal_subscription_id"] = person["ideal_subscription_id"].to_i
         | 
| 22 | 
            +
                      r["phase"] = person["phase"].to_i
         | 
| 23 | 
            +
                      r["ideal_protein_birthday"] = person["birthday"]
         | 
| 24 | 
            +
                    end
         | 
| 25 | 
            +
                  rescue
         | 
| 26 | 
            +
                    $stderr.puts(row.inspect)
         | 
| 27 | 
            +
                    raise
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  def find_ideal_protein_client(row)
         | 
| 31 | 
            +
                    person = find_by_email(row[:raw].email) || find_by_name(last: row[:raw].last_name, first: row[:raw].first_name) || ask_for_verification(row)
         | 
| 32 | 
            +
                  end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                  def find_by_name(first:, last:)
         | 
| 35 | 
            +
                    first_letter = last[0]
         | 
| 36 | 
            +
                    if @optimized_data[first_letter].nil?
         | 
| 37 | 
            +
                      @data.find { |r| r["first_name"].downcase == first.downcase && r["last_name"].downcase == last.downcase }
         | 
| 38 | 
            +
                    else
         | 
| 39 | 
            +
                      @optimized_data.find { |r| r["first_name"].downcase == first.downcase && r["last_name"].downcase == last.downcase }
         | 
| 40 | 
            +
                    end
         | 
| 41 | 
            +
                  end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                  def find_by_email(email)
         | 
| 44 | 
            +
                    @data.find { |c| c["email"].downcase == email.downcase }
         | 
| 45 | 
            +
                  end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                  def ask_for_verification(row)
         | 
| 48 | 
            +
                    # text = []
         | 
| 49 | 
            +
                    # text << "\tVerification\t\t".underline.light_red.bold
         | 
| 50 | 
            +
                    # text << "There was a problem matching #{row['full_name']} with an ideal protein client.".light_black
         | 
| 51 | 
            +
                    # text << ""
         | 
| 52 | 
            +
                    # text << "The client's data is:" + "#{row.inspect}".cyan
         | 
| 53 | 
            +
                    # text << "Should I skip this person or not?".magenta.bold
         | 
| 54 | 
            +
                    # print text.join("\n")
         | 
| 55 | 
            +
                    # bool = IO.gets.chomp!.include?("y")
         | 
| 56 | 
            +
                    $skipped_people << row[:raw].id
         | 
| 57 | 
            +
                    nil
         | 
| 58 | 
            +
                  end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
              end
         | 
| 62 | 
            +
            end
         | 
| @@ -0,0 +1,32 @@ | |
| 1 | 
            +
            module Clienteer
         | 
| 2 | 
            +
              module Digester
         | 
| 3 | 
            +
                class IndexesCleanUp
         | 
| 4 | 
            +
                  def initialize
         | 
| 5 | 
            +
                  end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                  def process(row)
         | 
| 8 | 
            +
                    row["health_profile"] = get_index("health_profile", row: row)
         | 
| 9 | 
            +
                    row["blood_work"] = get_index("blood_work", row: row)
         | 
| 10 | 
            +
                  end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  def get_index(attr, row: )
         | 
| 13 | 
            +
                    indexes = row["indexes"]
         | 
| 14 | 
            +
                    if indexes.is_a? Hash
         | 
| 15 | 
            +
                      if indexes[:name] == row
         | 
| 16 | 
            +
                        return pull_out_attr from: indexes
         | 
| 17 | 
            +
                      end
         | 
| 18 | 
            +
                    else
         | 
| 19 | 
            +
                      index = indexes.find { |i| i[:name] == row }
         | 
| 20 | 
            +
                      return pull_out_attr from: index
         | 
| 21 | 
            +
                    end
         | 
| 22 | 
            +
                    nil
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                  private
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                  def pull_out_attr(from: index)
         | 
| 28 | 
            +
                    from[:values][:client_index_value][:name]
         | 
| 29 | 
            +
                  end
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
            end
         | 
| @@ -0,0 +1,16 @@ | |
| 1 | 
            +
            require "pry"
         | 
| 2 | 
            +
            module Clienteer
         | 
| 3 | 
            +
              module Digester
         | 
| 4 | 
            +
                class PhaseCreation
         | 
| 5 | 
            +
                  def initialize
         | 
| 6 | 
            +
                  end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                  def process(row)
         | 
| 9 | 
            +
                    $count += 1
         | 
| 10 | 
            +
                    binding.pry unless $count >= 20
         | 
| 11 | 
            +
                    row["phase"] = Phase.where(number: row["phase"]).first
         | 
| 12 | 
            +
                    row
         | 
| 13 | 
            +
                  end
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
            end
         | 
| @@ -0,0 +1,24 @@ | |
| 1 | 
            +
            require 'ruby-progressbar'
         | 
| 2 | 
            +
            module Clienteer
         | 
| 3 | 
            +
              module Ingester
         | 
| 4 | 
            +
                class Mindbody
         | 
| 5 | 
            +
                  def initialize
         | 
| 6 | 
            +
                    $progressbar = ProgressBar.create total: 2059, format: '%a %bᗧ%i %p%% %t', progress_mark: ' ', remainder_mark: '・'
         | 
| 7 | 
            +
                    @clients = get_clients
         | 
| 8 | 
            +
                  end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  def self.get_clients
         | 
| 11 | 
            +
                    hash = {"Username" => ENV["MINDBODY_USERNAME"], "Password" => ENV["MINDBODY_PASSWORD"], "SiteIDs" => {"int" => ENV["MINDBODY_SITE_IDS"]}}
         | 
| 12 | 
            +
                    alpha = ::MindBody::Services::ClientService.get_clients("UserCredentials"  => hash, "SearchText" => "")
         | 
| 13 | 
            +
                    alpha.result[:clients]
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  def each
         | 
| 17 | 
            +
                    @clients.each do |c|
         | 
| 18 | 
            +
                      object = {raw: c}
         | 
| 19 | 
            +
                      yield object
         | 
| 20 | 
            +
                    end
         | 
| 21 | 
            +
                  end
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
            end
         | 
| @@ -0,0 +1,51 @@ | |
| 1 | 
            +
            module Clienteer
         | 
| 2 | 
            +
              module Outgester
         | 
| 3 | 
            +
                class Maliero
         | 
| 4 | 
            +
                  def initialize
         | 
| 5 | 
            +
                    @clients = []
         | 
| 6 | 
            +
                  end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                  def write(row)
         | 
| 9 | 
            +
                    $progressbar.increment
         | 
| 10 | 
            +
                    @clients << new_client(row)
         | 
| 11 | 
            +
                  end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  def new_client(row)
         | 
| 14 | 
            +
                    Client.find_or_create_by(first_name: row[:raw].first_name, last_name: row[:raw].first_name) do |c|
         | 
| 15 | 
            +
                      c.mindbody_id = row[:raw].id.to_s
         | 
| 16 | 
            +
                      c.birthdate = row[:raw].birth_date
         | 
| 17 | 
            +
                      c.gender = row[:raw].gender
         | 
| 18 | 
            +
                      # c.blood_work = row["blood_work"]
         | 
| 19 | 
            +
                      # c.constant_contact = row["constant_contact"]
         | 
| 20 | 
            +
                      c.email = row[:raw].email
         | 
| 21 | 
            +
                      # c.health_profile = row["health_profile"]
         | 
| 22 | 
            +
                      c.ideal_subscription_id = row["ideal_subscription_id"].to_s
         | 
| 23 | 
            +
                      c.ideal_protein_subscription = !row["ideal_subscription_id"].nil?
         | 
| 24 | 
            +
                      # c.needs_blood_work = row["needs_blood_work"]
         | 
| 25 | 
            +
                      # c.newsletter = row["newsletter"]
         | 
| 26 | 
            +
                      c.notes = row[:raw].notes
         | 
| 27 | 
            +
                      c.phase = row["phase"]
         | 
| 28 | 
            +
                      c.phone_number = row[:raw].home_phone || row[:raw].mobile_phone || nil
         | 
| 29 | 
            +
                      c.address = row["address"]
         | 
| 30 | 
            +
                    end
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  def close
         | 
| 34 | 
            +
                    $stderr.puts "\n\n\nHELLO\n\n\n\n"
         | 
| 35 | 
            +
                    binding.pry
         | 
| 36 | 
            +
                    Client.transaction do
         | 
| 37 | 
            +
                      success = @clients.map(&:save)
         | 
| 38 | 
            +
                      unless success.all?
         | 
| 39 | 
            +
                        binding.pry
         | 
| 40 | 
            +
                        errored = @clients.select{ |b| !b.errors.blank? }
         | 
| 41 | 
            +
                        errored.each do |e|
         | 
| 42 | 
            +
                          e.save!(validate: false)
         | 
| 43 | 
            +
                        end
         | 
| 44 | 
            +
                        # do something with the errored values
         | 
| 45 | 
            +
                        raise ActiveRecord::Rollback
         | 
| 46 | 
            +
                      end
         | 
| 47 | 
            +
                    end
         | 
| 48 | 
            +
                  end
         | 
| 49 | 
            +
                end
         | 
| 50 | 
            +
              end
         | 
| 51 | 
            +
            end
         | 
| @@ -0,0 +1,22 @@ | |
| 1 | 
            +
             | 
| 2 | 
            +
            module Clienteer
         | 
| 3 | 
            +
              module Sanitizer
         | 
| 4 | 
            +
                class Address
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                  def process(row)
         | 
| 7 | 
            +
                    address = row["address"]
         | 
| 8 | 
            +
                    return nil unless check_zip_code address
         | 
| 9 | 
            +
                    clean_state address
         | 
| 10 | 
            +
                    row
         | 
| 11 | 
            +
                  end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  def check_zip_code(address)
         | 
| 14 | 
            +
                    address.zip_code.match /\A\d{5}(-\d{4})?\Z/
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  def clean_state(address)
         | 
| 18 | 
            +
                    address.state = "Illinois" if address.state.match /il/i
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
            end
         | 
| @@ -0,0 +1,16 @@ | |
| 1 | 
            +
             | 
| 2 | 
            +
            module Clienteer
         | 
| 3 | 
            +
              module Sanitizer
         | 
| 4 | 
            +
                class Name
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                  def process(row)
         | 
| 7 | 
            +
                    names = [row[:raw].first_name, row[:raw].last_name]
         | 
| 8 | 
            +
                    names.any?(&:not_proper?) ? nil : row
         | 
| 9 | 
            +
                  end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                  def not_proper?(name)
         | 
| 12 | 
            +
                    return true if name.match /\d/
         | 
| 13 | 
            +
                  end
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
            end
         | 
| @@ -0,0 +1,18 @@ | |
| 1 | 
            +
             | 
| 2 | 
            +
            module Clienteer
         | 
| 3 | 
            +
              module Sanitizer
         | 
| 4 | 
            +
                class NilFinder
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                  def process(row)
         | 
| 7 | 
            +
                    raw = row[:raw]
         | 
| 8 | 
            +
                    attrs = [row, raw, raw.first_name, raw.last_name, raw.email]
         | 
| 9 | 
            +
                    return nil if contains_nils? attrs
         | 
| 10 | 
            +
                    row
         | 
| 11 | 
            +
                  end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  def contains_nils?(attrs)
         | 
| 14 | 
            +
                    attrs.any? {|a| a.nil? }
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
            end
         | 
| @@ -0,0 +1,78 @@ | |
| 1 | 
            +
            require 'open-uri'
         | 
| 2 | 
            +
            require 'json'
         | 
| 3 | 
            +
            module IdealProtein
         | 
| 4 | 
            +
              class Clean
         | 
| 5 | 
            +
                EDIT_URL_REGEX = /\/clinic\/(\d+)\/dieter\/(\d+)\/edit/.freeze
         | 
| 6 | 
            +
                class << self
         | 
| 7 | 
            +
                  def open_file
         | 
| 8 | 
            +
                    File.read("data/ideal_protein.json")
         | 
| 9 | 
            +
                  end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                  def data
         | 
| 12 | 
            +
                    @data ||= JSON.parse(open_file)
         | 
| 13 | 
            +
                  end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                  def cleaned_data
         | 
| 16 | 
            +
                    @cleaned_data ||= data["aaData"].map do |r|
         | 
| 17 | 
            +
                      row = {}
         | 
| 18 | 
            +
                      row[:first_name], row[:last_name] = r[0].split(" ")
         | 
| 19 | 
            +
                      row[:birthday] = r[1]
         | 
| 20 | 
            +
                      row[:empty] = r[2]
         | 
| 21 | 
            +
                      row[:email] = r[3]
         | 
| 22 | 
            +
                      row[:phase] = r[4][-1].to_i
         | 
| 23 | 
            +
                      row[:verified] = r[5].to_i.eql?(1)
         | 
| 24 | 
            +
                      row[:ideal_subscription_id] = r[6]["edit"]["attr"]["href"].match(EDIT_URL_REGEX)[1].to_i
         | 
| 25 | 
            +
                      row
         | 
| 26 | 
            +
                    end
         | 
| 27 | 
            +
                  end
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
              class Update
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                LOGIN_COOKIES = ENV["CLIENTEER_LOGIN_COOKIES"]
         | 
| 34 | 
            +
                class << self
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                  def ideal_protein_path(number: total_clients_number, page: 2)
         | 
| 37 | 
            +
                    "http://my.idealprotein.com/clinic/12195/dieter/browse.json?sEcho=#{page}&iColumns=7&sColumns=&iDisplayStart=0&iDisplayLength=#{number}&mDataProp_0=0&mDataProp_1=1&mDataProp_2=2&mDataProp_3=3&mDataProp_4=4&mDataProp_5=5&mDataProp_6=6&sSearch=&bRegex=false&sSearch_0=&bRegex_0=false&bSearchable_0=true&sSearch_1=&bRegex_1=false&bSearchable_1=true&sSearch_2=&bRegex_2=false&bSearchable_2=true&sSearch_3=&bRegex_3=false&bSearchable_3=true&sSearch_4=&bRegex_4=false&bSearchable_4=true&sSearch_5=&bRegex_5=false&bSearchable_5=true&sSearch_6=&bRegex_6=false&bSearchable_6=true&iSortCol_0=0&sSortDir_0=asc&iSortingCols=1&bSortable_0=true&bSortable_1=true&bSortable_2=true&bSortable_3=true&bSortable_4=true&bSortable_5=true&bSortable_6=false&sDateFrom=&sDateTo=&sPhase=&sStatus="
         | 
| 38 | 
            +
                  end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  def total_clients_number
         | 
| 41 | 
            +
                    @@total_clients_number ||= begin
         | 
| 42 | 
            +
                      response = make_request url: ideal_protein_path(number: 1)
         | 
| 43 | 
            +
                      response["iTotalRecords"].to_i
         | 
| 44 | 
            +
                    end
         | 
| 45 | 
            +
                  end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                  def make_request(url: )
         | 
| 48 | 
            +
                    buffer = open(url, "Cookie" => COOKIES).read
         | 
| 49 | 
            +
                    JSON.parse(buffer)
         | 
| 50 | 
            +
                  end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                  def get_clients
         | 
| 53 | 
            +
                    make_request url: ideal_protein_path
         | 
| 54 | 
            +
                  end
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
              end
         | 
| 57 | 
            +
            end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
            namespace "ideal_protein" do
         | 
| 60 | 
            +
             | 
| 61 | 
            +
              task :default => :clean
         | 
| 62 | 
            +
             | 
| 63 | 
            +
              desc "Cleans Ideal Protein client information"
         | 
| 64 | 
            +
              task :clean do
         | 
| 65 | 
            +
                json = IdealProtein::Clean.cleaned_data
         | 
| 66 | 
            +
                File.open("data/ideal_protein.clean.json", "w+") do |f|
         | 
| 67 | 
            +
                  f.write(JSON.pretty_generate(json))
         | 
| 68 | 
            +
                end
         | 
| 69 | 
            +
              end
         | 
| 70 | 
            +
             | 
| 71 | 
            +
              desc "Updates Ideal Protein client information"
         | 
| 72 | 
            +
              task :update do
         | 
| 73 | 
            +
                json = IdealProtein::Update.get_clients
         | 
| 74 | 
            +
                File.open("data/ideal_protein.json", "w+") do |f|
         | 
| 75 | 
            +
                  f.write(JSON.pretty_generate(json))
         | 
| 76 | 
            +
                end
         | 
| 77 | 
            +
              end
         | 
| 78 | 
            +
            end
         | 
    
        metadata
    ADDED
    
    | @@ -0,0 +1,154 @@ | |
| 1 | 
            +
            --- !ruby/object:Gem::Specification
         | 
| 2 | 
            +
            name: clienteer
         | 
| 3 | 
            +
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            +
              version: 1.3.0
         | 
| 5 | 
            +
            platform: ruby
         | 
| 6 | 
            +
            authors:
         | 
| 7 | 
            +
            - Patrick Metcalfe
         | 
| 8 | 
            +
            autorequire: 
         | 
| 9 | 
            +
            bindir: exe
         | 
| 10 | 
            +
            cert_chain: []
         | 
| 11 | 
            +
            date: 2015-07-15 00:00:00.000000000 Z
         | 
| 12 | 
            +
            dependencies:
         | 
| 13 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 14 | 
            +
              name: kiba
         | 
| 15 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 16 | 
            +
                requirements:
         | 
| 17 | 
            +
                - - ">="
         | 
| 18 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            +
                    version: '0'
         | 
| 20 | 
            +
              type: :runtime
         | 
| 21 | 
            +
              prerelease: false
         | 
| 22 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 | 
            +
                requirements:
         | 
| 24 | 
            +
                - - ">="
         | 
| 25 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            +
                    version: '0'
         | 
| 27 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 28 | 
            +
              name: ruby-progressbar
         | 
| 29 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 30 | 
            +
                requirements:
         | 
| 31 | 
            +
                - - ">="
         | 
| 32 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 33 | 
            +
                    version: '0'
         | 
| 34 | 
            +
              type: :runtime
         | 
| 35 | 
            +
              prerelease: false
         | 
| 36 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 37 | 
            +
                requirements:
         | 
| 38 | 
            +
                - - ">="
         | 
| 39 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 40 | 
            +
                    version: '0'
         | 
| 41 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 42 | 
            +
              name: bundler
         | 
| 43 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 44 | 
            +
                requirements:
         | 
| 45 | 
            +
                - - "~>"
         | 
| 46 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 47 | 
            +
                    version: '1.10'
         | 
| 48 | 
            +
              type: :development
         | 
| 49 | 
            +
              prerelease: false
         | 
| 50 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 51 | 
            +
                requirements:
         | 
| 52 | 
            +
                - - "~>"
         | 
| 53 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 54 | 
            +
                    version: '1.10'
         | 
| 55 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 56 | 
            +
              name: rake
         | 
| 57 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 58 | 
            +
                requirements:
         | 
| 59 | 
            +
                - - "~>"
         | 
| 60 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 61 | 
            +
                    version: '10.0'
         | 
| 62 | 
            +
              type: :development
         | 
| 63 | 
            +
              prerelease: false
         | 
| 64 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 65 | 
            +
                requirements:
         | 
| 66 | 
            +
                - - "~>"
         | 
| 67 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 68 | 
            +
                    version: '10.0'
         | 
| 69 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 70 | 
            +
              name: rspec
         | 
| 71 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 72 | 
            +
                requirements:
         | 
| 73 | 
            +
                - - ">="
         | 
| 74 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 75 | 
            +
                    version: '0'
         | 
| 76 | 
            +
              type: :development
         | 
| 77 | 
            +
              prerelease: false
         | 
| 78 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 79 | 
            +
                requirements:
         | 
| 80 | 
            +
                - - ">="
         | 
| 81 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 82 | 
            +
                    version: '0'
         | 
| 83 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 84 | 
            +
              name: pry
         | 
| 85 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 86 | 
            +
                requirements:
         | 
| 87 | 
            +
                - - ">="
         | 
| 88 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 89 | 
            +
                    version: '0'
         | 
| 90 | 
            +
              type: :development
         | 
| 91 | 
            +
              prerelease: false
         | 
| 92 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 93 | 
            +
                requirements:
         | 
| 94 | 
            +
                - - ">="
         | 
| 95 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 96 | 
            +
                    version: '0'
         | 
| 97 | 
            +
            description: 
         | 
| 98 | 
            +
            email:
         | 
| 99 | 
            +
            - git@patrickmetcalfe.com
         | 
| 100 | 
            +
            executables: []
         | 
| 101 | 
            +
            extensions: []
         | 
| 102 | 
            +
            extra_rdoc_files: []
         | 
| 103 | 
            +
            files:
         | 
| 104 | 
            +
            - ".gitignore"
         | 
| 105 | 
            +
            - ".rspec"
         | 
| 106 | 
            +
            - ".travis.yml"
         | 
| 107 | 
            +
            - Gemfile
         | 
| 108 | 
            +
            - LICENSE.txt
         | 
| 109 | 
            +
            - README.md
         | 
| 110 | 
            +
            - Rakefile
         | 
| 111 | 
            +
            - bin/console
         | 
| 112 | 
            +
            - bin/setup
         | 
| 113 | 
            +
            - clienteer.gemspec
         | 
| 114 | 
            +
            - lib/clienteer.rb
         | 
| 115 | 
            +
            - lib/clienteer/digester.rb
         | 
| 116 | 
            +
            - lib/clienteer/digesters/address_creation.rb
         | 
| 117 | 
            +
            - lib/clienteer/digesters/ideal_protein_cross_reference.rb
         | 
| 118 | 
            +
            - lib/clienteer/digesters/indexes_clean_up.rb
         | 
| 119 | 
            +
            - lib/clienteer/digesters/phase_creation.rb
         | 
| 120 | 
            +
            - lib/clienteer/ingester.rb
         | 
| 121 | 
            +
            - lib/clienteer/ingesters/mindbody.rb
         | 
| 122 | 
            +
            - lib/clienteer/outgester.rb
         | 
| 123 | 
            +
            - lib/clienteer/outgesters/maliero.rb
         | 
| 124 | 
            +
            - lib/clienteer/sanitizer.rb
         | 
| 125 | 
            +
            - lib/clienteer/sanitizers/address.rb
         | 
| 126 | 
            +
            - lib/clienteer/sanitizers/name.rb
         | 
| 127 | 
            +
            - lib/clienteer/sanitizers/nil_finder.rb
         | 
| 128 | 
            +
            - lib/clienteer/version.rb
         | 
| 129 | 
            +
            - rakelib/ideal_protein.rake
         | 
| 130 | 
            +
            homepage: http://maliero.herokuapp.com
         | 
| 131 | 
            +
            licenses:
         | 
| 132 | 
            +
            - MIT
         | 
| 133 | 
            +
            metadata: {}
         | 
| 134 | 
            +
            post_install_message: 
         | 
| 135 | 
            +
            rdoc_options: []
         | 
| 136 | 
            +
            require_paths:
         | 
| 137 | 
            +
            - lib
         | 
| 138 | 
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         | 
| 139 | 
            +
              requirements:
         | 
| 140 | 
            +
              - - ">="
         | 
| 141 | 
            +
                - !ruby/object:Gem::Version
         | 
| 142 | 
            +
                  version: '0'
         | 
| 143 | 
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 144 | 
            +
              requirements:
         | 
| 145 | 
            +
              - - ">="
         | 
| 146 | 
            +
                - !ruby/object:Gem::Version
         | 
| 147 | 
            +
                  version: '0'
         | 
| 148 | 
            +
            requirements: []
         | 
| 149 | 
            +
            rubyforge_project: 
         | 
| 150 | 
            +
            rubygems_version: 2.4.6
         | 
| 151 | 
            +
            signing_key: 
         | 
| 152 | 
            +
            specification_version: 4
         | 
| 153 | 
            +
            summary: Kiba for a legacy client system.
         | 
| 154 | 
            +
            test_files: []
         |