Skip to content
Browse files

first commit

  • Loading branch information...
0 parents commit 0399c4397c5784863947b2328c7ba0b8a713577a @fluke777 fluke777 committed Jun 21, 2011
Showing with 327 additions and 0 deletions.
  1. +4 −0 .gitignore
  2. +7 −0 Gemfile
  3. 0 README
  4. +8 −0 Rakefile
  5. +1 −0 autotest/discover.rb
  6. +210 −0 lib/variable_uploader.rb
  7. +5 −0 lib/variable_uploader/version.rb
  8. +36 −0 spec/dsl_spec.rb
  9. +26 −0 spec/plan_spec.rb
  10. +2 −0 spec/values.txt
  11. +28 −0 variable_uploader.gemspec
4 .gitignore
@@ -0,0 +1,4 @@
+*.gem
+.bundle
+Gemfile.lock
+pkg/*
7 Gemfile
@@ -0,0 +1,7 @@
+gem 'gooddata', :path => '../gooddata-ruby'
+
+source "http://rubygems.org"
+
+# Specify your gem's dependencies in variable_uploader.gemspec
+gemspec
+
0 README
No changes.
8 Rakefile
@@ -0,0 +1,8 @@
+require 'rubygems'
+require 'bundler/setup'
+require 'rake'
+require 'rspec/core/rake_task'
+
+Bundler::GemHelper.install_tasks
+
+RSpec::Core::RakeTask.new
1 autotest/discover.rb
@@ -0,0 +1 @@
+Autotest.add_discovery { "rspec2" }
210 lib/variable_uploader.rb
@@ -0,0 +1,210 @@
+require 'fastercsv'
+require 'gooddata'
+require 'pp'
+require 'logger'
+
+module GoodData
+ module VariableUploader
+
+ class Variable
+ attr_accessor :uri
+ end
+
+ class Step
+
+ attr_reader :variable_uri, :filename, :display_form_uri, :logger
+
+ def initialize(filename, variable_uri, label_uri)
+ @filename = filename
+ @variable_uri = variable_uri
+ @display_form_uri = label_uri
+ end
+
+ def values
+ return @values unless @values.nil?
+ get_values
+ end
+
+ def get_values
+ data = FasterCSV.read(filename)
+ vals = {}
+ data.each do |line|
+ vals.has_key?(line.first) ? vals[line.first].concat(line[1..-1]) : vals[line.first] = line[1..-1]
+ end
+ @values = vals
+ end
+
+ def run(variable_logger, project)
+ @logger = variable_logger
+ # get variable
+ variable = GoodData::MdObject[variable_uri]
+
+ logger.debug("Updating variable #{variable.title}") if logger
+ attribute = GoodData::MdObject[variable.content["attribute"]]
+
+ # get display form
+ default_label = get_default_display_form(attribute)
+
+ elements_lookup = create_elements_lookup(default_label)
+ users_lookup = create_users_lookup(project)
+
+ # Create the values to be created
+ expressions_by_user = create_expressions_for_update(users_lookup, elements_lookup)
+
+
+ # Create the current values
+ updated, new_el = gather_updates(project, variable, expressions_by_user)
+
+ logger.debug("New values #{new_el.size}") if logger
+ logger.debug("Updated values #{updated.size}") if logger
+
+ data_to_send = []
+ (updated + new_el).each do |user|
+ data_to_send << {
+ :expression => "[#{attribute.uri}] IN (#{user[:values].map {|v| "[#{v}]"}.join(", ")})",
+ :level => "user",
+ :prompt => variable.uri,
+ :related => user[:user],
+ :type => "filter"
+ } unless user[:values].empty?
+ end
+
+ updated.each do |update|
+ GoodData.delete(update[:uri])
+ end
+
+ GoodData.post("/gdc/md/#{project.obj_id}/variables/user", ({:variables => data_to_send}))
+ end
+
+ private
+
+ def create_expressions_for_update(users_lookup, elements_lookup)
+ expressions_by_user = {}
+ get_values.each do |key, value|
+ if users_lookup.has_key?(key)
+ expressions_by_user[users_lookup[key]] = value.inject([]) do |all, val|
+ if elements_lookup.has_key?(val)
+ all << elements_lookup[val]
+ else
+ @logger.warn("Value #{val} for #{key} will not be used.")
+ all
+ end
+ end
+ else
+ @logger.warn("Values for #{key} will not be used. User not found in project.")
+ end
+ end
+ expressions_by_user
+ end
+
+ def create_users_lookup(project)
+ users_lookup = {}
+ GoodData.get("#{project.uri}/users")["users"].each do |user|
+ user = user["user"]
+ users_lookup[user["content"]["email"]] = user["links"]["self"]
+ end
+ users_lookup
+ end
+
+ def get_default_display_form(attribute)
+ if display_form_uri.nil?
+ labels = attribute.content["displayForms"].collect do |df|
+ GoodData::MdObject[df["meta"]["uri"]]
+ end
+ labels.detect do |label|
+ label.content["default"] == 1
+ end
+ else
+ GoodData::MdObject[display_form_uri]
+ end
+ end
+
+ def create_elements_lookup(default_label)
+ elements = GoodData.get(default_label.links["elements"])
+ # pp elements
+ elements_lookup = {}
+
+ elements["attributeElements"]["elements"].each do |element|
+ elements_lookup[element["title"]] = element["uri"]
+ end
+ elements_lookup
+ end
+
+ def gather_updates(project, variable, expressions_by_user)
+ search = GoodData::post("/gdc/md/#{project.obj_id}/variables/search", {"variablesSearch" => {
+ "variables" => [variable.uri],
+ "context" => []
+ }})
+ current_expressions_by_user = {}
+ search["variables"].each do |var|
+ current_expressions_by_user[var["related"]] = {
+ :values => var['objects'].find_all {|obj| obj["category"] == "attributeElement"}.collect {|obj| obj["uri"]},
+ :uri => var["uri"]
+ }
+ end
+
+ # Compare and work only with new or changed, deleted
+ updated = []
+ new_el = []
+ expressions_by_user.each do |profile_uri, values|
+ a = current_expressions_by_user[profile_uri]
+ b = values
+
+ if a.nil?
+ new_el << {:user => profile_uri, :values => values}
+ else
+ user = {:user => profile_uri, :values => values, :uri => a[:uri]}
+ updated << user unless ((a[:values] | b) - (a[:values] & b)).empty?
+ end
+ end
+ [updated, new_el]
+ end
+ end
+
+ module DSL
+
+ class Project
+
+ attr_reader :steps
+
+ def self.update(options = {}, &block)
+ self.new(options, &block)
+ end
+
+ def initialize(options = {}, &block)
+ @login = options[:login]
+ @password = options[:pass]
+ @pid = options[:pid]
+ @steps = []
+ instance_eval(&block)
+ run
+ end
+
+ def run
+ # GoodData.logger = Logger.new(STDOUT)
+ GoodData.connect(@login, @password)
+ p = GoodData.use(@pid)
+
+ logger = Logger.new(STDOUT)
+
+ steps.each do |step|
+ step.run(logger, p)
+ end
+ end
+
+ def upload(options={})
+ raise "Specify file name or values" if (options[:values].nil? && options[:file].nil?)
+ raise "Variable needs to be defined" if options[:variable].nil?
+
+ # if options[:values]
+ # raise "Values need to be of type Hash" unless options[:values].kind_of? Hash
+ # @steps << Step.new(options[:values], Variable.new)
+ # else
+ @steps << Step.new(options[:file], options[:variable], options[:label])
+ # end
+ end
+ end
+
+ end
+ end
+end
5 lib/variable_uploader/version.rb
@@ -0,0 +1,5 @@
+module GoodData
+ module VariableUploader
+ VERSION = "0.0.1"
+ end
+end
36 spec/dsl_spec.rb
@@ -0,0 +1,36 @@
+require 'lib/variable_uploader'
+
+include GoodData::VariableUploader
+include GoodData::VariableUploader::DSL
+
+describe "DSL" do
+
+ before :each do
+ @plan = Plan.new do
+ upload :file => 'spec/values.txt', :variable => '/gdc/1'
+ upload :file => 'spec/another_values.txt', :variable => '/gdc/2'
+ end
+ end
+
+ it "should generate plan" do
+ @plan.steps.size.should equal 2
+ @plan.steps.first.values.size.should equal 2
+ end
+
+ it "each step should have a path for values file" do
+ step1 = @plan.steps.first
+ step1.filename.should == "spec/values.txt"
+
+ step2 = @plan.steps[1]
+ step2.filename.should == "spec/another_values.txt"
+ end
+
+ it "should have defined the variable" do
+ step1 = @plan.steps.first
+ step1.variable_uri.should == "/gdc/1"
+
+ step2 = @plan.steps[1]
+ step2.variable_uri.should == "/gdc/2"
+ end
+
+end
26 spec/plan_spec.rb
@@ -0,0 +1,26 @@
+require 'lib/variable_uploader'
+
+include GoodData::VariableUploader
+include GoodData::VariableUploader::DSL
+
+describe "Step" do
+
+ before :each do
+ @step = Step.new("spec/values.txt", "/gdc/1")
+
+ # @variable = double('Manager variable')
+ # @variable.stub(:uri).and_return('/gdc/variable/123')
+ #
+ # @step = Step.new({
+ # "john@example.com" => [1,2,4]
+ # }, @variable)
+ end
+
+ it "should be able to return the values as is" do
+ @step.values
+ values.class.should be Hash
+ values.has_key?("john@example.com").should be
+ values["john@example.com"].should == [1,2,4]
+ end
+
+end
2 spec/values.txt
@@ -0,0 +1,2 @@
+john@example.com,small,big,medium
+jane@example.com,small
28 variable_uploader.gemspec
@@ -0,0 +1,28 @@
+# -*- encoding: utf-8 -*-
+$:.push File.expand_path("../lib", __FILE__)
+require "variable_uploader/version"
+
+Gem::Specification.new do |s|
+ s.name = "variable_uploader"
+ s.version = GoodData::VariableUploader::VERSION
+ s.platform = Gem::Platform::RUBY
+ s.authors = ["Tomas Svarovsky"]
+ s.email = ["svarovsky.tomas@gmail.com"]
+ s.homepage = ""
+ s.summary = %q{Wrapper on GoodData ruby gem that should make uploading varaibles easier}
+ s.description = %q{Wrapper on GoodData ruby gem that should make uploading varaibles easier==}
+
+ s.rubyforge_project = "variable_uploader"
+
+ s.files = `git ls-files`.split("\n")
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
+ s.require_paths = ["lib"]
+
+ s.add_dependency "rspec"
+ s.add_dependency "rake"
+ s.add_dependency "fastercsv"
+ # s.add_dependency "gooddata"
+
+end
+

0 comments on commit 0399c43

Please sign in to comment.
Something went wrong with that request. Please try again.