class Flow::Flow

A Tableau Prep Flow file.

Attributes

base[R]
build[R]
dataSourceNamesMap[R]
datasource[R]
datasourceNames[R]
datasourceUINames[R]
datasources[R]
dir[R]
modtime[R]
name[R]
platform[R]
root[R]
type[R]
version[R]

Public Class Methods

new(tflWithDir) click to toggle source

Creates a Flow from its file name.

Parameters:

flowWithDir

The Flow's file name, the Flow can be a TWB or TWBX file.
# File lib/tfl/Flow.rb, line 47
def initialize tflWithDir
  raise ArgumentError.new("ERROR in Flow creation: '#{tflWithDir}' must be a String, is a #{tflWithDir.class} \n ")    unless tflWithDir.is_a? String
  raise ArgumentError.new("ERROR in Flow creation: '#{tflWithDir}' must have an extension of .tfl or .tflx \n ")       unless tflWithDir.upcase.end_with?(".TFL", ".TFLX")
  raise ArgumentError.new("ERROR in Flow creation: '#{tflWithDir}' must must be a file, is a Directory\\Folder \n ")   if File.directory?(tflWithDir)
  raise ArgumentError.new("ERROR in Flow creation: '#{tflWithDir}' cannot be found, must be a Tableau Flow file. \n ") unless File.file?(tflWithDir)
  @valid = false
  if File.file?(tflWithDir) then
    @name    = File.basename(tflWithDir)
    @dir     = File.dirname(File.expand_path(tflWithDir))
    @modtime = File.new(tflWithDir).mtime.strftime("%Y-%m-%d %H:%M:%S")
    case File.extname(tflWithDir).downcase
      when '.tlf'  then processTFL(tflWithDir)
      when '.tflx' then processTFLX(flowWithDir)
    end
  end
end

Public Instance Methods

actionNames() click to toggle source
# File lib/tfl/Flow.rb, line 104
def actionNames
  @actions.keys
end
actions() click to toggle source
# File lib/tfl/Flow.rb, line 100
def actions
  @actions.values
end
dashboard(name) click to toggle source
# File lib/tfl/Flow.rb, line 96
def dashboard name
  @dashboards[name]
end
dashboardNames() click to toggle source
# File lib/tfl/Flow.rb, line 92
def dashboardNames
  @dashboards.keys
end
dashboards() click to toggle source
# File lib/tfl/Flow.rb, line 88
def dashboards
  @dashboards.values
end
id() click to toggle source
# File lib/tfl/Flow.rb, line 64
def id
    @id ||= @id = @name.hash
end
orphanDataSources() click to toggle source
# File lib/tfl/Flow.rb, line 116
def orphanDataSources
  @orphanDataSources ||= identifyOrphandatasoUrceS
end
parameters() click to toggle source
# File lib/tfl/Flow.rb, line 112
def parameters
  @parameters ||= loadParameters
end
release() click to toggle source
# File lib/tfl/Flow.rb, line 72
def release
  @build ||= loadBuild
end
storyboard(name) click to toggle source
# File lib/tfl/Flow.rb, line 128
def storyboard name
  @storyboards[name]
end
storyboardNames() click to toggle source
# File lib/tfl/Flow.rb, line 124
def storyboardNames
  @storyboards.keys
end
storyboards() click to toggle source
# File lib/tfl/Flow.rb, line 120
def storyboards
  @storyboards.values
end
worksheet(name) click to toggle source
# File lib/tfl/Flow.rb, line 80
def worksheet name
  @worksheets[name]
end
worksheetNames() click to toggle source
# File lib/tfl/Flow.rb, line 84
def worksheetNames
  @worksheets.keys
end
worksheets() click to toggle source
# File lib/tfl/Flow.rb, line 76
def worksheets
  @worksheets.values
end

Private Instance Methods

ensureDashboardsNodeExists() click to toggle source

Make sure that the TWB has a <dashboards> node. It's possible for a TWB to have no dashboards, and therefore no <dashboards> node.

# File lib/tfl/Flow.rb, line 267
def ensureDashboardsNodeExists
  if @dashesNode.nil?
    @dashesNode = Nokogiri::XML::Node.new "dashboards", @ndoc
    # TODO fix this @dataSourcesNode.add_next_sibling(@dashesNode)
  end
end
ensureWindowsNodeExists() click to toggle source
# File lib/tfl/Flow.rb, line 274
def ensureWindowsNodeExists
  if @windowsnode.nil?
    @windowsnode = Nokogiri::XML::Node.new "windows", @ndoc
    # TODO fix this @dataSourcesNode.add_next_sibling(@windowsnode)
  end
end
getNewDashboardTitle(t) click to toggle source
# File lib/tfl/Flow.rb, line 281
def getNewDashboardTitle(t)
  title = t
  if @datasources.include?(title)
    inc = 0
    loop do
      inc+=1
      title = t + ' ' + inc.to_s
      if !@datasources.include?(title)
        break
      end
    end
  end
  return title
end
identifyOrphandatasoUrceS() click to toggle source
# File lib/tfl/Flow.rb, line 242
def identifyOrphandatasoUrceS
  sheetDataSources = Set.new
  @worksheets.values.each do |sheet|
    sheet.datasources.each do |ds|
        sheetDataSources << ds.uiname
    end
  end
  @orphanDataSources = @datasourceUINames - sheetDataSources
end
loadActions() click to toggle source
# File lib/tfl/Flow.rb, line 233
def loadActions
  @actions = {}
  actionNodes = @ndoc.xpath("//flow/actions/action")
  actionNodes.each do |anode|
    action = Twb::Action.new(anode, @flownode)
    @actions[action.uiname] = action
  end
end
loadBuild() click to toggle source
# File lib/tfl/Flow.rb, line 153
def loadBuild
  # - earlier Version, need to confirm when source-build began
  #   @build   = @ndoc.xpath('/flow/comment()').text.gsub(/^[^0-9]+/,'').strip
  @build = if !@ndoc.at_xpath('/flow/@source-build').nil?
               @ndoc.at_xpath('/flow/@source-build').text
           else 
               if @ndoc.at_xpath('/flow/comment()').nil?
                  'not found'
               else
                  @ndoc.at_xpath('/flow/comment()').text.gsub(/^[^0-9]+/,'').strip
              end
           end
end
loadDashboards() click to toggle source
# File lib/tfl/Flow.rb, line 202
def loadDashboards
  @dashesNode = @ndoc.at_xpath('//flow/dashboards')
  @dashboards = {}
  dashes = @ndoc.xpath('//flow/dashboards/dashboard').to_a
  dashes.each do |node|
    unless node.attr('type') == 'storyboard' then
      dashboard = Twb::Dashboard.new(node, @worksheets)
      @dashboards[dashboard.name] = dashboard
    end
  end
end
loadParameters() click to toggle source
# File lib/tfl/Flow.rb, line 296
def loadParameters
  @parameters = {}
  paramsDS = ndoc.at_xpath('./flow/datasources/datasource[@name="Parameters"]')
  unless paramsDS.nil?
    paramNodes = paramsDS.xpath('.//column')
    paramNodes.each do |pn|
      parameter = Twb::Parameter.new pn
      @parameters[parameter.name] = parameter
    end
  end
  return @parameters
end
loadStoryboards() click to toggle source
# File lib/tfl/Flow.rb, line 214
def loadStoryboards
  @storyboards = {}
  boards = @ndoc.xpath("//flow/dashboards/dashboard[@type='storyboard']" ).to_a
  boards.each do |node|
    sheet = Twb::Storyboard.new(node)
    @storyboards[sheet.name] = sheet
  end
end
loadWindows() click to toggle source
# File lib/tfl/Flow.rb, line 223
def loadWindows
  @windowsnode = @ndoc.at_xpath("//flow/windows")
  @windows = {}
  windows  = @ndoc.xpath("//flow/windows/window[@name]")
  windows.each do |node|
    window = Twb::Window.new(node)
    @windows[window.name] = window
  end
end
loadWorksheets() click to toggle source
# File lib/tfl/Flow.rb, line 188
def loadWorksheets
  @worksheets  = {}
  hiddenSheets = []
  @ndoc.xpath('//flow/windows/window[@hidden="true"]').each do |hs|
    hiddenSheets << hs['name']
  end
  sheets = @ndoc.xpath('//flow/worksheets/worksheet' ).to_a
  sheets.each do |node|
    sheet = Twb::Worksheet.new(node, self)
    sheet.hidden = hiddenSheets.include? sheet.name 
    @worksheets[sheet.name] = sheet
  end
end
loaddatasources() click to toggle source
# File lib/tfl/Flow.rb, line 167
def loaddatasources
  # puts "LOAD DATA SOURCES"
  # @dataSourcesNode = @ndoc.at_xpath('//flow/datasources')
  @datasources        = Set.new
  @datasourceNames    = SortedSet.new
  @datasourceUINames  = SortedSet.new
  @dataSourceNamesMap = {}
  datasourceNodes     = @ndoc.xpath('//flow/datasources/datasource')
  # puts "DATASOURCENODES : #{@datasourceNodes.length}"
  datasourceNodes.each do |node|
    datasource = Twb::DataSource.new(node,self)
    @datasources << datasource
    @datasourceNames    << datasource.name
    @datasourceNames    << datasource.uiname
    @datasourceUINames  << datasource.uiname
    @dataSourceNamesMap[datasource.name]   = datasource 
    @dataSourceNamesMap[datasource.uiname] = datasource 
  end
  # puts "DATASOURCES    : #{@datasources.length}"
end
processDoc() click to toggle source
# File lib/tfl/Flow.rb, line 149
def processDoc
  @valid = true
end
processTFL(twbFile) click to toggle source
# File lib/tfl/Flow.rb, line 143
def processTFL(twbFile)
  @ndoc = Nokogiri::XML(open(twbFile))
  @type = :twb
  processDoc
end
processTFLX(twbxWithDir) click to toggle source
# File lib/tfl/Flow.rb, line 134
def processTFLX(twbxWithDir)
  Zip::File.open(twbxWithDir) do |zip_file|
    twb   = zip_file.glob('*.twb').first
    @ndoc = Nokogiri::XML(twb.get_input_stream)
    @type = :twbx
    processDoc
  end
end
writeTwb(name=@name) click to toggle source
# File lib/tfl/Flow.rb, line 252
def writeTwb(name=@name)
  $f = File.open(name,'w')
  if $f
      $f.puts @ndoc
      $f.close
  end
  return name
end
writeTwbx(name=@name) click to toggle source
# File lib/tfl/Flow.rb, line 261
def writeTwbx(name=@name)
    emit  "Writing the Workbook, need implementation"
end