akamai_api 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Guardfile +1 -1
- data/README.md +43 -2
- data/Thorfile +1 -1
- data/lib/akamai_api.rb +1 -1
- data/lib/akamai_api/cli/eccu/base.rb +47 -0
- data/lib/akamai_api/eccu/token.rb +10 -0
- data/lib/akamai_api/eccu/tokenizer.rb +124 -0
- data/lib/akamai_api/eccu_parser.rb +94 -0
- data/lib/akamai_api/version.rb +1 -1
- data/spec/features/eccu/parser_integration_spec.rb +32 -0
- data/spec/fixtures/eccu/parser/dir_with_extension.xml +10 -0
- data/spec/fixtures/eccu/parser/dir_with_filename.xml +10 -0
- data/spec/fixtures/eccu/parser/only_sub_dirs_extension.xml +10 -0
- data/spec/fixtures/eccu/parser/recursive_extension.xml +8 -0
- data/spec/fixtures/eccu/parser/sub_dirs.xml +8 -0
- data/spec/fixtures/eccu/parser/this_dir_only.xml +8 -0
- data/spec/fixtures/eccu/parser/this_dir_recursive.xml +6 -0
- data/spec/lib/akamai_api/eccu/tokenizer_spec.rb +85 -0
- data/spec/lib/akamai_api/eccu_parser_spec.rb +37 -0
- metadata +25 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 357ad26a6a5da39a595170949bbb7fb84226ce87
         | 
| 4 | 
            +
              data.tar.gz: 9c14d311812d842102696154f90c902c423d0bde
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 3d384c9b6755b5e8c74c0cdb266f42a5575e54f83a3b693ccf6b9910c428ba5a40ac43b8f7f1c42fbfae43ed162707585bd8f1262f714e48e270b89a450d58c3
         | 
| 7 | 
            +
              data.tar.gz: c083205f44b3bf0019f8775c7557eeb176fd6f0cc5fdd306b704b7bbf7cf498a243cd23fd3f7afd3dd836930687484646f331cc508658aa6d04f8544cd79c403
         | 
    
        data/Guardfile
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            # A sample Guardfile
         | 
| 2 2 | 
             
            # More info at https://github.com/guard/guard#readme
         | 
| 3 3 |  | 
| 4 | 
            -
            guard :rspec do
         | 
| 4 | 
            +
            guard :rspec, cmd: 'bundle exec rspec' do
         | 
| 5 5 | 
             
              watch(%r{^spec/.+_spec\.rb$})
         | 
| 6 6 | 
             
              watch(%r{^lib/(.+)\.rb$})     { |m| "spec/lib/#{m[1]}_spec.rb" }
         | 
| 7 7 | 
             
              watch('spec/spec_helper.rb')  { "spec" }
         | 
    
        data/README.md
    CHANGED
    
    | @@ -102,6 +102,7 @@ In the ECCU interface you can see the requestes already published and publish yo | |
| 102 102 | 
             
                akamai_api ECCU last_request                              # Print the last request made to ECCU
         | 
| 103 103 | 
             
                akamai_api ECCU publish_xml path/to/request.xml john.com  # Publish a request made in XML for the specified Digital Property (usually the Host Header)
         | 
| 104 104 | 
             
                akamai_api ECCU requests                                  # Print the list of the last requests made to ECCU
         | 
| 105 | 
            +
                akamai_api ECCU revalidate now jhon.com "*.png"           # Create an XML request based on querystring input (*.png) for the specified Digital Property (usually the Host Header)
         | 
| 105 106 | 
             
            ```
         | 
| 106 107 |  | 
| 107 108 | 
             
            ### Viewing Requests
         | 
| @@ -125,14 +126,54 @@ Options: | |
| 125 126 | 
             
                                                      # Default: hostheader
         | 
| 126 127 | 
             
                  [--no-exact-match]                  # Do not do an exact match on property names
         | 
| 127 128 | 
             
              -e, [--emails=foo@foo.com bar@bar.com]  # Email(s) to use to send notification on status change
         | 
| 128 | 
            -
              -n, [--notes=NOTES]
         | 
| 129 | 
            -
                                                      # Default: ECCU Request using AkamaiApi gem
         | 
| 129 | 
            +
              -n, [--notes=NOTES]                     # Default: ECCU Request using AkamaiApi gem
         | 
| 130 130 | 
             
            ```
         | 
| 131 131 |  | 
| 132 132 | 
             
            The command takes two arguments:
         | 
| 133 133 | 
             
            - the file containing the request;
         | 
| 134 134 | 
             
            - the Digital Property to which you want to apply the request (usually it's the host);
         | 
| 135 135 |  | 
| 136 | 
            +
            ### Revalidate based on a query string
         | 
| 137 | 
            +
             | 
| 138 | 
            +
            You con use *akamai_api ECCU revalidate* for generate an XML revalidation file base on a query string.
         | 
| 139 | 
            +
             | 
| 140 | 
            +
            ```
         | 
| 141 | 
            +
            Usage:
         | 
| 142 | 
            +
              akamai_api revalidate now jhon.com "*.png"
         | 
| 143 | 
            +
             | 
| 144 | 
            +
            Options:
         | 
| 145 | 
            +
              -f, [--force]                            # Force request without confirm
         | 
| 146 | 
            +
              -P, [--property-type=type]               # Type of enlisted properties
         | 
| 147 | 
            +
                                                       # Default: hostheader
         | 
| 148 | 
            +
                  [--no-exact-match]                   # Do not do an exact match on property names
         | 
| 149 | 
            +
              -e, [--emails=foo@foo.com bar@bar.com]   # Email(s) to use to send notification on status change
         | 
| 150 | 
            +
              -n, [--notes=NOTES]                      # Default: ECCU Request using AkamaiApi gem
         | 
| 151 | 
            +
            ```
         | 
| 152 | 
            +
             | 
| 153 | 
            +
            The command produces the following result and ask you if you want to publish:
         | 
| 154 | 
            +
             | 
| 155 | 
            +
            ```xml
         | 
| 156 | 
            +
            <?xml version="1.0"?><eccu><match:ext value="png"><revalidate>now</revalidate></match:ext></eccu>
         | 
| 157 | 
            +
            ```
         | 
| 158 | 
            +
             | 
| 159 | 
            +
            The command takes two arguments:
         | 
| 160 | 
            +
            - the timestamp after which any content, matched, in cache with an older timestamp will be considered stale
         | 
| 161 | 
            +
            - the Digital Property to which you want to apply the request (usually it's the host);
         | 
| 162 | 
            +
            - the query string that will be analyzed to produce the XML
         | 
| 163 | 
            +
             | 
| 164 | 
            +
            #### Rules for the Querystring
         | 
| 165 | 
            +
             | 
| 166 | 
            +
            - *foo* : indicate a filename
         | 
| 167 | 
            +
            - *foo/* : indicate the **foo** dir
         | 
| 168 | 
            +
            - *foo/** : indicate all direct sub dirs of **foo**
         | 
| 169 | 
            +
            - *foo/*** : indicate recursively all sub dirs of **foo**
         | 
| 170 | 
            +
            - **.png* : indicate all pngs
         | 
| 171 | 
            +
            - *foo.txt* : indicate specific file (foo.txt)
         | 
| 172 | 
            +
             | 
| 173 | 
            +
            Following the Akamai API docs there is a limitation:
         | 
| 174 | 
            +
             | 
| 175 | 
            +
            Akamai recommends that you limit the number of matches to 250 or fewer. Submitting more than 250 invalidation requests at one time can result in a “global invalidation”
         | 
| 176 | 
            +
             | 
| 136 177 | 
             
            # As a Library
         | 
| 137 178 |  | 
| 138 179 | 
             
            Remember to init the AkamaiApi gem with your login credentials. You can set your credentials with the following statement:
         | 
    
        data/Thorfile
    CHANGED
    
    | @@ -20,7 +20,7 @@ class Default < Thor | |
| 20 20 |  | 
| 21 21 | 
             
              desc "release", "Create tag v#{AkamaiApi::VERSION} and build and push akamai_api-#{AkamaiApi::VERSION}.gem to Rubygems"
         | 
| 22 22 | 
             
              def release
         | 
| 23 | 
            -
                Rake::Task["release"]. | 
| 23 | 
            +
                Rake::Task["release"].invoke
         | 
| 24 24 | 
             
              end
         | 
| 25 25 |  | 
| 26 26 | 
             
              desc "spec", "Run RSpec code examples"
         | 
    
        data/lib/akamai_api.rb
    CHANGED
    
    
| @@ -55,5 +55,52 @@ module AkamaiApi::CLI::ECCU | |
| 55 55 | 
             
                rescue Savon::SOAPFault
         | 
| 56 56 | 
             
                  puts $!.message
         | 
| 57 57 | 
             
                end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                desc 'revalidate now jhon.com "*.png"', 'Create an XML request based on querystring input (*.png) for the specified Digital Property (usually the Host Header)'
         | 
| 60 | 
            +
                long_desc 'Create an XML request based on querystring input (*.png) for the specified Digital Property (usually the Host Header)'
         | 
| 61 | 
            +
                method_option :force, :type => :boolean, :aliases => '-f',
         | 
| 62 | 
            +
                              :default => false, :banner => 'force',
         | 
| 63 | 
            +
                              :desc => 'Force request without confirm'
         | 
| 64 | 
            +
                method_option :property_type, :type => :string, :aliases => '-P',
         | 
| 65 | 
            +
                              :default => 'hostheader', :banner => 'type',
         | 
| 66 | 
            +
                              :desc => 'Type of enlisted properties'
         | 
| 67 | 
            +
                method_option :no_exact_match, :type => :boolean,
         | 
| 68 | 
            +
                              :desc => 'Do not do an exact match on property names'
         | 
| 69 | 
            +
                method_option :emails,   :type => :array,  :aliases => '-e',
         | 
| 70 | 
            +
                              :banner => "foo@foo.com bar@bar.com",
         | 
| 71 | 
            +
                              :desc => 'Email(s) to use to send notification on status change'
         | 
| 72 | 
            +
                method_option :notes, :type => :string, :aliases => '-n',
         | 
| 73 | 
            +
                              :default => "ECCU Request using AkamaiApi #{AkamaiApi::VERSION}"
         | 
| 74 | 
            +
                def revalidate(revalidate_on, property, querystring)
         | 
| 75 | 
            +
                  load_config
         | 
| 76 | 
            +
                  args = {
         | 
| 77 | 
            +
                    :notes => options[:notes],
         | 
| 78 | 
            +
                    :property_exact_match => !options[:no_exact_match],
         | 
| 79 | 
            +
                    :property_type => options[:property_type],
         | 
| 80 | 
            +
                    :emails => options[:emails]
         | 
| 81 | 
            +
                  }
         | 
| 82 | 
            +
                  parser = AkamaiApi::ECCUParser.new querystring, revalidate_on
         | 
| 83 | 
            +
                  puts parser.xml
         | 
| 84 | 
            +
                  if options[:force]
         | 
| 85 | 
            +
                    str = "Y"
         | 
| 86 | 
            +
                  else
         | 
| 87 | 
            +
                    print "\nPublish this XML? (Y/n)"
         | 
| 88 | 
            +
                    begin
         | 
| 89 | 
            +
                      system("stty raw -echo")
         | 
| 90 | 
            +
                      str = STDIN.getc
         | 
| 91 | 
            +
                    ensure
         | 
| 92 | 
            +
                      system("stty -raw echo")
         | 
| 93 | 
            +
                    end
         | 
| 94 | 
            +
                  end
         | 
| 95 | 
            +
                  if str == "Y"
         | 
| 96 | 
            +
                    id = AkamaiApi::ECCURequest.publish property, parser.xml, args
         | 
| 97 | 
            +
                    puts "\n\nRequest correctly published:"
         | 
| 98 | 
            +
                    puts EntryRenderer.new(AkamaiApi::ECCURequest.find(id, :verbose => true)).render
         | 
| 99 | 
            +
                  else
         | 
| 100 | 
            +
                    puts "\n\nExit without publish request"
         | 
| 101 | 
            +
                  end
         | 
| 102 | 
            +
                rescue Exception => e
         | 
| 103 | 
            +
                  puts e.message
         | 
| 104 | 
            +
                end
         | 
| 58 105 | 
             
              end
         | 
| 59 106 | 
             
            end
         | 
| @@ -0,0 +1,124 @@ | |
| 1 | 
            +
            require 'akamai_api/eccu/token'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module AkamaiApi::ECCU
         | 
| 4 | 
            +
              # Class used to tokenize path used for invalidate cache
         | 
| 5 | 
            +
              #
         | 
| 6 | 
            +
              # foo/bar/*.txt
         | 
| 7 | 
            +
              class Tokenizer
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                SEPARATORS = ['/']
         | 
| 10 | 
            +
                DIR_REGEXP = /^[^\/]+$/
         | 
| 11 | 
            +
                WILDCARD_REGEXP = /^\**$/
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                attr_reader :tokens, :cursor
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                def initialize expression
         | 
| 16 | 
            +
                  @cursor = -1
         | 
| 17 | 
            +
                  tokenize expression
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                def current_token
         | 
| 21 | 
            +
                  return nil if cursor == -1
         | 
| 22 | 
            +
                  tokens[cursor]
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def next_token
         | 
| 26 | 
            +
                  @cursor += 1
         | 
| 27 | 
            +
                  current_token
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                def look_next_token i = 1
         | 
| 31 | 
            +
                  tokens[cursor + i] 
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                def look_prev_token i = 1
         | 
| 35 | 
            +
                  tokens[cursor - 1]
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                def look_next_token_except exclude_type = nil
         | 
| 39 | 
            +
                  look_next_token if exclude_type == nil
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                  i = 1
         | 
| 42 | 
            +
                  while tokens[cursor + i].type == exclude_type
         | 
| 43 | 
            +
                    i += 1
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
                  tokens[cursor + i]
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                def look_next_token_of_type token_type = nil
         | 
| 49 | 
            +
                  look_next_token if token_type == nil
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                  i = cursor
         | 
| 52 | 
            +
                  while tokens.size < i
         | 
| 53 | 
            +
                    return tokens[i] if tokens[i].type == token_type
         | 
| 54 | 
            +
                    i += 1
         | 
| 55 | 
            +
                  end
         | 
| 56 | 
            +
                  nil
         | 
| 57 | 
            +
                end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
              private 
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                def tokenize expression
         | 
| 62 | 
            +
                  @tokens = []
         | 
| 63 | 
            +
                  expression_to_parse = expression.strip
         | 
| 64 | 
            +
                  while expression_to_parse.size > 0
         | 
| 65 | 
            +
                    tokens << read_next_token(expression_to_parse)
         | 
| 66 | 
            +
                  end
         | 
| 67 | 
            +
                end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                def read_next_token expression_to_parse
         | 
| 70 | 
            +
                  expression_to_parse.strip!
         | 
| 71 | 
            +
                  next_char = expression_to_parse.slice 0
         | 
| 72 | 
            +
                  if SEPARATORS.include? next_char
         | 
| 73 | 
            +
                    read_next_separator_token expression_to_parse
         | 
| 74 | 
            +
                  elsif next_char =~ WILDCARD_REGEXP
         | 
| 75 | 
            +
                    read_next_wildcard_token expression_to_parse
         | 
| 76 | 
            +
                  elsif next_char =~ DIR_REGEXP
         | 
| 77 | 
            +
                    read_next_dir_token expression_to_parse
         | 
| 78 | 
            +
                  else
         | 
| 79 | 
            +
                    raise "Unknown token starting with '#{next_char}'"
         | 
| 80 | 
            +
                  end
         | 
| 81 | 
            +
                end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                def read_next_separator_token expression_to_parse
         | 
| 84 | 
            +
                  Token.new :separator, expression_to_parse.slice!(0)
         | 
| 85 | 
            +
                end
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                def read_next_wildcard_token expression_to_parse
         | 
| 88 | 
            +
                  wildcard_value, next_char = loop_until_regexp expression_to_parse, WILDCARD_REGEXP
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                  if wildcard_value.size == 1
         | 
| 91 | 
            +
                    Token.new :wildcard, wildcard_value
         | 
| 92 | 
            +
                  elsif wildcard_value.size == 2
         | 
| 93 | 
            +
                    Token.new :double_wildcard, wildcard_value
         | 
| 94 | 
            +
                  else
         | 
| 95 | 
            +
                    raise "Unknown wildcard '#{wildcard_value}'"
         | 
| 96 | 
            +
                  end
         | 
| 97 | 
            +
                end
         | 
| 98 | 
            +
             | 
| 99 | 
            +
                def read_next_dir_token expression_to_parse
         | 
| 100 | 
            +
                  dir_value, next_char = loop_until_regexp expression_to_parse, DIR_REGEXP
         | 
| 101 | 
            +
             | 
| 102 | 
            +
                  if tokens.size > 0 && tokens.last.type == :wildcard
         | 
| 103 | 
            +
                    Token.new :extension, dir_value.gsub('.','')
         | 
| 104 | 
            +
                  elsif SEPARATORS.include? next_char
         | 
| 105 | 
            +
                    Token.new :dir, dir_value
         | 
| 106 | 
            +
                  else
         | 
| 107 | 
            +
                    Token.new :filename, dir_value
         | 
| 108 | 
            +
                  end
         | 
| 109 | 
            +
                end
         | 
| 110 | 
            +
             | 
| 111 | 
            +
                def loop_until_regexp expression_to_parse, regexp
         | 
| 112 | 
            +
                  looped_value = ''
         | 
| 113 | 
            +
                  next_char = ''
         | 
| 114 | 
            +
                  begin
         | 
| 115 | 
            +
                    looped_value << expression_to_parse.slice!(0)
         | 
| 116 | 
            +
                    next_char = expression_to_parse.slice 0
         | 
| 117 | 
            +
                  end while next_char && "#{looped_value}#{next_char}" =~ regexp
         | 
| 118 | 
            +
             | 
| 119 | 
            +
                  return looped_value, next_char
         | 
| 120 | 
            +
                end
         | 
| 121 | 
            +
             | 
| 122 | 
            +
              end
         | 
| 123 | 
            +
             | 
| 124 | 
            +
            end
         | 
| @@ -0,0 +1,94 @@ | |
| 1 | 
            +
            require 'akamai_api/eccu/tokenizer'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module AkamaiApi
         | 
| 4 | 
            +
              # The {ECCUParser} class is used to create a XML request file starting from a url
         | 
| 5 | 
            +
              #
         | 
| 6 | 
            +
              # @example
         | 
| 7 | 
            +
              #   AkamaiApi::ECCUParser.new(foo/bar/*.png).xml
         | 
| 8 | 
            +
              class ECCUParser
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                PLACEHOLDER = "{YIELD}"
         | 
| 11 | 
            +
                NOT_ALLOWED_EXTENSIONS = %w[*]
         | 
| 12 | 
            +
                NOT_ALLOWED_DIRS = %w[. ..]
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                attr_reader :tokenizer, :xml, :revalidate_on
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                def initialize expression, revalidate_on = 'now'
         | 
| 17 | 
            +
                  raise "Expression can't be empty" if expression.empty?
         | 
| 18 | 
            +
                  revalidate_on = revalidate_on.to_i if revalidate_on != 'now'
         | 
| 19 | 
            +
                  @tokenizer = ECCU::Tokenizer.new expression
         | 
| 20 | 
            +
                  @revalidate_on = revalidate_on
         | 
| 21 | 
            +
                  @xml = "<?xml version=\"1.0\"?>\n<eccu>#{PLACEHOLDER}</eccu>"
         | 
| 22 | 
            +
                  parse
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
              private
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                def parse
         | 
| 28 | 
            +
                  while tokenizer.look_next_token
         | 
| 29 | 
            +
                    tokenizer.next_token
         | 
| 30 | 
            +
                    send "add_#{tokenizer.current_token.type.to_s}_tag", tokenizer.current_token.value
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  add_revalidate
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                def next_wildcard_extension?
         | 
| 37 | 
            +
                  tokenizer.look_next_token.type == :wildcard and 
         | 
| 38 | 
            +
                    ! tokenizer.look_next_token(2).nil? and 
         | 
| 39 | 
            +
                    tokenizer.look_next_token(2).type == :extension
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                def next_filename?
         | 
| 43 | 
            +
                  tokenizer.look_next_token.type == :filename
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                def add_revalidate
         | 
| 47 | 
            +
                  xml.gsub! PLACEHOLDER, "<revalidate>#{revalidate_on}</revalidate>"
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                def add_dir_tag dir_name
         | 
| 51 | 
            +
                  raise "Dir '#{dir_name}' not allowed" if NOT_ALLOWED_DIRS.include? dir_name
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                  xml.gsub! PLACEHOLDER, "<match:recursive-dirs value=\"#{dir_name}\">#{PLACEHOLDER}</match:recursive-dirs>"
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                def add_this_dir_tag
         | 
| 57 | 
            +
                  xml.gsub! PLACEHOLDER, "<match:this-dir value=\"This Directory Only\">#{PLACEHOLDER}</match:this-dir>"
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
             | 
| 61 | 
            +
                def add_extension_tag extension
         | 
| 62 | 
            +
                  raise "Extension '#{extension}' not allowed" if NOT_ALLOWED_EXTENSIONS.include? extension
         | 
| 63 | 
            +
                  raise "Extension will be the last element" if tokenizer.look_next_token != nil
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                  xml.gsub! PLACEHOLDER, "<match:ext value=\"#{extension}\">#{PLACEHOLDER}</match:ext>"
         | 
| 66 | 
            +
                end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                def add_filename_tag filename
         | 
| 69 | 
            +
                  xml.gsub! PLACEHOLDER, "<match:filename value=\"#{filename}\" nocase=\"off\">#{PLACEHOLDER}</match:filename>"
         | 
| 70 | 
            +
                end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                def add_separator_tag separator
         | 
| 73 | 
            +
                  if tokenizer.look_prev_token.type == :dir
         | 
| 74 | 
            +
                    if tokenizer.look_next_token == nil
         | 
| 75 | 
            +
                      add_this_dir_tag
         | 
| 76 | 
            +
                    elsif next_wildcard_extension? or next_filename?
         | 
| 77 | 
            +
                      add_this_dir_tag
         | 
| 78 | 
            +
                    end
         | 
| 79 | 
            +
                  end
         | 
| 80 | 
            +
                end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                def add_double_wildcard_tag token
         | 
| 83 | 
            +
                  # Double wildcard do nothing
         | 
| 84 | 
            +
                end
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                def add_wildcard_tag wildcard
         | 
| 87 | 
            +
                  if tokenizer.look_next_token.nil? or 
         | 
| 88 | 
            +
                      tokenizer.look_next_token.type == :separator
         | 
| 89 | 
            +
                    xml.gsub! PLACEHOLDER, "<match:sub-dirs-only value=\"Sub-directories Only\">#{PLACEHOLDER}</match:sub-dirs-only>"
         | 
| 90 | 
            +
                  end
         | 
| 91 | 
            +
                end
         | 
| 92 | 
            +
             | 
| 93 | 
            +
              end
         | 
| 94 | 
            +
            end
         | 
    
        data/lib/akamai_api/version.rb
    CHANGED
    
    
| @@ -0,0 +1,32 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            def open_expected_file( filename )
         | 
| 4 | 
            +
              content = File.open(File.dirname(__FILE__) + "/../../fixtures/eccu/parser/#{filename}", "r").read
         | 
| 5 | 
            +
              strip_content content
         | 
| 6 | 
            +
            end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            def strip_content( xml )
         | 
| 9 | 
            +
              xml.gsub(/(\n|\t|\r)/, " ").gsub(/>\s*</, "><").strip
         | 
| 10 | 
            +
            end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            describe 'Some example of input -> output' do
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              tests = {
         | 
| 15 | 
            +
                "foo/"               => "this_dir_only.xml",
         | 
| 16 | 
            +
                "foo/**"             => "this_dir_recursive.xml",
         | 
| 17 | 
            +
                "foo/*"              => "sub_dirs.xml",
         | 
| 18 | 
            +
                "foo/*/"             => "sub_dirs.xml",
         | 
| 19 | 
            +
                "foo/bar.txt"        => "dir_with_filename.xml",
         | 
| 20 | 
            +
                "eccu_test/**/*.txt" => "recursive_extension.xml",
         | 
| 21 | 
            +
                "eccu_test/*/*.txt"  => "only_sub_dirs_extension.xml",
         | 
| 22 | 
            +
                "eccu_test/*.txt"    => "dir_with_extension.xml",
         | 
| 23 | 
            +
              }
         | 
| 24 | 
            +
             | 
| 25 | 
            +
              tests.each do |expression, file|
         | 
| 26 | 
            +
                context expression do
         | 
| 27 | 
            +
                  let(:parser){ AkamaiApi::ECCUParser.new expression }
         | 
| 28 | 
            +
                  it{ expect( strip_content( parser.xml ) ).to eq( open_expected_file(file) ) }
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
            end
         | 
| @@ -0,0 +1,10 @@ | |
| 1 | 
            +
            <?xml version="1.0"?>
         | 
| 2 | 
            +
            <eccu>
         | 
| 3 | 
            +
              <match:recursive-dirs value="foo">
         | 
| 4 | 
            +
                <match:this-dir value="This Directory Only">
         | 
| 5 | 
            +
                  <match:filename value="bar.txt" nocase="off">
         | 
| 6 | 
            +
                    <revalidate>now</revalidate>
         | 
| 7 | 
            +
                  </match:filename>
         | 
| 8 | 
            +
                </match:this-dir>
         | 
| 9 | 
            +
              </match:recursive-dirs>
         | 
| 10 | 
            +
            </eccu>
         | 
| @@ -0,0 +1,85 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module AkamaiApi::ECCU
         | 
| 4 | 
            +
              describe Tokenizer do
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                describe '.tokenize' do
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                  context 'with empty expression' do
         | 
| 9 | 
            +
                    let(:tokenizer) { Tokenizer.new "" }
         | 
| 10 | 
            +
                    it 'return 0 tokens' do
         | 
| 11 | 
            +
                      expect( tokenizer.tokens.size ).to equal 0
         | 
| 12 | 
            +
                    end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                    it '.current_token return nil' do
         | 
| 15 | 
            +
                      expect( tokenizer.current_token ).to be_nil
         | 
| 16 | 
            +
                    end
         | 
| 17 | 
            +
                    it '.look_next_token return nil' do
         | 
| 18 | 
            +
                      expect( tokenizer.look_next_token ).to be_nil
         | 
| 19 | 
            +
                    end
         | 
| 20 | 
            +
                    it '.next_token return nil' do
         | 
| 21 | 
            +
                      expect( tokenizer.next_token ).to be_nil
         | 
| 22 | 
            +
                    end
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                  context 'with correct expression' do
         | 
| 26 | 
            +
                    let(:tokenizer) { Tokenizer.new "foo/bar/**/*.png" }
         | 
| 27 | 
            +
                    it 'return 8 tokens' do
         | 
| 28 | 
            +
                      expect(tokenizer.tokens.size).to equal 8
         | 
| 29 | 
            +
                    end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                    it 'and all tokens have the correct type' do
         | 
| 32 | 
            +
                      expect( tokenizer.tokens[0].type ).to equal :dir
         | 
| 33 | 
            +
                      expect( tokenizer.tokens[1].type ).to equal :separator
         | 
| 34 | 
            +
                      expect( tokenizer.tokens[2].type ).to equal :dir
         | 
| 35 | 
            +
                      expect( tokenizer.tokens[3].type ).to equal :separator
         | 
| 36 | 
            +
                      expect( tokenizer.tokens[4].type ).to equal :double_wildcard
         | 
| 37 | 
            +
                      expect( tokenizer.tokens[5].type ).to equal :separator
         | 
| 38 | 
            +
                      expect( tokenizer.tokens[6].type ).to equal :wildcard
         | 
| 39 | 
            +
                      expect( tokenizer.tokens[7].type ).to equal :extension
         | 
| 40 | 
            +
                    end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                    it '.current_token return nil initially' do
         | 
| 43 | 
            +
                      expect( tokenizer.current_token ).to be_nil
         | 
| 44 | 
            +
                    end
         | 
| 45 | 
            +
                    it '.current_token return a Token object after call .next_token' do
         | 
| 46 | 
            +
                      tokenizer.next_token
         | 
| 47 | 
            +
                      expect( tokenizer.current_token.class.name ).to eq "AkamaiApi::ECCU::Token"
         | 
| 48 | 
            +
                    end
         | 
| 49 | 
            +
                    it '.next_token return a Token object' do
         | 
| 50 | 
            +
                      expect( tokenizer.next_token.class.name ).to eq "AkamaiApi::ECCU::Token"
         | 
| 51 | 
            +
                    end
         | 
| 52 | 
            +
                    it '.look_next_token return a Token object' do
         | 
| 53 | 
            +
                      expect( tokenizer.look_next_token.class.name ).to eq "AkamaiApi::ECCU::Token"
         | 
| 54 | 
            +
                    end
         | 
| 55 | 
            +
                    it '.look_next_token after all token cycles return nil' do
         | 
| 56 | 
            +
                      tokenizer.tokens.size.times do
         | 
| 57 | 
            +
                        tokenizer.next_token
         | 
| 58 | 
            +
                      end
         | 
| 59 | 
            +
                      expect( tokenizer.look_next_token ).to be_nil
         | 
| 60 | 
            +
                    end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                    context 'expression not tokenizable' do
         | 
| 63 | 
            +
                      it { expect{ Tokenizer.new('foo/***') }.to raise_error }
         | 
| 64 | 
            +
                    end
         | 
| 65 | 
            +
                  end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                  context 'last token is a :filename' do
         | 
| 68 | 
            +
                    let(:tokenizer) { Tokenizer.new "foo/bar/**/test.png" }
         | 
| 69 | 
            +
                    it { expect( tokenizer.tokens.last.type ).to equal :filename }
         | 
| 70 | 
            +
                  end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                  context 'single word is a :filename' do
         | 
| 73 | 
            +
                    let(:tokenizer) { Tokenizer.new "foo" }
         | 
| 74 | 
            +
                    it { expect( tokenizer.tokens.first.type ).to equal :filename }
         | 
| 75 | 
            +
                  end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                  context 'single word with end / is a :dir' do
         | 
| 78 | 
            +
                    let(:tokenizer) { Tokenizer.new "foo/" }
         | 
| 79 | 
            +
                    it { expect( tokenizer.tokens.first.type ).to equal :dir }
         | 
| 80 | 
            +
                  end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                end
         | 
| 83 | 
            +
             | 
| 84 | 
            +
              end
         | 
| 85 | 
            +
            end
         | 
| @@ -0,0 +1,37 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module AkamaiApi
         | 
| 4 | 
            +
              describe ECCUParser do
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                describe 'initialize' do
         | 
| 7 | 
            +
                  context 'create tokenizer' do
         | 
| 8 | 
            +
                    let(:parser){ ECCUParser.new "foo/bar/*.png" }
         | 
| 9 | 
            +
                    it{ expect( parser.tokenizer.class.name ).to eq( "AkamaiApi::ECCU::Tokenizer" ) }
         | 
| 10 | 
            +
                  end
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                describe 'raises' do
         | 
| 14 | 
            +
                  context 'error on empty string' do
         | 
| 15 | 
            +
                    let(:parser){ ECCUParser.new "" }
         | 
| 16 | 
            +
                    it { expect{ parser.xml }.to raise_error "Expression can't be empty" }
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
                  context '* as not allowed extension' do
         | 
| 19 | 
            +
                    let(:parser){ ECCUParser.new "foo/*.*" }
         | 
| 20 | 
            +
                    it { expect{ parser.xml }.to raise_error }
         | 
| 21 | 
            +
                  end
         | 
| 22 | 
            +
                  context '. as not allowed dir' do
         | 
| 23 | 
            +
                    let(:parser){ ECCUParser.new "./test.png" }
         | 
| 24 | 
            +
                    it { expect{ parser.xml }.to raise_error }
         | 
| 25 | 
            +
                  end
         | 
| 26 | 
            +
                  context '.. as not allowed dir' do
         | 
| 27 | 
            +
                    let(:parser){ ECCUParser.new "../test.png" }
         | 
| 28 | 
            +
                    it { expect{ parser.xml }.to raise_error }
         | 
| 29 | 
            +
                  end
         | 
| 30 | 
            +
                  context 'Extension will be the last element ' do
         | 
| 31 | 
            +
                    let(:parser){ ECCUParser.new "foo/*.png/" }
         | 
| 32 | 
            +
                    it { expect{ parser.xml }.to raise_error "Extension will be the last element" }
         | 
| 33 | 
            +
                  end
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
              end
         | 
| 37 | 
            +
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: akamai_api
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.4.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Nicola Racco
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2015-05- | 
| 11 | 
            +
            date: 2015-05-12 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: httparty
         | 
| @@ -205,7 +205,10 @@ files: | |
| 205 205 | 
             
            - lib/akamai_api/eccu/not_found.rb
         | 
| 206 206 | 
             
            - lib/akamai_api/eccu/publish_request.rb
         | 
| 207 207 | 
             
            - lib/akamai_api/eccu/soap_body.rb
         | 
| 208 | 
            +
            - lib/akamai_api/eccu/token.rb
         | 
| 209 | 
            +
            - lib/akamai_api/eccu/tokenizer.rb
         | 
| 208 210 | 
             
            - lib/akamai_api/eccu/update_attribute_request.rb
         | 
| 211 | 
            +
            - lib/akamai_api/eccu_parser.rb
         | 
| 209 212 | 
             
            - lib/akamai_api/eccu_request.rb
         | 
| 210 213 | 
             
            - lib/akamai_api/error.rb
         | 
| 211 214 | 
             
            - lib/akamai_api/unauthorized.rb
         | 
| @@ -216,6 +219,7 @@ files: | |
| 216 219 | 
             
            - spec/features/eccu/destroy_spec.rb
         | 
| 217 220 | 
             
            - spec/features/eccu/find_request_spec.rb
         | 
| 218 221 | 
             
            - spec/features/eccu/list_request_spec.rb
         | 
| 222 | 
            +
            - spec/features/eccu/parser_integration_spec.rb
         | 
| 219 223 | 
             
            - spec/features/eccu/publish_request_spec.rb
         | 
| 220 224 | 
             
            - spec/features/eccu/update_email_spec.rb
         | 
| 221 225 | 
             
            - spec/features/eccu/update_notes_spec.rb
         | 
| @@ -223,6 +227,13 @@ files: | |
| 223 227 | 
             
            - spec/fixtures/eccu/delete/successful.xml
         | 
| 224 228 | 
             
            - spec/fixtures/eccu/get_ids/successful.xml
         | 
| 225 229 | 
             
            - spec/fixtures/eccu/get_info/successful.xml
         | 
| 230 | 
            +
            - spec/fixtures/eccu/parser/dir_with_extension.xml
         | 
| 231 | 
            +
            - spec/fixtures/eccu/parser/dir_with_filename.xml
         | 
| 232 | 
            +
            - spec/fixtures/eccu/parser/only_sub_dirs_extension.xml
         | 
| 233 | 
            +
            - spec/fixtures/eccu/parser/recursive_extension.xml
         | 
| 234 | 
            +
            - spec/fixtures/eccu/parser/sub_dirs.xml
         | 
| 235 | 
            +
            - spec/fixtures/eccu/parser/this_dir_only.xml
         | 
| 236 | 
            +
            - spec/fixtures/eccu/parser/this_dir_recursive.xml
         | 
| 226 237 | 
             
            - spec/fixtures/eccu/set_notes/successful.xml
         | 
| 227 238 | 
             
            - spec/fixtures/eccu/set_status_change_email/fault.xml
         | 
| 228 239 | 
             
            - spec/fixtures/eccu/set_status_change_email/successful.xml
         | 
| @@ -246,7 +257,9 @@ files: | |
| 246 257 | 
             
            - spec/lib/akamai_api/eccu/list_request_spec.rb
         | 
| 247 258 | 
             
            - spec/lib/akamai_api/eccu/publish_request_spec.rb
         | 
| 248 259 | 
             
            - spec/lib/akamai_api/eccu/soap_body_spec.rb
         | 
| 260 | 
            +
            - spec/lib/akamai_api/eccu/tokenizer_spec.rb
         | 
| 249 261 | 
             
            - spec/lib/akamai_api/eccu/update_attribute_request_spec.rb
         | 
| 262 | 
            +
            - spec/lib/akamai_api/eccu_parser_spec.rb
         | 
| 250 263 | 
             
            - spec/lib/akamai_api/eccu_request_spec.rb
         | 
| 251 264 | 
             
            - spec/spec_helper.rb
         | 
| 252 265 | 
             
            - wsdls/ccuapi.wsdl
         | 
| @@ -293,6 +306,7 @@ test_files: | |
| 293 306 | 
             
            - spec/features/eccu/destroy_spec.rb
         | 
| 294 307 | 
             
            - spec/features/eccu/find_request_spec.rb
         | 
| 295 308 | 
             
            - spec/features/eccu/list_request_spec.rb
         | 
| 309 | 
            +
            - spec/features/eccu/parser_integration_spec.rb
         | 
| 296 310 | 
             
            - spec/features/eccu/publish_request_spec.rb
         | 
| 297 311 | 
             
            - spec/features/eccu/update_email_spec.rb
         | 
| 298 312 | 
             
            - spec/features/eccu/update_notes_spec.rb
         | 
| @@ -300,6 +314,13 @@ test_files: | |
| 300 314 | 
             
            - spec/fixtures/eccu/delete/successful.xml
         | 
| 301 315 | 
             
            - spec/fixtures/eccu/get_ids/successful.xml
         | 
| 302 316 | 
             
            - spec/fixtures/eccu/get_info/successful.xml
         | 
| 317 | 
            +
            - spec/fixtures/eccu/parser/dir_with_extension.xml
         | 
| 318 | 
            +
            - spec/fixtures/eccu/parser/dir_with_filename.xml
         | 
| 319 | 
            +
            - spec/fixtures/eccu/parser/only_sub_dirs_extension.xml
         | 
| 320 | 
            +
            - spec/fixtures/eccu/parser/recursive_extension.xml
         | 
| 321 | 
            +
            - spec/fixtures/eccu/parser/sub_dirs.xml
         | 
| 322 | 
            +
            - spec/fixtures/eccu/parser/this_dir_only.xml
         | 
| 323 | 
            +
            - spec/fixtures/eccu/parser/this_dir_recursive.xml
         | 
| 303 324 | 
             
            - spec/fixtures/eccu/set_notes/successful.xml
         | 
| 304 325 | 
             
            - spec/fixtures/eccu/set_status_change_email/fault.xml
         | 
| 305 326 | 
             
            - spec/fixtures/eccu/set_status_change_email/successful.xml
         | 
| @@ -323,7 +344,9 @@ test_files: | |
| 323 344 | 
             
            - spec/lib/akamai_api/eccu/list_request_spec.rb
         | 
| 324 345 | 
             
            - spec/lib/akamai_api/eccu/publish_request_spec.rb
         | 
| 325 346 | 
             
            - spec/lib/akamai_api/eccu/soap_body_spec.rb
         | 
| 347 | 
            +
            - spec/lib/akamai_api/eccu/tokenizer_spec.rb
         | 
| 326 348 | 
             
            - spec/lib/akamai_api/eccu/update_attribute_request_spec.rb
         | 
| 349 | 
            +
            - spec/lib/akamai_api/eccu_parser_spec.rb
         | 
| 327 350 | 
             
            - spec/lib/akamai_api/eccu_request_spec.rb
         | 
| 328 351 | 
             
            - spec/spec_helper.rb
         | 
| 329 352 | 
             
            has_rdoc: 
         |