module Optimacms
  class Template < ApplicationRecord
    self.table_name = 'cms_templates'

    EXTENSION_DEFAULT = 'html'
    EXTENSIONS = {'blank'=>'', 'html'=>'html', 'erb'=>'html.erb', 'haml'=>'html.haml'}

    belongs_to :type, :foreign_key => 'type_id', :class_name => 'TemplateType', optional: true

    has_many :translations, foreign_key: 'item_id', class_name: 'TemplateTranslation', dependent: :destroy, :inverse_of => :template
    accepts_nested_attributes_for :translations

    has_many :data_relations, foreign_key: 'template_id', class_name: 'TemplateDataRelation', dependent: :destroy

    ### callbacks
    before_validation :_before_validation
    before_create :_before_create
    before_update :_before_update
    before_destroy :_before_destroy

    # tree
    has_ancestry

    #
    #validate :check_unique_path,  unless: :is_folder?
    validates_uniqueness_of :basepath, :scope => :is_folder

    #validate :check_parent_folder_exists,  unless: :is_folder?

    #
    paginates_per 10

    # scopes
    scope :folders, -> { where(is_folder: true) }
    scope :layouts, -> { where(is_folder: false, type_id: TemplateType::TYPE_LAYOUT) }
    scope :blocks , -> { where(is_folder: false, type_id: TemplateType::TYPE_BLOCKVIEW) }
    scope :blocks_or_partials , -> { where(is_folder: false, type_id: [TemplateType::TYPE_BLOCKVIEW, TemplateType::TYPE_PARTIAL]) }

    scope :of_parent, lambda {  |parent_id| where_parent(parent_id) }

    # search
    searchable_by_simple_filter

    ###
    def to_s
      "#{title} (#{basepath})"
    end

    ### settings

    def self.base_dir
      Rails.root.to_s + '/app/views/'
    end

    ### properties

    def parent_title
      self.parent.title
    end

    def has_code?
      ['haml', 'erb', 'blank'].include?(self.tpl_format)
    end

    def is_folder?
      self.is_folder
    end

    def is_layout?
      return self.type_id==TemplateType::TYPE_LAYOUT
    end

    def is_type_page?
      return self.type_id==TemplateType::TYPE_PAGE
    end

    def is_type_partial?
      return self.type_id==TemplateType::TYPE_PARTIAL
    end

    ### translations

    def build_translations
      #
      if is_translated
        langs = Language.list_with_default
      else
        langs = ['']
      end

      #
      langs_missing = langs - self.translations.all.map{|r| r.lang}

      langs_missing.each do |lang|
        self.translations.new(:lang=>lang)
      end

    end

    ##### search

    def self.where_parent(parent_id)
      if parent_id==0
        roots
      elsif parent_id>0
        children_of(parent_id.to_s)
      end
    end

    #### operations

    def attach
      # check if file exists
      if !content_file_exists?
        errors.add(:attach, "file not found")
        return false
      end

      save
    end

    #### path

    def path(lang='')
      return nil if self.basename.nil?
      self.basedirpath + filename_base + Template.filename_lang_postfix(lang) + Template.filename_ext_with_dot(self.tpl_format)
    end

    def fullpath(lang='')
      f = self.path(lang)
      return nil if f.nil?
      Template.base_dir + f
    end

    def content_file_exists?(lang='')
      postfixes = EXTENSIONS.map{|k,v| '.'+v}

      found = false
      postfixes.each do |p|
        if File.exists?(self.fullpath(lang))
          found = true
          break
        end
      end
      found
    end

    ### validations

    def check_parent_folder_exists
      if self.parent_id.nil? && !self.basedirpath.blank?
        errors.add(:basedirpath, "folder not exists. create it first")
      end
    end

    ##### folder

    def folder_path
      return nil if self.basepath.nil?
      self.basepath+'/'
    end

    def folder_fullpath
      f = self.folder_path
      return nil if f.nil?
      Template.base_dir + f
    end

    ### content

    def content(lang='')
       filename =  fullpath(lang)
       return nil if filename.nil?
       return '' if !File.exists? filename
       File.read(filename)
     end

     def content=(v, lang='')
       File.open(self.fullpath(lang), "w+") do |f|
         f.write(v)
       end
     end

    ### helpers for path

    # base filename depending on  type
    # for page = name
    # for partial = _name
    def filename_base
      return '_'+self.basename if self.is_type_partial?

      self.basename
    end

    def self.filename_lang_postfix(lang)
      lang = lang.to_s
      return '' if lang==''
      return '.'+lang
    end

    def self.filename_ext(format)
      EXTENSIONS[format]
    end

    def self.filename_ext_with_dot(format)
      ext = filename_ext(format)
      ext = '.'+ext unless ext.blank?
      ext
    end

    ### operations with path

    def set_basepath
      if self.parent.nil?
        self.basepath = self.basename
        self.basedirpath ||= ''
      else
        self.basepath = self.parent.basepath+'/'+self.basename
        self.basedirpath ||= self.parent.basepath+'/'
      end

    end

    def fix_basedirpath
      self.basedirpath ||= ''
      if !self.basedirpath.blank? && self.basedirpath[-1] !='/'
        self.basedirpath << '/'
      end
    end

    def set_basedirpath_from_parent
      v = ''
      if self.parent_id.nil?
        v = ''
      else
        v = self.parent.basepath+'/' if self.parent_id >0
      end

      self.basedirpath = v
      #v
    end

    def set_parent_from_basedirpath
      v = self.basedirpath

      # set parent_id from dir
      d = v.chop
      r = Template.where(is_folder: true, basepath: d).first
      if r
        self.parent_id = r.id
      else
        self.parent_id = nil
      end
    end

    #### callbacks

    def _before_validation
      fix_basedirpath

      # parent, basedirpath
      if self.parent_id.nil? && !self.basedirpath.blank?
        set_parent_from_basedirpath
      elsif self.basedirpath.nil? && !self.parent_id.nil?
        set_basedirpath_from_parent
      end

      set_basepath
    end

    def _before_create
      if self.is_folder
        # create dir on disk
        Fileutils::Fileutils.create_dir_if_not_exists self.folder_fullpath
      else
        # add folders if needed
        if self.parent_id.nil? && !self.basedirpath.blank?
          self.parent = Template.create_folders_tree(self.basedirpath)
        end

      end

    end

    def _before_update
      if self.is_folder
        oldpath = self.folder_fullpath

        self.set_basepath

        # rename dir on disk
        if self.basename_changed?
          raise "cannot change folder path"

          require 'fileutils'
          newpath = self.folder_fullpath

          if Dir.exists?(newpath)
            errors.add(:basename, 'Folder already exists')
            return false
          end

          FileUtils.mv oldpath, newpath

          # TODO: change paths for child templates

        end

      else
        # file

        # TODO: rename file
        #self.make_basepath

        # remove translations if needed
        if !self.is_translated
          self.translations = self.translations.reject{|r| r.lang!=''}
          #self.translations.clear

        end
      end

    end

    def _before_destroy
      if self.is_folder

        # cannot delete not empty dir
        if !self.folder_empty?
          return false
        end

        # delete dir
        folder_delete

      else
        # file

      end

      true
    end

    # create folders if necessary - NOT WORKING
    def self.create_folders_tree(dirpath)
      a = dirpath.split /\//

      d = ''
      parent_current = nil
      prev_d = d
      a.each do |s|
        d = d + (d=='' ? '' : '/') +s
        r = Template.where(is_folder: true, basepath: d).first
        if r
          parent_current = r
          next
        end
        # create missing folder
        path_new = File.basename(d)
        basedirpath_new = prev_d
        r = Template.create(is_folder: true, basename: path_new, basedirpath: basedirpath_new, title: path_new, parent: parent_current)
        parent_current = r

        prev_d = d
      end

      parent_current

    end

    #### folders

    def folder_delete
      dirpath = self.folder_fullpath
      FileUtils.remove_dir(dirpath) if Dir.exists? dirpath
    end

    def folder_empty?
      dirpath = self.folder_fullpath
      if !Dir.exists? dirpath
        return true
      end

      return Dir.entries(dirpath).size == 2
    end

  end
end


module RSqoot
  module Commission

    # Retrieve information of commissions based on the following parameters
    #
    # @param [String] :to Start date
    # @param [String] :from End date
    #
    # @return [RSqoot::SqootCommission]
    def commissions(options = {})
      options = update_by_expire_time options
      if commissions_not_latest?(options)
        @rsqoot_commissions = get('commissions', options, SqootCommission)
        @rsqoot_commissions = @rsqoot_commissions.commissions if @rsqoot_commissions
      end
      logger(uri: sqoot_query_uri, records: @rsqoot_commissions, type: 'commissions', opts: options)
      @rsqoot_commissions
    end
  end
end


module Optimacms
  class Admin::BackupMetadataController < Admin::AdminBaseController

    def lib_service
      Optimacms::BackupMetadata::Backup
    end

    def index
      @list_backups = lib_service.list_backups
    end

    def backup
      @res = lib_service.perform_backup

      respond_to do |format|
        format.html {      }
        format.json{        render :json=>@res      }
      end
    end

    def upload
      # input
      uploaded_file = params[:import][:file]

      #
      @res = BackupMetadata::Backup.upload_backup uploaded_file

      redirect_to backup_metadata_path
    end

    def view
      # input
      @filename = params[:f]
      @dirname = params[:dirname]

      #
      @backup_filename = BackupMetadata::Backup.make_backup_path @filename

    end

    def download
      f = params[:f]

      path = File.join(BackupMetadata::Backup.dir_backups, f)

      #data = File.open(path, 'rb') { |f| f.read }
      data = IO.read(path)
      send_data data, filename: f
      #send_file path
    end

    def delete
      f =  CGI::unescape(params[:f])
      @res = BackupMetadata::Backup.delete_backup(f)

      #
      respond_to do |format|
        format.html {      }
        format.js{ }
        format.json{        render :json=>@res      }
      end
    end

    ### import templates

    def reviewimport_templates
      # input
      @dirname = params[:dirname]

      # work
      @backup_basedir = Optimacms::BackupMetadata::Backup.make_backup_dir_path @dirname
      @backup_templates_dirpath = File.join(@backup_basedir, "templates")
      @analysis = Optimacms::BackupMetadata::TemplateImport.analyze_data_dir(@backup_templates_dirpath)

    end

    def import_template
      # input
      @backup_dir = params[:backup_dir]
      @filename = params[:filename]
      @cmd = params[:cmd]

      # work
      @res = Optimacms::BackupMetadata::TemplateImport.import_template(@backup_dir, @filename, @cmd)

      respond_to do |format|
        format.html {      }
        format.json{        render :json=>@res      }
      end
    end

    ### import pages

    def reviewimport_pages
      # input
      @dirname = params[:dirname]

      # work
      @backup_basedir = Optimacms::BackupMetadata::Backup.make_backup_dir_path @dirname
      @backup_templates_dirpath = File.join(@backup_basedir, "pages")

      @analysis = Optimacms::BackupMetadata::PageImport.analyze_data_dir(@backup_templates_dirpath)

    end

    def import_page
      # input
      @backup_dir = params[:backup_dir]
      @filename = params[:filename]
      @cmd = params[:cmd]

      # work
      @res = Optimacms::BackupMetadata::PageImport.import(@backup_dir, @filename, @cmd)

      respond_to do |format|
        format.html {      }
        format.json{        render :json=>@res      }
      end
    end

  end
end


require 'json'

module FootballRuby
  class Client < Base

    # List all available leagues.
    def leagues(opts={})
      season = opts.fetch(:season) { Time.now.year }

      json_response get("competitions/?season=#{season}")
    end

    # List all teams for a certain league.
    def league_teams(id)
      raise IdMissingError, 'missing id' if id.nil?

      json_response get("competitions/#{id}/teams")
    end

    # Show League Table / current standing.
    # Filters:
    #
    # match_day=/\d+/

    def league_table(id, opts={})
      raise IdMissingError, 'missing id' if id.nil?

      match_day = opts[:match_day]

      uri = "competitions/#{id}/leagueTable/"
      url = match_day.nil? ? uri : "#{uri}?matchday=#{match_day}"

      json_response get(url)
    end

    # List all fixtures for a certain league.
    # Filters:
    #
    # time_frame=/p|n[1-9]{1,2}/
    # match_day=/\d+/

    def league_fixtures(id, opts={})
      raise IdMissingError, 'missing id' if id.nil?

      time_frame  = opts[:time_frame]
      match_day   = opts[:match_day]

      uri = "competitions/#{id}/fixtures/"
      url = time_frame.nil? ? uri : "#{uri}?timeFrame=#{time_frame}"
      url = match_day.nil? ? url : "#{url}?matchday=#{match_day}"

      json_response get(url)
    end

    # List fixtures across a set of leagues.
    # Filters:
    #
    # time_frame=/p|n[1-9]{1,2}/
    # league=leagueCode

    def fixtures(opts={})
      time_frame = opts[:time_frame]
      league = opts[:league]

      uri = "fixtures/"
      url = time_frame.nil? ? uri : "#{uri}?timeFrame=#{time_frame}"
      url = league.nil? ? url : "#{url}?league=#{league}"

      json_response get(url)
    end

    # Show one fixture.
    # Filters:
    #
    # head2head=/\d+/

    def fixture(id, opts={})
      raise IdMissingError, 'missing id' if id.nil?

      head2head = opts[:head2head]

      uri = "fixtures/#{id}/"
      url = head2head.nil? ? uri : "#{uri}?head2head=#{head2head}"

      json_response get(url)
    end

    # Show all fixtures for a certain team.
    # Filters:
    #
    # season=/\d\d\d\d/
    # time_frame=/p|n[1-9]{1,2}/
    # venue=/home|away/

    def team_fixtures(id, opts={})
      raise IdMissingError, 'missing id' if id.nil?

      season      = opts[:season]
      time_frame  = opts[:time_frame]
      venue       = opts[:venue]

      uri = "teams/#{id}/fixtures/"
      url = season.nil? ? uri : "#{uri}?season=#{season}"
      url = time_frame.nil? ? url : "#{url}?timeFrame=#{time_frame}"
      url = venue.nil? ? url : "#{url}?venue=#{venue}"

      json_response get(url)
    end

    # Show one team.
    def team(id)
      raise IdMissingError, 'missing id' if id.nil?

      json_response get("teams/#{id}/")
    end

    # Show all players for a certain team.
    def team_players(id)
      raise IdMissingError, 'missing team id' if id.nil?

      json_response get("teams/#{id}/players/")
    end

    # Show live scores
    def live_scores
      json_response get_live_scores
    end

    private

    def json_response(request)
      JSON.parse(request.body, symbolize_names: true)
    end
  end
end


module Ov
  module Ext
    #
    # Add `match` method, which work like `case` statement but for types
    #
    # == Usage
    #
    #    include Ov::Ext
    #
    #    match("String", "dsa") do
    #      try(String, Array) {|str, arr| "#{str} #{arr}" }
    #      try(String) {|str| "#{str}"  }
    #      otherwise { "none" }
    #    end
    #
    #
    def match(*args, &block)
      z = Module.new do
        include Ov
        extend self
        def try(*args, &block)
          let :anon_method, *args, &block
        end
        def otherwise(&block)
          let :otherwise, &block
        end
        instance_eval &block
      end
      begin
        z.anon_method(*args)
      rescue Ov::NotImplementError => e
        z.otherwise
      end
    end
  end
end


require_dependency "ckpages/application_controller"

module Ckpages
  class PagesController < ApplicationController
    before_action :set_page, only: [:show, :edit, :update, :destroy]

    # GET /pages
    def index
      @pages = Page.order(id: :desc).page(params[:page])
    end

    # GET /pages/1
    def show
    end

    # GET /pages/new
    def new
      @page = Page.new(path: '/')

      if params[:path].present?
        @page.path = CGI::unescape(params[:path])
      end
    end

    # GET /pages/1/edit
    def edit
    end

    # POST /pages
    def create
      @page = Page.new(page_params)

      if @page.save
        redirect_to @page, notice: 'Page was successfully created.'
      else
        render :new
      end
    end

    # PATCH/PUT /pages/1
    def update
      if @page.update(page_params)
        redirect_to @page, notice: 'Page was successfully updated.'
      else
        render :edit
      end
    end

    # DELETE /pages/1
    def destroy
      @page.destroy
      redirect_to pages_url, notice: 'Page was successfully destroyed.'
    end

    private
      # Use callbacks to share common setup or constraints between actions.
      def set_page
        @page = Page.find(params[:id])
      end

      # Only allow a trusted parameter "white list" through.
      def page_params
        params.require(:page).permit(:path, :content, :keywords, :description, :title, :robots, :redirect_url, :title1, :url1, :title2, :url2, :title3, :url3, :title4, :url4, :title5, :url5)
      end
  end
end


# encoding: utf-8

require 'tabledata/exceptions'

module Tabledata

  # Represents a row in a table and provides an easy way to enumerate and access
  # values in a row.
  #
  # If your table defines accessors, you can access columns by using methods of that name.
  #
  # @example
  #     table = Tabledata.table body: [[1,2,3], [4,5,6]], accessors: %i[foo bar baz]
  #     table[0].foo     # => 1
  #     table[1].baz     # => 6
  #     table[1].bar = 9
  #
  # @note
  #   The row data is referenced. If you mutate the table, adding a row to it,
  #   this row instance's data will not change. Its index will be off.
  class Row

    # @return [Tabledata::Table] The table this column belongs to.
    attr_reader :table

    # @return [Integer] The row index in the table. Zero based, including header and footer.
    attr_reader :index

    # @return [Array] The row's data. It's the internal structure, don't modify it directly.
    attr_reader :data

    include Enumerable

    # @param [Tabledata::Table] table
    #   The table this column belongs to.
    # @param [Integer] index
    #   The index of the column in the table.
    # @param [Array] data
    #   The data of the row. If set to nil, it is fetched from the table.
    def initialize(table, index, data=nil)
      @table  = table
      @index  = index
      @data   = data || @table.data[index]
    end

    # Iterate over each cell in this row
    def each(&block)
      @data.each(&block)
    end

    # Tries to return the value of the column identified by index, corresponding accessor or header.
    # It throws an IndexError exception if the referenced index lies outside of the array bounds.
    # This error can be prevented by supplying a second argument, which will act as a default value.
    #
    # Alternatively, if a block is given it will only be executed when an invalid
    # index is referenced.  Negative values of index count from the end of the
    # array.
    def fetch(column, *default_value, &default_block)
      raise ArgumentError, "Must only provide at max one default value or one default block" if default_value.size > (block_given? ? 0 : 1)

      index = case column
        when Symbol then @table.index_for_accessor(column)
        when String then @table.index_for_header(column)
        when Integer then column
        else raise InvalidColumnSpecifier, "Invalid index type, expected Symbol, String or Integer, but got #{column.class}"
      end

      @data.fetch(index, *default_value, &default_block)
    end

    # Convenience access of values in the row.
    # Can either be used like Array#[], i.e. it accepts an offset,
    # an offset + length, or an offset-to-offset range.
    # Alternatively you can use a Symbol, if it's a valid accessor in this table.
    # And the last variant is using a String, which will access the value of
    # the corresponding header.
    #
    # @return [Array, Object] Either the value of a given cell, or an array of values.
    #
    # @see #slice for a faster way to use ranges or offset+length
    # @see #at_accessor for a faster way to access by name
    # @see #at_index for a faster way to access by index
    # @see #at_header for a faster way to access by header value
    def [](a,b=nil)
      if b || a.is_a?(Range) then
        slice(a,b)
      else
        at(a)
      end
    end

    # Array-like access to row-data.
    #
    # @example
    #     table = Tabledata.table body: [[:a,:b,:c]], accessors: %i[foo bar baz]
    #     row   = table.row(0)
    #     row.slice(1)      # => :b
    #     row.slice(0, 2)   # => [:a, :b]
    #     row.slice(-2, 2)  # => [:b, :c]
    #     row.slice(1..2)   # => [:b, :c]
    #     row.slice(0..-2)  # => [:a, :b]
    #     row.slice(-2..-1) # => [:b, :c]
    #     row.slice(:foo)   # !> TypeError
    #     row.slice("foo")  # !> TypeError
    #
    # @see #[] Generic cell access.
    def slice(*args)
      @data[*args]
    end

    # Access a single cell by either index, index-range, accessor or header-name.
    #
    # @example
    #     table = Tabledata.table header: %w[x y z], body: [[:a,:b,:c]], accessors: %i[foo bar baz]
    #     row   = table.row(1)
    #     row.at(0)    # => :a
    #     row.at(:foo) # => :a
    #     row.at("x")  # => :a
    def at(column)
      case column
        when Symbol  then at_accessor(column)
        when String  then at_header(column)
        when Integer then at_index(column)
        when Range   then @data[column]
        else raise InvalidColumnSpecifier, "Invalid index type, expected Symbol, String or Integer, but got #{column.class}"
      end
    end

    # Access a single cell by its corresponding header-name.
    # This method is faster than the generic methods Tabledata::Row#[] and #at.
    #
    # @example
    #     table = Tabledata.table header: %w[x y z], body: [[:a,:b,:c]], accessors: %i[foo bar baz]
    #     row   = table.row(1)
    #     row.at_header("x")  # => :a
    def at_header(name)
      index = @table.index_for_header(name)
      raise InvalidColumnName, "No column named #{name}" unless index

      @data[index]
    end

    # Access a single cell by its corresponding accessor.
    # This method is faster than the generic methods Tabledata::Row#[] and #at.
    #
    # @example
    #     table = Tabledata.table header: %w[x y z], body: [[:a,:b,:c]], accessors: %i[foo bar baz]
    #     row   = table.row(1)
    #     row.at_accessor(:foo) # => :a
    def at_accessor(name)
      index = @table.index_for_accessor(name)
      raise InvalidColumnAccessor, "No column named #{name}" unless index

      @data[index]
    end

    # Access a single cell by its index.
    # This method is faster than the generic methods Tabledata::Row#[] and #at.
    #
    # @example
    #     table = Tabledata.table header: %w[x y z], body: [[:a,:b,:c]], accessors: %i[foo bar baz]
    #     row   = table.row(1)
    #     row.at_index(0)    # => :a
    def at_index(index)
      @data.at(index)
    end

    # Access multiple values by either index, index-range, accessor or header-name.
    # @example
    #     table = Tabledata.table header: %w[x y z], body: [[:a,:b,:c]], accessors: %i[foo bar baz]
    #     row   = table.row(1)
    #     row.values_at(2,1,0)    # => [:c, :b, :a]
    #     row.values_at(:foo,'z') # => [:a, :c]
    #     row.values_at(0..1, 2..-1) # => [:a, :b, :c]
    def values_at(*columns)
      result = []
      columns.each do |column|
        data = at(column)
        if column.is_a?(Range)
          result.concat(data) if data
        else
          result << data
        end
      end

      result
    end

    # @return [Integer] The number of cells in this row.
    def size
      @data.size
    end
    alias length size

    # @return [Hash]
    #   A hash with the accessors as key and the cell values as values.
    def to_h
      Hash[@table.accessor_columns.map { |accessor, index| [accessor, @data[index]] }]
    end

    # @return [Array]
    #   The row values as array
    def to_a
      @data.dup
    end
    alias to_ary to_a

    # @private
    # See Object#respond_to_missing?
    def respond_to_missing?(name, include_private)
      if name =~ /=$/
        @table.index_for_accessor(name[0..-2].to_sym) ? true : false
      else
        @table.index_for_accessor(name) ? true : false
      end
    end

    # Allow reading and writing cell values by their accessor name.
    def method_missing(name, *args, &block)
      return super unless @table.accessors?

      name              =~ /^(\w+)(=)?$/
      name_mod, assign  = $1, $2
      index             = @table.index_for_accessor(name_mod)
      arg_count         = assign ? 1 : 0

      return super unless index

      raise ArgumentError, "Wrong number of arguments (#{args.size} for #{arg_count})" if args.size > arg_count

      if assign then
        @data[index] = args.first
      else
        @data[index]
      end
    end

    # @private
    # See Object#inspect
    def inspect
      sprintf "%s%p", self.class, to_a
    end
  end
end


module TaskMapper::Provider
  # This is the Unfuddle Provider for taskmapper
  module Unfuddle
    include TaskMapper::Provider::Base
    TICKET_API = UnfuddleAPI::Ticket # The class to access the api's tickets
    PROJECT_API = UnfuddleAPI::Project # The class to access the api's projects

    # This is for cases when you want to instantiate using TaskMapper::Provider::Unfuddle.new(auth)
    def self.new(auth = {})
      TaskMapper.new(:unfuddle, auth)
    end

    # Providers must define an authorize method. This is used to initialize and set authentication
    # parameters to access the API
    def authorize(auth = {})
      @authentication ||= TaskMapper::Authenticator.new(auth)
      auth = @authentication
      if (auth.account.nil? and auth.subdomain.nil?) or auth.username.nil? or auth.password.nil?
        raise "Please provide at least an account (subdomain), username and password)"
      end
      UnfuddleAPI.protocol = auth.protocol if auth.protocol?
      UnfuddleAPI.account = auth.account || auth.subdomain
      UnfuddleAPI.authenticate(auth.username, auth.password)
    end

    # declare needed overloaded methods here

    def valid?
      begin
        PROJECT_API.find(:first)
        true
      rescue
        false
      end
    end
  end
end


module ApiAuth

  module Helpers # :nodoc:

    def b64_encode(string)
      if Base64.respond_to?(:strict_encode64)
        Base64.strict_encode64(string)
      else
        # Fall back to stripping out newlines on Ruby 1.8.
        Base64.encode64(string).gsub(/\n/, '')
      end
    end

    def md5_base64digest(string)
      if Digest::MD5.respond_to?(:base64digest)
        Digest::MD5.base64digest(string)
      else
        b64_encode(Digest::MD5.digest(string))
      end
    end

    # Capitalizes the keys of a hash
    def capitalize_keys(hsh)
      capitalized_hash = {}
      hsh.each_pair {|k,v| capitalized_hash[k.to_s.upcase] = v }
      capitalized_hash
    end

    def time_as_httpdate
      Helpers.time_as_httpdate
    end

    def self.time_as_httpdate
      Time.now.utc.strftime("%a, %d %b %Y %T GMT")
    end

  end

end


# @markup markdown
# @title Reliquary::Client
# @author Steve Huff
#

require 'multi_json'
require 'rest-client'
require 'uri'

module Reliquary
  class Client

    HTTP_METHODS = ['get','put','post','patch','delete','head']

    # @!attribute [r] api_key
    #   @return [String] a [New Relic REST API](https://rpm.newrelic.com/api/explore) key
    attr_reader :api_key

    # @!attribute [r] api_base
    #   @return [URI] the base URI on which additional REST calls will be built
    attr_reader :api_base

    # @!method initialize(api_key = get_api_key_from_env)
    #   Constructor method
    #   @param api_key [String] (see api_key)
    #   @return [Reliquary::Client] the initialized client
    #
    def initialize(api_key = nil)
      begin
        # get API key from env if not provided
        api_key = get_api_key_from_env if api_key.nil?

        @api_key = validate_api_key(api_key)
        @api_base = build_api_base('https://api.newrelic.com/v2/')

      rescue NoMethodError => e
        false

      rescue StandardError => e
        raise e
      end
    end

    # @!method parse(json)
    #   Parse returned JSON into a Ruby object
    #
    #   @param [String] json JSON-formatted string
    #   @return [Object] Ruby object representing JSON-formatted string
    def parse(json)
      begin
        # strip off some layers of nonsense added by Oj
        MultiJson.load(json, :symbolize_keys => true).values[0]

      rescue StandardError => e
        raise e
      end
    end

    # @!method method_missing(method_name, *args, &block)
    #   Delegate HTTP method calls to RestClient::Resource
    #
    #   @param method_name [Symbol] name of method (must be a member of
    #     {Reliquary::Client::HTTP_METHODS})
    #   @param args [Array] additional method params
    #   @param block [Proc] block to which method will yield
    def method_missing(method_name, *args, &block)
      begin
        self.api_base.send(method_name.to_sym, *args, &block)

      rescue StandardError => e
        raise e
      end
    end

    def respond_to_missing?(method_name, include_private = false)
      HTTP_METHODS.include?(method_name.to_s) || super
    end

    private

    def build_api_base(uri)
      begin
        validated_uri = URI(uri)

        RestClient::Resource.new(validated_uri.to_s, :headers => auth_header)

      rescue URI::InvalidURIError => e
        raise "'#{uri}' does not look like a valid URI"

      rescue StandardError => e
        raise e
      end
    end

    def validate_api_key(api_key)
      begin
        if /^[\h]{47}$/ =~ api_key
          api_key
        else
          raise "'#{api_key}' does not look like a valid New Relic REST API key"
        end

      rescue StandardError => e
        raise e
      end
    end

    def auth_header(api_key = self.api_key)
      begin
        {:x_api_key => api_key}

      rescue StandardError => e
        raise e
      end
    end

    def get_api_key_from_env(env = ENV)
      begin
        env.fetch('NEW_RELIC_API_KEY', env.fetch('NEWRELIC_API_KEY', nil))

      rescue NoMethodError => e
        raise "that doesn't look like a valid environment: #{e.message}"

      rescue StandardError => e
        raise e
      end
    end

  end
end


# encoding: utf-8
# vim: ft=ruby expandtab shiftwidth=2 tabstop=2

require "thor"

module Pushbullet_CLI

  class Push < Thor
    class_option :token, :desc => "Access token"

    desc "push create <MESSAGE>", "Send a push to devices or another persons."
    method_option :title, :desc => "Title of the notification."
    method_option :device, :desc => "Iden of the target device to push."
    method_option :url, :desc => "The url to open."
    # method_option :person, :aliases => "-p", :desc => "Delete the file after parsing it"
    def create( message = "" )
      if "help" == message
        invoke( :help, [ "create" ] );
        exit 0
      end

      if File.pipe?( STDIN ) || File.select( [STDIN], [], [], 0 ) != nil then
        message = STDIN.readlines().join( "" )
      end

      url = "https://api.pushbullet.com/v2/pushes"
      token = Utils::get_token( options )

      unless message.empty?
        args = Utils::get_push_args( options )
        args['body'] = message
        Utils::send( url, token, "post", args )
      else
        puts "Nothing to do."
      end
    end # end create

    desc "push list", "Request push history."
    method_option :format, :desc => "Accepted values: table, json. Default: table"
    method_option :fields, :desc => "Limit the output to specific object fields."
    def list( help = "" )
      unless help.empty?
        if "help" == help
          invoke( :help, [ "list" ] );
          exit 0
        else
          self.class.handle_argument_error
          exit 1
        end
      end

      url = "https://api.pushbullet.com/v2/pushes?active=true"
      token = Utils::get_token( options )
      cols = [ 'iden', 'type', 'title', 'created' ]

      unless options[:fields].nil?
        unless options[:fields].empty?
          cols = options[:fields].split( /\s*,\s*/ )
        end
      end

      result = Utils::send( url, token, "get" )
      Utils::print( {
        :format => options[:format],
        :cols => cols,
        :rows => result['pushes'],
      } )
    end # end list

  end
end


module Risky::SecondaryIndexes

  def self.included(base)
    base.extend ClassMethods
  end

  module ClassMethods
    # Add a new secondary index to this model.
    # Default option is :type => :int, can also be :bin
    # Default option is :multi => false, can also be true
    # Option :map can be used to map the index to a model (see map_model).
    #   This assumes by default that the index name ends in _id (use :map => true)
    #   If it ends in something else, use :map => '_suffix'
    def index2i(name, opts = {})
      name = name.to_s

      opts.replace({:type => :int, :multi => false, :finder => :find}.merge(opts))
      indexes2i[name] = opts

      class_eval %Q{
        def #{name}
          @indexes2i['#{name}']
        end

        def #{name}=(value)
          @indexes2i['#{name}'] = value
        end
      }

      if opts[:map]
        if opts[:map] === true # assume that it ends in _id
          model_name = name[0..-4]
          map_model(model_name, opts)
        else
          model_name = name[0..-(opts[:map].length + 1)]
          map_model(model_name, opts.merge(:suffix => opts[:map]))
        end
      end
    end

    # A list of all secondary indexes
    def indexes2i
      @indexes2i ||= {}
    end

    def find_by_index(index2i, value)
      index = "#{index2i}_#{indexes2i[index2i.to_s][:type]}"
      key = bucket.get_index(index, value).first
      return nil if key.nil?

      find(key)
    end

    def find_all_by_index(index2i, value)
      index = "#{index2i}_#{indexes2i[index2i.to_s][:type]}"
      keys = bucket.get_index(index, value)

      find_all_by_key(keys)
    end

    def find_all_keys_by_index(index2i, value)
      index = "#{index2i}_#{indexes2i[index2i.to_s][:type]}"
      bucket.get_index(index, value)
    end

    def paginate_by_index(index2i, value, opts = {})
      keys = paginate_keys_by_index(index2i, value, opts)
      Risky::PaginatedCollection.new(find_all_by_key(keys), keys)
    end

    def paginate_keys_by_index(index2i, value, opts = {})
      opts.reject! { |k, v| v.nil? }

      index = "#{index2i}_#{indexes2i[index2i.to_s][:type]}"
      bucket.get_index(index, value, opts)
    end

    def create(key, values = {}, indexes2i = {}, opts = {})
      obj = new key, values, indexes2i
      obj.save(opts)
    end

    # The map_model method is a convenience method to map the model_id to getters and setters.
    # The assumption is that you have a value or index2i for model_id.
    # The default suffix is '_id', so map_model :promotion implies that promotion_id is the index2i.
    #
    # For example, map_model :promotion will create these three methods
    # ```ruby
    # def promotion
    #   @promotion ||= Promotion.find_by_id promotion_id
    # end
    #
    # def promotion=(value)
    #   @promotion = promotion
    #   self.promotion_id = value.nil? ? nil : value.id
    # end
    #
    # def promotion_id=(value)
    #   @promotion = nil if self.promotion_id != value
    #   indexes2i['promotion_id'] = value
    # end
    # ```
    def map_model(model_name, opts = {})
      model_name = model_name.to_s
      class_name = Risky::Inflector.classify(model_name)

      opts.replace({:type => :index2i, :suffix => '_id'}.merge(opts))

      class_eval %Q{
        def #{model_name}
          @#{model_name} ||= #{class_name}.#{opts[:finder]} #{model_name}#{opts[:suffix]}
        end

        def #{model_name}=(value)
          @#{model_name} = value
          self.#{model_name}#{opts[:suffix]} = value.nil? ? nil : value.id
        end

        def #{model_name}_id=(value)
          @#{model_name} = nil if self.#{model_name}_id != value
          indexes2i['#{model_name}#{opts[:suffix]}'] = value
        end
      }
    end
  end

  ### Instance methods
  def initialize(key = nil, values = {}, indexes2i = {})
    super((key.nil? ? nil : key.to_s), values)

    # Parse anything not parsed correctly by Yajl (no support for json_create)
    self.class.values.each do |k,v|
      if self[k].is_a?(Hash) && self[k]['json_class']
        klass = Risky::Inflector.constantize(self[k]['json_class'])
        self[k] = klass.send(:json_create, self[k])
      end
    end

    @indexes2i = {}

    indexes2i.each do |k,v|
      send(k.to_s + '=', v)
    end
  end

  def save(opts = {})
    self.class.indexes2i.each do |k, v|
      raise ArgumentError, "Nil for index #{k} on #{self.class.name}" if (v[:multi] ? @indexes2i[k].nil? : @indexes2i[k].blank?) && !v[:allow_nil]

      case v[:type]
      when :int
        @riak_object.indexes["#{k}_int"] = v[:multi] && @indexes2i[k].respond_to?(:map) ? @indexes2i[k].map(&:to_i) : [ @indexes2i[k].to_i ]
      when :bin
        @riak_object.indexes["#{k}_bin"] = v[:multi] && @indexes2i[k].respond_to?(:map) ? @indexes2i[k].map(&:to_s) : [ @indexes2i[k].to_s ]
      else
        raise TypeError, "Invalid 2i type '#{v[:type]}' for index #{k} on #{self.class.name}"
      end
    end

    super(opts)
  end

  def load_riak_object(riak_object, opts = {:merge => true})
    super(riak_object, opts)

    # Parse anything not parsed correctly by Yajl (no support for json_create)
    self.class.values.each do |k,v|
      if self[k].is_a?(Hash) && self[k]['json_class']
        klass = Risky::Inflector.constantize(self[k]['json_class'])
        self[k] = klass.send(:json_create, self[k])
      end
    end

    self.class.indexes2i.each do |k, v|
      case v[:type]
      when :int
        @indexes2i[k] = v[:multi] ? @riak_object.indexes["#{k}_int"].map(&:to_i) : @riak_object.indexes["#{k}_int"].first.to_i
      when :bin
        @indexes2i[k] = v[:multi] ? @riak_object.indexes["#{k}_bin"].map(&:to_s) : @riak_object.indexes["#{k}_bin"].first.to_s
      else
        raise TypeError, "Invalid 2i type '#{v[:type]}' for index #{k} on #{self.class.name}"
      end
    end

    self
  end

  def indexes2i
    @indexes2i
  end

  def inspect
    "#<#{self.class} #{key} #{@indexes2i.inspect} #{@values.inspect}>"
  end
end


module Ropenstack::Networking::Version2::Extensions
  module L3
    ##
    # Get a list of a tenants routers
    #
    # :call-seq:
    #   routers(id) => A single router with the id matching the parameter
    #   routers => All routers visible to the tenant making the request
    ##
    def routers(id = nil)
      endpoint = "routers"
      unless id.nil?
        endpoint = endpoint + "/" + id
      end
      return get_request(address(endpoint), @token)
    end
    ##
    # Create a new router with a given name.
    ##
    def create_router(name, admin_state_up = true)
      data = {
        'router' =>{
          'name' => name,
          'admin_state_up' => admin_state_up,
        }
      }
      return post_request(address("routers"), data, @token)
    end

    ##
    # Delete a router given a routers id.
    ##
    def delete_router(router)
      return delete_request(address("routers/" + router), @token)
    end

    ##
    # Connect a router to a subnet, given router id and subnet id.
    ##
    def add_router_interface(router, subnet)
      data = { 'subnet_id' => subnet }
      return put_request(address("routers/"+router+"/add_router_interface"), data, @token)
    end

    ##
    # Delete a connection between a subnet and router given either port
    # or subnet ids.
    #
    # :call-seq:
    #   delete_router_interface(router_id, subnet_id, "subnet")
    #   delete_router_interface(router_id, port_id, "port")
    ##
    def delete_router_interface(router, id, type)
      data = case type
        when 'port' then { 'port_id' => id }
        when 'subnet' then { 'subnet_id' => id }
        else raise "Invalid Interface Type"
        end
      return put_request(address("routers/" + router + "/remove_router_interface"), data, @token)
    end

    ##
    # Enable external connectivity through this router by connecting it to
    # an "external network"
    ##
    def add_router_gateway(router, network_id)
      data = { 'router' => {'external_gateway_info' => { 'network_id' => network_id }}}
      return put_request(address("routers/"+router), data, @token)
    end

    ##
    # Clear a routers external gateway information given a router id.
    ##
    def delete_router_gateway(router)
      data = { 'router' => {'external_gateway_info' => nil}}
      return put_request(address('routers/' + router), data, @token)
    end

    ##
    # Get a full list of floating ips for the tenant
    ##
    def floating_ips
      return get_request(address("floatingips"), @token)
    end

    def create_floating_ip(network, port = nil)
      data = {
        'floatingip' => {
          'floating_network_id' => network
        }
      }
      unless port.nil?
        data['floatingip']['port_id'] = port
      end
      return post_request(address('floatingips'), data, @token)
    end

    def delete_floating_ip(id)
      return delete_request(address("floatingips/#{id}"), @token)
    end

    def update_floating_ip(id, port)
      data = {
        'floatingip' => {
          'port_id' => port
        }
      }
      return put_request(address("floatingips/#{id}"), data, @token)
    end
  end
end


module Ov
  class OA < Array
    attr_accessor :complete, :result
    #find in self
    #find in ancestors
    #find types
    #find any types
    def where(method)
      @complete, @result = nil, nil
      z = find_or_next(method) { |method|
        self.find{|m| m.eql?(method) }
      }.find_or_next(method) { |method|
        self.find{|m| m.eql0?(method) }
      }.find_or_next(method) { |method|
        self.find{|m| m.like?(method) }
      }.find_or_next(method) {|method|
        self.find{|m| m.like0?(method) }
      }.get
    end

    def find_or_next(method, &block)
      return self if @complete
      ev_block = yield(method)
      @complete, @result = true, ev_block if ev_block
      self
    end

    alias :get :result
  end
end


require 'yaml'

module Semistatic
  class Configuration
    class Error < StandardError; end

    def initialize
      @templates_path = Rails.root. + 'app/views/layout'
      @config_files = [(Rails.root. + 'config/semistatic.yml')]
      @config = HashWithIndifferentAccess.new({pages: {}})
    end

    # set the template path
    # @param Pathname path
    def templates_path=(path)
      @templates_path = path
    end

    # get the template path
    # @return Pathname
    def templates_path
      @templates_path
    end

    # set the config files
    # @param Array[Pathname] files # the filepaths in a array
    def config_files=(files)
      @config_files = files
    end

    # get the config files
    # @return Array # the filepaths in a array
    def config_files
      @config_files
    end

    # load config from files
    def load
      config_files.each do |file|
        config = YAML::load(File.open(file))
        @config.merge! config
      end
    end

    # @return Hash
    def pages
      @config[:pages]
    end

    # @param Symbol key
    # @return hash
    def page(key)
      page = pages[key]
      raise Error.new("There is no page named '#{key}'") unless page
      page
    end

  end
end


module RSqoot
  module Provider
    # Retrieve a list of providers base on the following parameters
    #
    # @return [RSqoot::SqootProvider]
    def providers(options = {})
      options = update_by_expire_time options
      query = options.delete(:query)
      if providers_not_latest?(options)
        @rsqoot_providers = get('providers', options, SqootProvider)
        @rsqoot_providers = @rsqoot_providers.providers.map(&:provider) if @rsqoot_providers
      end
      result = query.present? ? query_providers(query) : @rsqoot_providers
      logger(uri: sqoot_query_uri, records: result, type: 'providers', opts: options)
      result
    end
  end
end


module RSqoot
  module Category

    # Retrieve a list of categories base on the following parameters
    #
    # @return [RSqoot::SqootCategory] category list
    def categories(options = {})
      options = update_by_expire_time options
      query = options.delete(:query)
      if categories_not_latest?(options)
        @rsqoot_categories = get('categories', options, SqootCategory)
        @rsqoot_categories = @rsqoot_categories.categories.map(&:category) if @rsqoot_categories
      end
      result = query.present? ? query_categories(query) : @rsqoot_categories
      logger(uri: sqoot_query_uri, records: result, type: 'categories', opts: options)
      result
    end
  end
end


module Challah::Rolls
  # AuthableRole is used to extend functionality to a model in your app named Role. By default,
  # this model already exists within the challah engine.
  #
  # The Role model is used to group together sets of permissions that can be assigned
  # to users.
  #
  # Roles are not used to detect features or options for a user. Instead, you should
  # always use permissions as the most granular level of detail within your app.
  #
  # For example, to restrict a piece of your application to a certain user, you should create
  # a new permission level that restricts it. Then, you can assign that permission to roles
  # and users on an ad hoc basis.
  #
  # In most cases roles should not be accessed directly, and only be used as a means to
  # quickly assign a user to several permissions. In other words, checking to see what role
  # a user is assigned to in your app is probably not a great idea. Use permission checks instead.
  #
  # The administrator role, which is included in the seeds file by default, is automatically
  # able to access all permissions. All subsequently added permissions will also be added
  # to the administrator role.
  #
  # == Validations
  #
  # A role requires that a unique name be provided.
  #
  # == Associations
  #
  # The following associations are set on this model by default:
  #
  # * Has many *users*
  # * Has many *permissions*
  #
  # The join table (permission_roles) is also included, but likely does not need to be
  # accessed directly.
  #
  # == Customizing the Role model
  #
  # By default, the Role model is included within the gem engine. However, if you wish to
  # include it within your app for any customizations, you can do so by creating a model
  # file named +role.rb+ and adding the +authable_role+ line near the top of the class.
  #
  # @example app/models/role.rb
  #   class Role < ActiveRecord::Base
  #     # Set up all role methods from challah gem
  #     authable_role
  #
  #     # Your customizations here..
  #   end
  module Role
    # This method sets up the +Role+ class with all baked in methods.
    #
    # A role requires the presence of the +name+ and +default_path+ attributes.
    #
    # Once this method has been called, the {InstanceMethods} and {ClassMethods} modules
    # will be accessibile within the Role model.
    def challah_role
      unless included_modules.include?(InstanceMethods)
        include InstanceMethods
        extend ClassMethods
      end

      class_eval do
        # Validations
        ################################################################

        validates :name, :presence => true, :uniqueness => true

        # Relationships
        ################################################################

        has_many :permission_roles,   :dependent => :destroy

        has_many :permissions,        :through => :permission_roles,
                                      :order => 'permissions.name'

        has_many :users,              :order => 'users.first_name, users.last_name'

        # Scoped Finders
        ################################################################

        default_scope order('roles.name')

        # Callbacks
        ################################################################

        after_save :save_permission_keys

        # Attributes
        ################################################################

        attr_accessible :description, :default_path, :locked, :name
      end
    end

    module ClassMethods
      # Quickly access a +Role+ instance by the provided name. If no +Role+
      # is found with that key, +nil+ is returned.
      #
      # @param [Symbol, String] name A role +name+ to locate.
      # @return [Role, nil]
      #
      # @example
      #   Role[:administrator]        # => Role.find_by_name('administrator')
      #   Role['User Manager']        # => Role.find_by_name('user manager')
      #   Role[:does_not_exist]       # => nil
      def [](name)
        self.find_by_name(name.to_s.strip.downcase.gsub(' ', '_').titleize)
      end

      # Shortcut for finding the Role named 'Administrator'
      #
      # @return [Role, nil]
      #
      # @example
      #   Role.admin # => Role.find_by_name('administrator')
      def admin
        @admin ||= self.find_by_name('Administrator')
      end
    end

    module InstanceMethods
      # Grab all permission keys for this +Role+
      #
      # Note that this returns <i>permission keys</i>, not Permission instances.
      #
      # @return [Array] List of permission keys registered to this role.
      #
      # @see #permission_keys=
      def permission_keys
        @permission_keys ||= self.permissions.collect(&:key)
      end

      # Set the permission keys that this role can access. This temporarily updates
      # the permission keys for the +Role+ instance, but changes are not saved until
      # the model has been saved.
      #
      # @param [Array] keys An array of permission keys to set for this role.
      # @return [Array] List of permission keys updated.
      #
      # @see #permission_keys=
      def permission_keys=(keys)
        @permission_keys = keys
        @permission_keys
      end

      # Does this role have the given +Permission+? Pass in a Permission instance, or
      # a permission key to check for its existance.
      #
      # @param [Permission, String, Symbol] permision_or_key The permission to check for.
      # @return [Boolean] Does this role have the given permission?
      #
      # @see #permission_keys
      def has(permision_or_key)
        symbolized_key = ::Permission === permision_or_key ? permision_or_key[:key] : permision_or_key.to_s
        permission_keys.include?(symbolized_key)
      end
      alias_method :permission?, :has

      # Customized +method_missing+ call that can be used to detect whether a role
      # has a given permission. This passes a key to the {#has} method.
      #
      # @example
      #   role.admin?               # => role.has(:admin)
      #   role.my_permission?       # => role.has(:my_permission)
      #
      # @see #has
      def method_missing(sym, *args, &block)
        return has(sym.to_s.gsub(/\?/, '')) if sym.to_s =~ /^[a-z0-9_]*\?$/
        super(sym, *args, &block)
      end

      protected
        # @private
        #
        # Save the permission keys that were updated using +permission_keys=+
        def save_permission_keys
          if @permission_keys and Array === @permission_keys
            self.permission_roles(true).clear

            @permission_keys.uniq.each do |key|
              permission = ::Permission.find_by_key(key)

              if permission
                self.permission_roles.create({ :permission_id => permission.id, :role_id => self.id }, :without_protection => true)
              end
            end

            @permission_keys = nil

            self.permissions(true).collect(&:key)
          end
        end
    end
  end
end


module Tang
  class Subscription < ActiveRecord::Base
    include AASM
    has_paper_trail

    aasm column: 'status' do
      state :trialing, initial: true
      state :active
      state :past_due
      state :canceled
      state :unpaid

      event :activate do
        transitions from: :trialing, to: :active
      end

      event :fail do
        transitions from: [:trialing, :active], to: :past_due
      end

      event :cancel, after: :cancel_stripe_subscription do
        transitions from: [:trialing, :active, :past_due], to: :canceled
      end

      event :close do
        transitions from: :past_due, to: :unpaid
      end
    end

    belongs_to :customer, class_name: Tang.customer_class.to_s
    belongs_to :plan
    belongs_to :coupon
    has_many :invoices, dependent: :destroy

    validates :customer, presence: true
    validates :plan, presence: true
    validates :stripe_id, presence: true, uniqueness: true
    validates :application_fee_percent, numericality: { greater_than_or_equal_to: 0 }, allow_nil: true
    validates :quantity, numericality: { greater_than_or_equal_to: 0 }, allow_nil: true
    validates :tax_percent, numericality: { greater_than_or_equal_to: 0 }, allow_nil: true,
                            format: { with: /\A\d+(?:\.\d{0,4})?\z/ }

    # before_save :nil_if_blank
    before_update :update_stripe_subscription
    # before_destroy :destroy_stripe_subscription
    before_save :check_for_upgrade
    after_save :handle_upgrade

    STATUSES = ['trialing', 'active', 'past_due', 'canceled', 'unpaid']

    def self.from_stripe(stripe_subscription, customer, plan)
      subscription = Subscription.find_or_create_by(stripe_id: stripe_subscription.id) do |s|
        s.customer = customer
        s.plan = plan
        s.application_fee_percent = stripe_subscription.application_fee_percent
        s.quantity = stripe_subscription.quantity
        s.tax_percent = stripe_subscription.tax_percent
        s.trial_end = stripe_subscription.trial_end
        s.coupon = Coupon.find_by(stripe_id: stripe_subscription.discount.coupon.id) if stripe_subscription.discount.present?
        s.status = stripe_subscription.status
      end
      return subscription
    end

    def period_start
      invoice = invoices.last
      if invoice.present?
        return invoice.period_start
      end
      return created_at
    end

    def period_end
      invoice = invoices.last
      if invoice.present?
        return invoice.period_end
      end
      return plan.period_days_from(period_start)
    end

    def quantity
      self[:quantity] || 1
    end

    def stripe_trial_end
      return 'now' if self.end_trial_now
      return self.trial_end.to_i if self.trial_end.present?
      return nil
    end

    def end_trial_now
      @end_trial_now || false
    end

    def end_trial_now=(val)
      @end_trial_now = val
    end

    def upgraded
      @upgraded || false
    end

    def upgraded=(val)
      @upgraded = val
    end

    def discount_for_plan(plan)
      amount_off = 0
      if self.coupon.percent_off.present?
        amount_off = (self.coupon.percent_off.to_f / 100.0) * plan.amount.to_f
      elsif self.coupon.amount_off.present?
        amount_off = self.coupon.amount_off
      end
      return amount_off
    end

    private

    # def nil_if_blank
    #   self.trial_end = nil if self.trial_end.blank?
    # end

    def check_for_upgrade
      if plan_id_changed?
        old_plan = Plan.find(plan_id_was) if plan_id_was.present?
        self.upgraded = true if old_plan.nil? || old_plan.order < plan.order
      end
    end

    def handle_upgrade
      if self.upgraded
        if Tang.delayed_email
          SubscriptionMailer.upgraded(self).deliver_later
        else
          SubscriptionMailer.upgraded(self).deliver_now
        end
      end
    end

    def update_stripe_subscription
      UpdateSubscription.call(self)
    end

    def cancel_stripe_subscription
      CancelSubscription.call(self)
    end
  end
end


module ZeevexProxy
  if Object.const_defined?("BasicObject")
    # A class with no predefined methods that behaves similarly to Builder's
    # BlankSlate. Used for proxy classes.
    class BasicObject < ::BasicObject
      undef_method :==
      undef_method :equal?

      # Let ActiveSupport::BasicObject at least raise exceptions.
      def raise(*args)
        ::Object.send(:raise, *args)
      end

      def initialize(*args); end

      # this causes a warning
      old_verbosity = $VERBOSE
      $VERBOSE = nil
      def object_id
        __id__
      end
      $VERBOSE = old_verbosity
    end
  else
    puts "Defining our own BasicObject"
    class BasicObject
      KEEP_METHODS = %w"__id__ __send__ method_missing __getobj__ object_id".map(&:to_sym)

      def self.remove_methods!
        m = (instance_methods.map(&:to_sym)) - KEEP_METHODS
        m.each{|m| undef_method(m)}
      end

      def self.inherited(subclass)
        BasicObject.remove_methods!
      end

      BasicObject.remove_methods!
    end
  end

  class Base < BasicObject
    def initialize(target, options = {}, &block)
      super()
      @obj = @__proxy_object__ = target
      if block
        eigenclass = class << self; self; end
        eigenclass.__send__(:define_method, :method_missing, &block)
      end
    end

    def __getobj__
      @__proxy_object__
    end

    def __substitute_self__(candidate, pself)
      candidate.__id__ == pself.__id__ ? self : candidate
    end

    # if chainable method or returns "self" for some other reason,
    # return this proxy instead
    def method_missing(name, *args, &block)
      obj = __getobj__
      __substitute_self__(obj.__send__(name, *args, &block), obj)
    end

  end
end


module RSqoot
  module Deal

    # Retrieve a list of deals based on the following parameters
    #
    # @param [String] query (Search deals by title, description, fine print, merchant name, provider, and category.)
    # @param [String] location (Limit results to a particular area. We'll resolve whatever you pass us (including an IP address) to coordinates and search near there.)
    # @param [Integer] radius (Measured in miles. Defaults to 10.)
    # @param [Integer] page (Which page of result to return. Default to 1.)
    # @param [Integer] per_page (Number of results to return at once. Defaults to 10.)
    #
    def deals(options = {})
      options = update_by_expire_time options
      if deals_not_latest?(options)
        uniq = !!options.delete(:uniq)
        @rsqoot_deals = get('deals', options, SqootDeal) || []
        @rsqoot_deals = @rsqoot_deals.deals.map(&:deal) unless @rsqoot_deals.empty?
        @rsqoot_deals = uniq_deals(@rsqoot_deals) if uniq
      end
      logger(uri: sqoot_query_uri, records: @rsqoot_deals, type: 'deals', opts: options)
      @rsqoot_deals
    end

    # Retrieve a deal by id
    #
    def deal(id, options = {})
      options = update_by_expire_time options
      if deal_not_latest?(id)
        @rsqoot_deal = get("deals/#{id}", options, SqootDeal)
        @rsqoot_deal = @rsqoot_deal.deal if @rsqoot_deal
      end
      logger(uri: sqoot_query_uri, records: [@rsqoot_deal], type: 'deal', opts: options)
      @rsqoot_deal
    end

    def impression(deal_id, options = {})
      url_generator("deals/#{deal_id}/image", options, true).first.to_s
    end

    # Auto Increment for deals query.
    def total_sqoot_deals(options = {})
      @total_deals  ||= []
      @cached_pages ||= []
      page = options[:page] || 1
      check_query_change options
      unless page_cached? page
        @total_deals += deals(options)
        @total_deals.uniq!
        @cached_pages << page.to_s
        @cached_pages.uniq!
      end
      @total_deals
    end

    private

    attr_reader :cached_pages, :total_deals, :last_deals_query

    # Uniq deals from Sqoot, because there are some many duplicated deals
    # with different ids
    # Simplely distinguish them by their titles
    #
    def uniq_deals(deals = [])
      titles = deals.map(&:title).uniq
      titles.map do |title|
        deals.map do |deal|
          deal if deal.try(:title) == title
        end.compact.last
      end.flatten
    end

    # A status checker for method :total_sqoot_deals
    # If the query parameters changed, this will reset the cache
    # else it will do nothing
    #
    def check_query_change(options = {})
      options = update_by_expire_time options
      @last_deals_query ||= ''
      current_query = options[:query].to_s
      current_query += options[:category_slugs].to_s
      current_query += options[:location].to_s
      current_query += options[:radius].to_s
      current_query += options[:online].to_s
      current_query += options[:expired_in].to_s
      current_query += options[:per_page].to_s
      if @last_deals_query != current_query
        @last_deals_query = current_query
        @total_deals  = []
        @cached_pages = []
      end
    end

    # Helper methods to detect which page is cached
    #
    def page_cached?(page = 1)
      cached_pages.include? page.to_s
    end
  end
end


require "watir"

# Cookies
module Watir
  class Browser
    # TODO: support windows.
    #
    # firefox only.
    def keep_cookies!
      require "tagen/selenium-webdriver/webdriver/firefox"

      launcher = driver.instance_variable_get("@bridge").instance_variable_get("@launcher")
      launcher.keep_cookies!
    end

    # Read cookies from Mozilla cookies.txt-style IO stream
    #
    # @param file [IO,String]
    #
    def load_cookies(file)
      now = ::Time.now

      io = case file
      when String
        open(file)
      else
        file
      end

      io.each_line do |line|
        line.chomp!
        line.gsub!(/#.+/, '')
        fields = line.split("\t")

        next if fields.length != 7

        name, value, domain, for_domain, path, secure, version = fields[5], fields[6],
          fields[0], (fields[1] == "TRUE"), fields[2], (fields[3] == "TRUE"), 0

        expires_seconds = fields[4].to_i
        expires = (expires_seconds == 0) ? nil : ::Time.at(expires_seconds)
        next if expires and (expires < now)

        cookies.add(name, value, domain: domain, path: path, expires: expires, secure: secure)
      end

      io.close if String === file

      self
    end

    # Write cookies to Mozilla cookies.txt-style IO stream
    #
    # @param file [IO,String]
    def dump_cookies(file)
      io = case file
      when String
        open(file, "w")
      else
        file
      end

      cookies.to_a.each do |cookie|
        io.puts([
          cookie[:domain],
          "FALSE", # for_domain
          cookie[:path],
          cookie[:secure] ? "TRUE" : "FALSE",
          cookie[:expires].to_i.to_s,
          cookie[:name],
          cookie[:value]
        ].join("\t"))
      end

      io.close if String === file

      self
    end
  end
end

module Watir
  class Element
    # quick set value.
    #
    # @example
    #
    #  form = browser.form(id: "foo")
    #  form.set2("//input[@name='value']", "hello")
    #  form.set2("//input[@name='check']", true)
    #  form.set2("//select[@name='foo']", "Bar")
    #  form.set2("//textarea[@name='foo']", "bar")
    #
    def set2(selector, value=nil)
      elem = element(xpath: selector).to_subtype

      case elem
      when Watir::Radio
        elem.set
      when Watir::Select
        elem.select value
      when Watir::Input
        elem.set value
      when Watir::TextArea
        elem.set value
      else
        elem.click
      end
    end
  end
end


require 'hashie/mash'
module RSqoot
  module Helper

    # Add auto-cache helper methods, instances to save the latest query
    #
    def self.included(base)
      ['deals',
       'deal',
       'categories',
       'providers',
       'merchant',
       'commissions',
       'clicks'].each do |name|
        attr_reader ('rsqoot_' + name).to_sym
        attr_accessor (name + '_options').to_sym
        base.send :define_method, (name + '_not_latest?').to_sym do |opt|
          result = method(name + '_options').call == opt ? false : true
          method(name + '_options=').call opt if result
          result
        end
      end

      # Add categories and providers query helpers
      # Search categories and providers will be very easy
      # Such as: query_categories('home&_visiter,friends')
      # => search records like: home, visiter, friends
      #
      ['categories',
       'providers'].each do |name|
        base.send :define_method, ('query_' + name).to_sym do |q|
          queries = q.downcase.scan(/[A-Za-z]+|\d+/)
          if queries.present?
            queries.map do |q|
              instance_variable_get('@rsqoot_' + name).dup.keep_if do |c|
                c.slug =~ Regexp.new(q)
              end
            end.flatten.compact.uniq
          end
        end
        base.class_eval { private ('query_' + name).to_sym }
      end

      # Add Wrappers: Deal, Category, Commission, Merchant, Provider, Click
      # All records should return as RSqoot::Sqoot* object
      #
      ['SqootDeal',
       'SqootCategory',
       'SqootCommission',
       'SqootMerchant',
       'SqootProvider',
       'SqootClick'].each do |class_name|
        new_class = Class.new(::Hashie::Mash)
        RSqoot.const_set class_name, new_class
      end
    end

    # Add expired time functionality to this gem
    # By default is 1.hour, and can be replaced anywhere
    #
    def update_by_expire_time(options = {})
      @expired_in = options[:expired_in] if options[:expired_in].present?
      time = Time.now.to_i / expired_in.to_i
      options.merge(expired_in: time)
    end
  end
end


require 'net/http'
#
# RubyMeetup is a light-weight client for the Meetup.com API version 2.
#
# ---
# Copyright (c) 2013 Long On, released under the MIT license

module RubyMeetup

# This class is abstract. It has accessor methods for configuring
# the API site. By default it is set to https://api.meetup.com but may be changed
# using the class setter method +site=+.
#
# The gem supports API request with two authentication strategies:
# API Key and OAuth 2 via the concrete classes *ApiKeyClient* and
# *AuthenticatedClient*, respectively. More information can be found in the
# specific class documentation.
#
# Example usage:
#
#  > require 'ruby_meetup'
#  > RubyMeetup::ApiKeyClient.key = 'abcd000000000000000wxyz'
#  > client = RubyMeetup::ApiKeyClient.new
#  > json_string = client.get_path("/2/groups", {:group_id => 390230})
#  > second_result = client.get({:group_id => 939203})
#
# If successful the captured response is a raw JSON string. The response can then
# be processed using a JSON parser. Otherwise an exception is raised.
#
# Typically, ApiKeyClient class is used to read data while the AuthenticatedClient
# class is used for both read and write data, subject to Meetup API permission scopes.
#
# ---
# Copyright (c) 2013 Long On, released under the MIT license

class Client
  @@site = "https://api.meetup.com"

  attr_accessor :path

  # == class methods

  # Retun the configured API endpoint
  def self.site
    @@site
  end
  # Set the global API endpoint
  def self.site=string
    @@site = string
  end

  # == instance methods

  # A convenience method to set @path and @options in the same API call.
  # Return a JSON string if successful, otherwise an Exception
  def get_path(path, options={})
    self.path = path
    get(options)
  end

  def post_path(path, options={})
    self.path = path
    post(options)
  end

  # Make a GET API call with the current path value and @options.
  # Return a JSON string if successful, otherwise an Exception
  def get(options={})
    uri = new_uri
    params = merge_params(options)
    uri.query = URI.encode_www_form(params)

    Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
      request = Net::HTTP::Get.new(uri)
      response = http.request(request)
      unless response.is_a?(Net::HTTPSuccess)
        raise "#{response.code} #{response.message}\n#{response.body}"
      end
      return response.body
    end
  end

  # Make a POST API call with the current path value and @options.
  # Return a JSON string if successful, otherwise an Exception
  def post(options={})
    uri = new_uri
    params = merge_params(options)
    uri.query = URI.encode_www_form(params)

    Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
      request = Net::HTTP::Post.new(uri)
      response = http.request(request)
      unless response.is_a?(Net::HTTPSuccess)
        raise "#{response.code} #{response.message}\n#{response.body}"
      end
      return response.body
    end
  end

  # :nodoc:
  def to_s
    "#{self.class.name}: site=#{@@site}, path=#{path}"
  end

  protected
    # :nodoc:
    def initialize
      @path = ""
    end

    # :nodoc:
    def new_uri
      URI(@@site + path)
    end

    # :nodoc:
    def merge_params(options={})
      options
    end

end

end
# :nodoc:
require 'authenticated_client'
# :nodoc:
require 'api_key_client'


module Optimacms
  class Admin::TemplatesController < Admin::AdminBaseController

    before_action :set_item, only: [:show, :edit, :update, :destroy]
    before_action :init_common
    before_action :init_data_form, only: [:new, :edit, :update, :create, :newfolder, :editfolder, :newattach, :reviewimport]
    #before_action :set_layout_modal

    def init_common
      @modal = (params[:modal] || 0).to_i
      set_layout_modal(@modal)

    end

    def set_layout_modal(modal)
      if modal.to_i==1
        #self.class.layout false
      end

    end

    def index
      #@filter.clear_data

      #
      @parent_id = @filter.v('parent_id').to_i
      @parent = Template.find(@parent_id) rescue nil

      if @parent.nil? && @parent_id>0
        redirect_to templates_path(:parent_id=>0) and return
      end

      #
      @items = model.by_filter(@filter)
      #@items = model.where(@filter.where).order(@filter.order_string).page(@filter.page)

    end

    #include SimpleFilter::Controller
    search_filter :index, {save_session: true, search_method: :post_and_redirect, url: :templates_url, search_url: :search_templates_url, search_action: :search} do
      # define filter
      default_order "title", 'asc'

      # fields
      field :title, :string, :text, {label: '', default_value: '', condition: :like_full}
      #field :parent_id, :int, :hidden, {label: '', default_value: 0, ignore_value: 0, condition: :empty}
      field :parent_id, :int, :hidden, {label: '', default_value: 0, ignore_value: -1, condition: :custom, condition_scope: :of_parent}

      #field :category_id, :int, :select, {collection: [['UGX- Uganda Shillings',1],['USD- US Dollars',2]], label_method: :first, value_method: :last}
      #field :type_id, :int, :select, {label: 'Type', default_value: 0, collection: TemplateType.all, label_method: :title, value_method: :id}
      #field :type, :string, :autocomplete, {label: 'Type', default_value: '', :source_query => :autocomplete_templates_url}

    end

    def autocomplete
      q = params[:q]
      type_id = (params[:t] || TemplateType::TYPE_PAGE).to_i

      rows = Template.where("type_id=#{type_id} AND (basepath LIKE ? OR title like ?)", "%#{q}%", "%#{q}%").order('basepath asc').limit(20)

      data = rows.map{|r| [r.id, "#{r.title} (#{r.basepath})"]}
      render :json => data
    end

    def show
    end

    def new
      @item = model.new({:tpl_format=>Optimacms::Template::EXTENSION_DEFAULT, :type_id=>TemplateType::TYPE_PAGE})
      item_init_parent
      @item.set_basedirpath_from_parent

      @url_back = url_list
    end

    def create
      @item = model.new(item_params)
      @res = @item.save

      respond_to do |format|
        if @res
          format.html {  redirect_to edit_template_path(@item), success: 'Successfully created' }
          #format.json {  render json: @item, status: :created, location: user_clients_url(:action => 'index')        }
          format.js {}
        else
          format.html {  render :new }
          #format.json { render json: @item.errors, status: :unprocessable_entity }
          format.js {}
        end
      end
    end

    def edit
      @item.build_translations
      @item.save
      @item.reload

    end

    def update
      # fix line breaks
      #content = data[:content]
      #content.gsub! /\r\n/, "\n"

      @item.attributes = item_params
      @res = @item.save
      #@res = @item.update(item_params)

      #@res = false

      if @res
        u = params[:continue]=="1" ? edit_template_path(@item) : url_list
        redirect_to u, success: 'Successfully updated'
      else
        render :edit
      end
    end

    def destroy
      @res = @item.destroy

      if @res
        redirect_to url_list, success: 'Successfully deleted'
      else
        redirect_to url_list, error: 'Cannot delete'
      end
    end

    ### layout

    def newlayout
      @item = model.new({:tpl_format=>Optimacms::Template::EXTENSION_DEFAULT, :type_id=>TemplateType::TYPE_LAYOUT})
      item_init_parent
      @item.set_basedirpath_from_parent

      @url_back = url_list
    end

    def createlayout
      @item = model.new(item_params)
      @res = @item.save

      respond_to do |format|
        if @res
          format.html {  redirect_to edit_template_path(@item), success: 'Successfully created' }
          #format.json {  render json: @item, status: :created, location: user_clients_url(:action => 'index')        }
          format.js {}
        else
          format.html {  render :newlayout }
          #format.json { render json: @item.errors, status: :unprocessable_entity }
          format.js {}
        end
      end
    end

    ### block

    def newblock
      @item = model.new({:tpl_format=>Optimacms::Template::EXTENSION_DEFAULT, :type_id=>TemplateType::TYPE_BLOCKVIEW})
      item_init_parent
      @item.set_basedirpath_from_parent

      @url_back = url_list
    end

    def createblock
      @item = model.new(item_params)
      @res = @item.save

      respond_to do |format|
        if @res
          format.html {  redirect_to edit_template_path(@item), success: 'Successfully created' }
          #format.json {  render json: @item, status: :created, location: user_clients_url(:action => 'index')        }
          format.js {}
        else
          format.html {  render :newblock }
          #format.json { render json: @item.errors, status: :unprocessable_entity }
          format.js {}
        end
      end
    end

    ### attach

    def newattach
      @item = model.new({:tpl_format=>Optimacms::Template::EXTENSION_DEFAULT})
      item_init_parent
      @item.set_basedirpath_from_parent

      @url_back = url_list
    end

    def attach
      item_params = params.require(model_name).permit!
      #(:title, :basepath, :parent_id, :tpl_format)
      item_params[:type_id] = TemplateType::TYPE_PAGE
      @item = model.new(item_params)
      @res = @item.attach

      respond_to do |format|
        if @res
          format.html {  redirect_to edit_template_path(@item), success: 'Successfully attached' }
          #format.json {  render json: @item, status: :created, location: user_clients_url(:action => 'index')        }
          format.js {}
        else
          format.html {  render :newattach }
          #format.json { render json: @item.errors, status: :unprocessable_entity }
          format.js {}
        end
      end
    end

    #### folders

    def newfolder
      @item = model.new(:is_folder=>true)
      item_init_parent
      @item.basedirpath = @item.parent.basepath+'/' unless @item.parent_id.nil?

    end

    def createfolder
      item_params = params.require(model_name).permit(:title, :basename, :parent_id, :is_folder)

      @item = model.new(item_params)
      @res = @item.save

      if @res
        redirect_to url_list, success: 'Successfully created'
      else
        render :newfolder
      end
    end

    def editfolder
      @item = Template.folders.find(params[:id])

      return url_list if @item.nil?

    end

    def updatefolder
      @item = Template.folders.find(params[:id])
      item_params = params.require(model_name).permit(:title, :basename, :parent_id, :is_folder)
      @res = @item.update_attributes(item_params)

      if @res
        redirect_to url_list, success: 'Successfully updated'
      else
        render :editfolder
      end
    end

    ### blocks

    def panel_blocks
      # input
      @path = params[:path]

      #
      @items = Template.blocks_or_partials.where("basepath LIKE ? ", "#{@path}%",).order('title asc').limit(100)

      render :layout=>false
    end

    private

    def init_data_form
      @url_back = url_list

      @languages = Language.list_with_default
    end

    def model
      Template
    end
    def model_name
      :template
    end

    def url_list
      templates_url
    end

    # Use callbacks to share common setup or constraints between actions.
    def set_item
      @item = model.find(params[:id])

      @url_back = url_list
    end

    def item_init_parent
      parent_id = params[:parent_id]
      parent_id = parent_id.to_i unless parent_id.nil?
      parent_id = nil if parent_id==0

      @item.parent_id = parent_id
    end

    def item_params
      #params.require(model_name).permit(:title)
      params.require(model_name).permit!
    end

    # filter

    def filter_prefix
      'admin_templates_index_'
    end

    def init_tabledata
      init_filter
    end

    def init_filter
      # input
      @pg = params[:pg].to_i || 1

      #
      @filter = Filters::FormFilter.new(session, filter_prefix)

      # set filter fields
      @filter.add_fields_from_array(
          [
              {name: 'title', type: 'text', dbtype: Filters::FormFilter::DBTYPE_STRING, title: 'Title', def: '', opt: {width: 120}},
              {name: 'parent_id', type: 'int', dbtype: Filters::FormFilter::FIELD_TYPE_HIDDEN, title: '', def: 0},
          ]
      )

      #
      if params.has_key? :parent_id
        @filter.set 'parent_id', params[:parent_id]
      end
      #@filter.set 'owner_id', current_user.owner_id

      #
      @cmd = params[:cmd] || ''

      # post
      if request.post? && params[:filter]
        if params[:cmd]=='clear'
          @filter.clear_data

          redirect_to url_list and return
        else
          @filter.set_data_from_form(params[:filter] || [])
          redirect_to url_list and return
        end

      end

      # order
      @filter.set_order_default('created_at' ,'desc')
      #@filter.set_order('created_at' ,'desc')

      if @cmd=='order'
        @filter.set_order params[:orderby], params[:orderdir]
        redirect_to url_list and return
      end

    end

    def table_columns
      @table_columns = [
          {name: "id", title: "##"},
          {name: "title", title: "title"},
      ]
    end

  end
end


module Ropenstack
  ##
  # * Name: ImageVersion1
  # * Description: Implementation of the Glance V1.0 API Client in Ruby
  # * Author: Sam 'Tehsmash' Betts, John Davidge
  # * Date: 30/06/2014
  ##
  module Image::Version1

    ##
    # No ID provided - Lists details for available images.
    # ID provided - Shows the image details as headers and the image binary in the body.
    ##
    def images(id, tenant_id)
      if id.nil?
        return get_request(address(tenant_id, "images/detail"), @token)
      else
        return get_request(address(tenant_id, "images/" + id), @token)
      end
    end

    ##
    # Registers a virtual machine image.
    ##
    def image_create(name, disk_format, container_format, create_image, tenant_id)
      data = {
        :name => name,
        :disk_format => disk_format,
        :container_format => container_format
      }
      unless create_image.nil?
        data[:create_image] = create_image
      end

      post_request(address(tenant_id, "images"), data, @token)
    end

    ##
    # Updates an image, uploads an image file, or updates metadata for an image.
    # NOT IMPLEMENTED
    ##
    def image_update(id, tenant_id)
      raise Ropenstack::RopenstackError, "Update Method Not Implemented."
    end

    ##
    # Deletes the specified image.
    ##
    def image_delete(id, tenant_id)
      delete_request(address(tenant_id, "images/" + id), @token)
    end

    ##
    # Replaces the membership list for an image.
    # @param memberships List of memberships in format [{'member_id': 'tenant1', 'can_share': 'false'}]
    ##
    def replace_memberships(id, memberships, tenant_id)
      data = {
        :memberships => memberships
      }
      put_request(address(tenant_id, "images/" + id + "/members"), data, @token)
    end

    ##
    # Adds a member to an image.
    # @param member_id The member to be added
    # @param can_share Optional boolean specifiying can_share value. Will default to false.
    ##
    def add_member(id, member_id, can_share, tenant_id)
      if can_share.nil?
        data = {
          :member => {:can_share => false}
        }
      else
        data = {
          :member => {:can_share => can_share}
        }
      end
      put_request(address(tenant_id, "images/" + id + "/members/" + member_id), data, @token)
    end

    ##
    # Removes a member from an image
    ##
    def delete_member(id, member_id, tenant_id)
      delete_request(address(tenant_id, "images/" + id + "/members/" + member_id), @token)
    end

    ##
    # Lists the images shared with a specified owner.
    ##
    def shared_images(id, owner_id, tenant_id)
      get_request(address(tenant_id, "shared-images/" + owner_id), @token)
    end

    ##
    # Returns the v1 address location of an endpoint.
    ##
    def address(tenant_id, endpoint)
      address("/v1/#{tenant_id}/#{endpoint}")
    end

    def version
      "V1"
    end
  end
end


require "etc"
require "fileutils"

module Scripto
  module FileCommands
    # Like mkdir -p +dir+. If +owner+ is specified, the directory will be
    # chowned to owner. If +mode+ is specified, the directory will be chmodded
    # to mode. Like all file commands, the operation will be printed out if
    # verbose?.
    def mkdir(dir, owner: nil, mode: nil)
      FileUtils.mkdir_p(dir, verbose: verbose?)
      chown(dir, owner) if owner
      chmod(dir, mode) if mode
    end

    # Like cp -pr +src+ +dst. If +mkdir+ is true, the dst directoy will be
    # created if necessary before the copy. If +owner+ is specified, the
    # directory will be chowned to owner. If +mode+ is specified, the
    # directory will be chmodded to mode. Like all file commands, the
    # operation will be printed out if verbose?.
    def cp(src, dst, mkdir: false, owner: nil, mode: nil)
      mkdir_if_necessary(File.dirname(dst)) if mkdir
      FileUtils.cp_r(src, dst, preserve: true, verbose: verbose?)
      chown(dst, owner) if owner && !File.symlink?(dst)
      chmod(dst, mode) if mode
    end

    # Like mv +src+ +dst. If +mkdir+ is true, the dst directoy will be created
    # if necessary before the copy. Like all file commands, the operation will
    # be printed out if verbose?.
    def mv(src, dst, mkdir: false)
      mkdir_if_necessary(File.dirname(dst)) if mkdir
      FileUtils.mv(src, dst, verbose: verbose?)
    end

    # Like ln -sf +src+ +dst. The command will be printed out if
    # verbose?.
    def ln(src, dst)
      FileUtils.ln_sf(src, dst, verbose: verbose?)
    rescue Errno::EEXIST => e
      # It's a race - this can occur because ln_sf removes the old
      # dst, then creates the symlink. Raise if they don't match.
      raise e if !(File.symlink?(dst) && src == File.readlink(dst))
    end

    # Like rm -f +file+. Like all file commands, the operation will be printed
    # out if verbose?.
    def rm(file)
      FileUtils.rm_f(file, verbose: verbose?)
    end

    # Runs #mkdir, but ONLY if +dir+ doesn't already exist. Returns true if
    # directory had to be created. This is useful with verbose?, to get an
    # exact changelog.
    def mkdir_if_necessary(dir, owner: nil, mode: nil)
      return if File.exist?(dir) || File.symlink?(dir)
      mkdir(dir, owner: owner, mode: mode)
      true
    end

    # Runs #cp, but ONLY if +dst+ doesn't exist or differs from +src+. Returns
    # true if the file had to be copied. This is useful with verbose?, to get
    # an exact changelog.
    def cp_if_necessary(src, dst, mkdir: false, owner: nil, mode: nil)
      return if File.exist?(dst) && FileUtils.compare_file(src, dst)
      cp(src, dst, mkdir: mkdir, owner: owner, mode: mode)
      true
    end

    # Runs #ln, but ONLY if +dst+ isn't a symlink or differs from +src+.
    # Returns true if the file had to be symlinked. This is useful with
    # verbose?, to get an exact changelog.
    def ln_if_necessary(src, dst)
      if File.symlink?(dst)
        return if src == File.readlink(dst)
        rm(dst)
      end

      ln(src, dst)
      true
    end

    # Runs #rm, but ONLY if +file+ exists. Return true if the file had to be
    # removed. This is useful with verbose?, to get an exact changelog.
    def rm_if_necessary(file)
      return if !File.exist?(file)
      rm(file)
      true
    end

    # Like chown user:user file. Like all file commands, the operation will be printed
    # out if verbose?.
    def chown(file, user)
      # who is the current owner?
      @scripto_uids ||= {}
      @scripto_uids[user] ||= Etc.getpwnam(user).uid
      uid = @scripto_uids[user]
      return if File.stat(file).uid == uid
      FileUtils.chown(uid, uid, file, verbose: verbose?)
    end

    # Like chmod mode file. Like all file commands, the operation will be
    # printed out if verbose?.
    def chmod(file, mode)
      return if File.stat(file).mode == mode
      FileUtils.chmod(mode, file, verbose: verbose?)
    end

    # Like rm -rf && mkdir -p. Like all file commands, the operation will be
    # printed out if verbose?.
    def rm_and_mkdir(dir)
      raise "don't do this" if dir == ""
      FileUtils.rm_rf(dir, verbose: verbose?)
      mkdir(dir)
    end

    # Copy mode, atime and mtime from +src+ to +dst+. This one is rarely used
    # and doesn't echo.
    def copy_metadata(src, dst)
      stat = File.stat(src)
      File.chmod(stat.mode, dst)
      File.utime(stat.atime, stat.mtime, dst)
    end

    # Atomically write to +path+. An open temp file is yielded.
    def atomic_write(path)
      tmp = Tempfile.new(File.basename(path))
      yield(tmp)
      tmp.close
      chmod(tmp.path, 0o644)
      mv(tmp.path, path)
    ensure
      rm_if_necessary(tmp.path)
    end
  end
end


module WordTree
  class BookList
    include Enumerable

    # can be initialized from the following sources:
    # - a WordTree::Disk::Library object
    # - an open File object (containing a list of files or paths to books)
    # - a String directory (presumed to be the library on disk)
    # - a String file (containing a list of files or paths to books)
    def initialize(source)
      @source = source
      @iterable = iterable_from_source(source)
    end

    def iterable_from_source(source)
      case source
      when WordTree::Disk::Library then
        source
      when File then
        source.read.split("\n").tap do |file|
          file.close
        end
      when String then
        if File.directory?(source)
          WordTree::Disk::Library.new(source)
        elsif File.exist?(source)
          IO.read(source).split("\n")
        else
          raise Errno::ENOENT, "Unable to find source for BookList, #{source.inspect}"
        end
      end
    end

    def each(&block)
      @iterable.each(&block)
    end
  end
end


module Conject
  class ObjectFactory
    construct_with :class_finder, :dependency_resolver

    def construct_new(name, object_context)
      object = nil
      config = object_context.get_object_config(name)
      lambda_constructor = config[:construct]
      alias_for = config[:is]
      klass = config[:class]
      raise "#{klass.inspect} is not a Class" if klass and !(Class === klass)
      if alias_for
        # This object is defined as simply being another name for a different object
        begin
          object = object_context.get(alias_for)
        rescue Exception => ex
          raise "(When attempting to fill alias '#{name}' with actual object '#{alias_for}') #{ex.message}"
        end

      elsif lambda_constructor
        case lambda_constructor.arity
        when 0
          object = lambda_constructor[]
        when 1
          object = lambda_constructor[object_context]
        when 2
          object = lambda_constructor[name, object_context]
        else
          raise "Constructor lambda takes 0, 1 or 2 params; this lambda takes #{lambda_constructor.arity}"
        end

      elsif klass
        # This object has a specified class
        object = type_1_constructor(klass, name, object_context, config[:specialize]) # Specify class
      else
        object = type_1_constructor(nil, name, object_context, config[:specialize]) # Let class be determined by name
      end

      # Stuff an internal back reference to the object context into the new object:
      object.__send__(:instance_variable_set, :@_conject_object_context, object_context)

      return object
    end

    private

    #
    # This implementation is what I'm loosely calling "type 1" or "regular" object creation:
    #  - Assume we're looking for a class to create an instance with
    #  - it may or may not have a declared list of named objects it needs to be constructed with
    #
    def type_1_constructor(klass, name, object_context, overrides=nil)
      klass ||= class_finder.find_class(name)

      if !klass.object_peers.empty?
        anchor_object_peers object_context, klass.object_peers
      end

      constructor_func = nil
      if klass.has_object_definition?
        object_map = dependency_resolver.resolve_for_class(klass, object_context, overrides)
        constructor_func = lambda do klass.new(object_map) end

      elsif Utilities.has_zero_arg_constructor?(klass)
        # Default construction
        constructor_func = lambda do klass.new end
      else
        # Oops, out of ideas on how to build.
        raise ArgumentError.new("Class #{klass} has no special component needs, but neither does it have a zero-argument constructor.");
      end

      object = nil
      Conject.override_object_context_with object_context do
        begin
          object = constructor_func.call
        rescue Exception => ex
          origin = "#{ex.message}\n\t#{ex.backtrace.join("\n\t")}"
          name ||= "(no name)"
          raise "Error while constructing object '#{name}' of class #{klass}: #{origin}"
        end
      end
    end

    def anchor_object_peers(object_context, object_peers)
      object_peers.each do |name|
        object_context.configure_objects(name => {})
      end
    end
  end
end


require 'thread'

module Capybarbecue
  class Server
    DEFAULT_TIMEOUT = 30
    attr_accessor :wait_for_response # For testing - set to false to keep #call from blocking
    attr_accessor :timeout, :app

    def initialize(app)
      @app = app
      @requestmq = Queue.new
      @wait_for_response = true
      @timeout = DEFAULT_TIMEOUT
    end

    def call(env)
      env.update({"rack.multithread" => false, "rack.multiprocess" => false, "rack.run_once" => false})
      queue_and_wait(env)
    end

    # Should be run by another thread - respond to all queued requests
    def handle_requests
      until @requestmq.empty?
        request = @requestmq.deq(true)
        begin
          request.response = @app.call(request.env)
        rescue Exception => e
          request.exception = e
        ensure
          body = request.response.try(:last)
          body.close  if body.respond_to? :close
        end
      end
    end

    private

    def queue_and_wait(env)
      request = QueuedRequest.new(env)
      @requestmq.enq(request)
      return unless wait_for_response
      wait_for request
      check_exception_for request
      request.response
    end

    def wait_for(request)
      started_at = Time.now
      while !request.ready? && Time.now - started_at < timeout.seconds
        # It feels dangerous not to sleep here... keep a pulse on this (sleep causes performance problems)
        Thread.pass
      end
      raise Timeout::Error.new('Timeout expired before response received') unless request.ready?
    end

    def check_exception_for(request)
      if request.exception.present?
        # Add the backtrace from this thread to make it useful
        backtrace = request.exception.backtrace + Kernel.caller
        request.exception.set_backtrace(backtrace)
        raise request.exception
      end
    end

    class QueuedRequest
      attr_reader :env
      attr_accessor :response, :exception
      def initialize(env)
        @env = env
      end
      def ready?
        @response.present? || @exception.present?
      end
    end
  end
end


# encoding: utf-8

module Tabledata

  # Represents a column in a table and provides an easy way to enumerate
  # values in a column.
  #
  # @note
  #   The column data is not copied. It is retrieved from the table via the columns index.
  #   If you mutate the table, adding a column to it, this column instance's data will change.
  class Column

    # @return [Tabledata::Table] The table this column belongs to.
    attr_reader :table

    # @return [Integer] The column index in the table, zero based.
    attr_reader :index

    include Enumerable

    # @param [Tabledata::Table] table
    #   The table this column belongs to.
    # @param [Integer] index
    #   The index of the column in the table.
    def initialize(table, index)
      @table  = table
      @index  = index
    end

    # @return [Object]
    #   The header value of this column (if available)
    def header
      @table.column_header(@index)
    end

    # @return [Symbol, nil]
    #   The accessor for this column
    def accessor
      @table.column_accessor(@index)
    end

    # Similar to Tabledata::Table#[], but only returns values for this column.
    # Provides array like access to this column's data. Only considers body
    # values (i.e., does not consider header and footer).
    #
    # @return [Array, Object]
    def [](*args)
      rows = @table.body[*args]

      if rows.is_a?(Array) # slice
        rows.map { |row| row[@index] }
      else # single row
        rows[@index]
      end
    end

    # Iterate over all body values (i.e. no header or footer) in the column.
    #
    # @see Tabledata::Column#each_value
    #   A method which iterates over all values, including header and footer.
    #
    # @yield [value]
    # @yieldparam [Object]
    #
    # @return [self]
    def each
      return enum_for(__method__) unless block_given?

      @table.each do |row|
        yield(row[@index])
      end

      self
    end

    # Iterate over all values in the column, including header and footer.
    #
    # @see Tabledata::Table#each
    #   A method which iterates only over body values, excluding header and footer.
    #
    # @yield [value]
    # @yieldparam [Object]
    #
    # @return [self]
    def each_value
      return enum_for(__method__) unless block_given?

      @table.data.each do |row|
        yield(row[@index])
      end

      self
    end

    # @return [Integer] The number of values, excluding headers and footer
    def size
      @table.size
    end
    alias length size

    # @param [Hash] options
    # @option options [Symbol] :include_header
    #   Defaults to true. If set to false, the header (if present) is excluded.
    # @option options [Symbol] :include_footer
    #   Defaults to true. If set to false, the footer (if present) is excluded.
    #
    # @return [Array] All values in the column, including header and footer.
    def to_a(options=nil)
      data = @table.data.transpose[@index]

      if options
        start_offset = options[:include_header] && @table.headers? ? 1 : 0
        end_offset   = options[:include_footer] && @table.footer? ? -2 : -1

        data[start_offset..end_offset]
      else
        data
      end
    end

    # @param [Tabledata::Column, Array, #to_ary, Object] other
    #
    # @return [true, false]
    #   Whether the values in this column is equal to the values in `other`
    #   False if other is neither a Tabledata::Column, Array, or Object
    #   responding to #to_ary.
    def ==(other)
      if other.is_a?(Tabledata::Column)
        other.to_a == @table.data.transpose[@index]
      elsif other.is_a?(Array)
        other == @table.data.transpose[@index]
      elsif other.respond_to?(:to_ary)
        other.to_ary == @table.data.transpose[@index]
      else
        false
      end
    end

    # @param [Object]
    #
    # @return [true, false] Whether `other` is also a column and contains the same data.
    def eql?(other)
      other.is_a?(Tabledata::Column) && @table.data.transpose[@index] == other.to_a
    end

    # See Object#hash
    def hash
      [Tabledata::Column, to_a].hash
    end
  end
end