require 'zip/zip' require 'fileutils' module GoodData class NoProjectError < RuntimeError ; end class Project USERSPROJECTS_PATH = '/gdc/account/profile/%s/projects' PROJECTS_PATH = '/gdc/projects' PROJECT_PATH = '/gdc/projects/%s' SLIS_PATH = '/ldm/singleloadinterface' attr_accessor :connection class << self # Returns an array of all projects accessible by # current user def all json = GoodData.get GoodData.profile.projects json['projects'].map do |project| Project.new project['project'] end end # Returns a Project object identified by given string # The following identifiers are accepted # - /gdc/md/ # - /gdc/projects/ # - # def [](id) if id.to_s !~ /^(\/gdc\/(projects|md)\/)?[a-zA-Z\d]+$/ raise ArgumentError.new("wrong type of argument. Should be either project ID or path") end id = id.match(/[a-zA-Z\d]+$/)[0] if id =~ /\// response = GoodData.get PROJECT_PATH % id Project.new response['project'] end # Create a project from a given attributes # Expected keys: # - :title (mandatory) # - :summary # - :template (default /projects/blank) # def create(attributes) GoodData.logger.info "Creating project #{attributes[:title]}" auth_token = attributes.delete(:auth_token) || GoodData.connection.auth_token json = { 'meta' => { 'title' => attributes[:title], 'summary' => attributes[:summary] }, 'content' => { # 'state' => 'ENABLED', 'guidedNavigation' => 1, 'authorizationToken' => auth_token } } json['meta']['projectTemplate'] = attributes[:template] if attributes[:template] && !attributes[:template].empty? project = Project.new json project.save project end end def initialize(json) @json = json end def save response = GoodData.post PROJECTS_PATH, { 'project' => @json } if uri == nil response = GoodData.get response['uri'] @json = response['project'] end end def delete raise "Project '#{title}' with id #{uri} is already deleted" if state == :deleted GoodData.delete @json['links']['self'] end def uri @json['links']['self'] if @json['links'] && @json['links']['self'] end def obj_id uri.split('/').last end def title @json['meta']['title'] if @json['meta'] end def state @json['content']['state'].downcase.to_sym if @json['content'] && @json['content']['state'] end def md @md ||= Links.new GoodData.get(@json['links']['metadata']) end # Creates a data set within the project # # == Usage # p.add_dataset 'Test', [ { 'name' => 'a1', 'type' => 'ATTRIBUTE' ... } ... ] # p.add_dataset 'title' => 'Test', 'columns' => [ { 'name' => 'a1', 'type' => 'ATTRIBUTE' ... } ... ] # def add_dataset(schema, columns = nil) schema = { 'title' => schema, 'columns' => columns } if columns schema = Model::Schema.new schema if schema.is_a? Hash raise ArgumentError.new("Required either schema object or title plus columns array") unless schema.is_a? Model::Schema Model.add_schema schema, self end def upload(file, schema, mode = "FULL") schema.upload file, self, mode end def slis link = "#{@json['links']['metadata']}#{SLIS_PATH}" Metadata.new GoodData.get(link) end def datasets datasets_uri = "#{md['data']}/sets" response = GoodData.get datasets_uri response['dataSetsInfo']['sets'].map do |ds| DataSet.new ds end end def to_json @json end end end