├── README.md ├── _amazon-tag.scss ├── amazon_tag.rb └── locale ├── en.yml └── ja.yml /README.md: -------------------------------------------------------------------------------- 1 | # Amazon Plugin for Jekyll 2 | This plugin is inspired [Amazon Liquid Filters for jekyll](http://base0.net/posts/amazon-liquid-filters-for-jekyll/). 3 | 4 | ## How to install 5 | 6 | ### Get dependency package 7 | 8 | cd /path/to/jekyll 9 | 10 | vi Gemfile 11 | 12 | + gem 'amazon-ecs' 13 | + gem 'i18n' 14 | + gem 'jekyll' 15 | 16 | bundle install --path vendor/bundle 17 | 18 | 19 | ### Get amazon_tag.rb 20 | 21 | cd plugins 22 | wget https://raw.github.com/longkey1/jekyll-amazon-plugin/master/amazon_tag.rb 23 | 24 | 25 | or by git-submodule 26 | 27 | cd /path/to/jekyll 28 | git submodule add git://github.com/longkey1/jekyll-amazon-plugin.git _plugins/amazon 29 | 30 | 31 | ### Configuring 32 | 33 | vi /path/to/jekyll/_config.yml 34 | 35 | + # Amazon plugin 36 | + amazon_access_key_id: 'your access key id' 37 | + amazon_secret_key: 'your secret key' 38 | + amazon_associate_tag: 'your associate' 39 | + amazon_cache: false # or true 40 | + amazon_cache_dir: '.amazon-cache' # default '.amazon-cache' 41 | + amazon_country: 'jp' # default 'us' 42 | + amazon_locale: 'ja' # default 'en' 43 | 44 | 45 | ## Usage 46 | 47 | ### Syntax: 48 | 49 | {% amazon [type] [asin] %} 50 | 51 | type: text, small_image, medium_image, large_image, title, detail, image 52 | 53 | ### Usage Examples: 54 | 55 | {% amazon large_image 4873113946 %} 56 | {% amazon detail 4873113946 %} 57 | 58 | ### Type detail: 59 | 60 | [type] detail display item with object layouted by css. 61 | If you want to use this option move `_amazon-tag.scss` file to `/path/to/jekyll/_sass` directory. 62 | 63 | mv _amazon_tag.scss /path/to/jekyll/sass 64 | 65 | vi main.scss 66 | 67 | + @import "amazon-tag"; 68 | 69 | jekyll build 70 | -------------------------------------------------------------------------------- /_amazon-tag.scss: -------------------------------------------------------------------------------- 1 | .amazon_tag { 2 | padding: 10px; 3 | border: 1px solid #E3E3E3; 4 | overflow : hidden; 5 | background-color: rgba(246, 246, 246, 0.5); 6 | margin-bottom: 1em; 7 | 8 | img { 9 | width: 120px; 10 | vertical-align: middle; 11 | border: 0px none; 12 | padding: 1px; 13 | float: left 14 | } 15 | 16 | p { 17 | line-height: 1.2; 18 | } 19 | 20 | .item_detail{ 21 | padding: 1em; 22 | float: left; 23 | margin-left: 5px; 24 | } 25 | 26 | &:after { 27 | clear: both; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /amazon_tag.rb: -------------------------------------------------------------------------------- 1 | require 'amazon/ecs' 2 | require 'i18n' 3 | 4 | module Jekyll 5 | class AmazonResultCache 6 | def initialize 7 | @result_cache = {} 8 | 9 | @cache = false 10 | @cache_dir = '.amazon-cache/' 11 | @options = { 12 | :associate_tag => nil, 13 | :AWS_access_key_id => nil, 14 | :AWS_secret_key => nil, 15 | :response_group => 'Images,ItemAttributes,ItemIds', 16 | :country => 'en', 17 | } 18 | end 19 | 20 | @@instance = AmazonResultCache.new 21 | 22 | def self.instance 23 | @@instance 24 | end 25 | 26 | def setup(context) 27 | site = context.registers[:site] 28 | 29 | #cache_dir 30 | @cache = site.config['amazon_cache'] if site.config['amazon_cache'] 31 | @cache_dir = site.config['amazon_cache_dir'].gsub(/\/$/, '') + '/' if site.config['amazon_cache_dir'] 32 | Dir::mkdir(@cache_dir) if File.exists?(@cache_dir) == false 33 | 34 | #options 35 | @options[:associate_tag] = site.config['amazon_associate_tag'] 36 | @options[:AWS_access_key_id] = site.config['amazon_access_key_id'] 37 | @options[:AWS_secret_key] = site.config['amazon_secret_key'] 38 | @options[:country] = site.config['amazon_country'] 39 | 40 | #i18n 41 | locale = 'en' 42 | locale = site.config['amazon_locale'] if site.config['amazon_locale'] 43 | I18n.enforce_available_locales = false 44 | I18n.locale = locale.to_sym 45 | I18n.load_path = [File.expand_path(File.dirname(__FILE__)) + "/locale/#{locale}.yml"] 46 | end 47 | 48 | def item_lookup(asin) 49 | return @result_cache[asin] if @result_cache.has_key?(asin) 50 | return @result_cache[asin] = Marshal.load(File.read(@cache_dir + asin)) if @cache && File.exist?(@cache_dir + asin) 51 | 52 | Amazon::Ecs.options = @options 53 | 54 | recnt = 0 55 | begin 56 | res = Amazon::Ecs.item_search(asin, search_index: 'All') 57 | 58 | #Liquid Exception HTTP Response: 503 Service Unavailable 59 | rescue Amazon::RequestError => e 60 | if /503/ =~ e.message && recnt < 3 61 | sleep 3 62 | recnt += 1 63 | puts asin + ' retry ' + recnt.to_s 64 | retry 65 | else 66 | raise e 67 | end 68 | end 69 | 70 | res.items.each do |item| 71 | element = item.get_element('ItemAttributes') 72 | data = { 73 | :title => item.get('ItemAttributes/Title').to_s.gsub(/ \[Blu-ray\]/, '').gsub(/ \(Ultimate Edition\)/, ''), 74 | :item_page_url => item.get('DetailPageURL').to_s, 75 | :small_image_url => item.get('SmallImage/URL').to_s, 76 | :medium_image_url => item.get('MediumImage/URL').to_s, 77 | :large_image_url => item.get('LargeImage/URL').to_s, 78 | :author => element.get_array('Author').join(', '), 79 | :product_group => element.get('ProductGroup'), 80 | :manufacturer => element.get('Manufacturer'), 81 | :publication_date => element.get('PublicationDate'), 82 | } 83 | @result_cache[asin] = data 84 | open(@cache_dir + asin, 'w'){|f| f.write(Marshal.dump(data))} if @cache 85 | break 86 | end 87 | return @result_cache[asin] 88 | end 89 | 90 | private_class_method :new 91 | end 92 | 93 | class AmazonTag < Liquid::Tag 94 | 95 | def initialize(name, params, token) 96 | super 97 | @params = params 98 | 99 | # make image alias methods for degression 100 | make_image_alias_methods 101 | end 102 | 103 | def render(context) 104 | if @params =~ /(?(text|(small|large|medium)?_?image|detail|title)\s+)(?\S+)/i 105 | type = $~['type'].strip 106 | asin = $~['asin'].strip.gsub(/"|“|”/, '') 107 | else 108 | raise 'parametor error for amazon tag' 109 | end 110 | 111 | AmazonResultCache.instance.setup(context) 112 | item = AmazonResultCache.instance.item_lookup(asin) 113 | 114 | if item.nil? 115 | raise "item data empty asin %s" % [asin] 116 | end 117 | 118 | self.send(type, item) 119 | end 120 | 121 | def title(item) 122 | url = item[:item_page_url] 123 | title = item[:title] 124 | '%s' % [url, title] 125 | end 126 | # for degression 127 | alias text title 128 | 129 | def image(item, size = 'medium') 130 | image_url = item["#{size}_image_url".to_sym] 131 | url = item[:item_page_url] 132 | '' % [url, image_url] 133 | end 134 | 135 | def make_image_alias_methods 136 | for size in ['small', 'medium', 'large'] do 137 | method = "#{size}_image".to_sym 138 | self.class.send(:define_method, method) do |item| 139 | size = __method__.to_s.sub(/_image/, '') 140 | image(item, size) 141 | end 142 | end 143 | end 144 | 145 | def check_param(param) 146 | return nil unless param 147 | return param 148 | end 149 | 150 | def print_product_content(item, max_title_chars = nil) 151 | url = item[:item_page_url] 152 | title = item[:title] 153 | unless max_title_chars.nil? then 154 | title = title[0..max_title_chars] + '...' if title.length > max_title_chars 155 | end 156 | contents = { 157 | author: I18n.t('author') + ':', 158 | publication_date: I18n.t('publication date') + ':', 159 | manufacturer: I18n.t('manufacturer') + ':', 160 | product_group: I18n.t('product group') + ':', 161 | } 162 | res = '%s' % [url, title] 163 | res += '

' 164 | contents.each do |key, value| 165 | res += "#{value}\t#{item[key]}
" if check_param item[key] 166 | end 167 | res += '

' 168 | end 169 | 170 | def detail(item) 171 | res ='
' 172 | res += '' % 173 | [item[:item_page_url], item[:medium_image_url] ] 174 | res += '
' 175 | res += print_product_content item, 40 176 | res += '
' * 2 177 | end 178 | end 179 | end 180 | 181 | Liquid::Template.register_tag('amazon', Jekyll::AmazonTag) 182 | -------------------------------------------------------------------------------- /locale/en.yml: -------------------------------------------------------------------------------- 1 | en: 2 | author: 'Author' 3 | publication date: 'Publication Date' 4 | manufacturer: 'Manufacturer' 5 | product group: 'Product Group' 6 | -------------------------------------------------------------------------------- /locale/ja.yml: -------------------------------------------------------------------------------- 1 | ja: 2 | author: '著者' 3 | publication date: '出版日' 4 | manufacturer: '出版社/メーカー' 5 | product group: 'カテゴリ' 6 | --------------------------------------------------------------------------------