Skip to content

Instantly share code, notes, and snippets.

@satyr
Last active May 12, 2016 00:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save satyr/29674 to your computer and use it in GitHub Desktop.
Save satyr/29674 to your computer and use it in GitHub Desktop.
amazon.co.jp (Ubiquity 0.5.4+)
var Name = 'jamazon',
Jamazon = 'http://www.amazon.co.jp/',
ItemMax = 35,
Logo = '<a class="logo" href="'+ Jamazon +'" accesskey="0">'
+ '<img border="0" width="126" height="28" align="middle" src="'
+ 'http://g-ecx.images-amazon.com/images/G/09/gno/images/general/'
+ 'navAmazonLogoFooter._V28243234_.gif'
+ '"/></a>',
Base = '<style>\
.head {padding:0 0.4em}\
.results, .features {margin:0; padding:0; list-style:none}\
.item img {float:right; border:none; margin:0 0.2em 0.2em 0}\
.query, .num, .price {font-weight:bold}\
.num, li {margin:0 0 0.2em}\
.price, .author, .label, .features {font-size:92%}\
.query::before, .query::after {content:\'"\'}\
.num::before {content:"Total: "}\
.num {float:right}\
.price {white-space:nowrap}\
.features li:before {content:"\\2022 "}\
.button {padding:0; border-width:1px; font:bold 92% monospace}\
.item {clear:both}\
.error {font-style:oblique; line-height:1.8}\
.loading {opacity:0.9}\
.loading + .logo {opacity:0.4}\
.error + .logo {opacity:0.7}\
</style>'+
'<div class='+ Name +'><div id='+ Name +'></div>'+ Logo +'</div>',
Categories = {
'All すべて': ['All', 'aps', ['u', 'default']],
'Apparel 服&ファッション小物': ['Apparel', 'apparel'],
'Automotive カー&バイク用品': ['Automotive', 'automotive'],
'Baby ベビー&マタニティ': ['Baby', 'baby'],
'Beauty コスメ': ['Beauty', 'beauty'],
'Books 和書': ['Books', 'stripbooks'],
'Classical クラシック音楽': ['Classical', 'classical'],
'DVD DVD': ['DVD', 'dvd'],
'Electronics 家電&カメラ': ['Electronics', 'electronics'],
'ForeignBooks 洋書': ['ForeignBooks', 'english-books'],
'Grocery 食品&飲料': ['Grocery', 'food-beverage'],
'HealthPersonalCare ヘルス&ビューティー': ['HealthPersonalCare', 'hpc'],
'Hobbies ホビー': ['Hobbies', 'hobby'],
'Jewelry ジュエリー': ['Jewelry', 'jewelry'],
'KindleStore Kindleストア': ['KindleStore', 'digital-text'],
'Kitchen ホーム&キッチン': ['Kitchen', 'kitchen'],
'MobileApps Androidアプリ': ['MobileApps', 'mobile-apps'],
'MP3Downloads MP3ミュージック': ['MP3Downloads', 'digital-music'],
'Music ミュージック': ['Music', 'popular'],
'MusicalInstruments 楽器': ['MusicalInstruments', 'mi'],
'OfficeProducts 文房具・オフィス用品': ['OfficeProducts', 'office-products'],
'Shoes&Bags シューズ&バッグ': ['Shoes', 'shoes'],
'Software PCソフト': ['Software', 'software'],
'SportingGoods スポーツ&アウトドア': ['SportingGoods', 'sporting'],
'Toys おもちゃ': ['Toys', 'toys'],
'VHS ビデオ': ['VHS', 'vhs'],
'VideoGames TVゲーム': ['VideoGames', 'videogames'],
'Watches 時計': ['Watches', 'watch'],
},
CategoList = (function(){
var xml = '<ul id="jamazon-categories" style="-moz-column-count:2">'
for(var [c, [k,, x]] in new Iterator(Categories))
xml += '<li class="'+ k +'">'
+ [x && '<'+ x[0] +' title="'+ x[1] +'">']
+ Utils.escapeHtml(c)
+ [x && '</'+ x[0] +'>']
+ '</li>'
return xml +'</ul>'
}()),
H = Utils.escapeHtml
function ng(c){
c.textContent = Array.slice(arguments, 1).join(' ');
c.className = 'error';
}
function joinq($_, sel, delim){
return $_.find(sel).map((_, x) => x.textContent).get().join(delim || ' ')
}
function onclick(e){
var b = e.target;
if(b.type !== "button") return;
e.preventDefault();
b.disabled = true;
Utils.openUrlInBrowser(b.title);
}
var amazEnc = (str) =>
encodeURIComponent(str).replace(/[!\'()*]+/g, (s) => escape(s, 0))
function amazSig(endp, reqp, params){
var ps = $.extend({
Timestamp: new Date().toISOString().slice(0, -5) +'Z',
AssociateTag: 'matyr-22',
AWSAccessKeyId: '0SP5F78NM10ZVNWWG482',
SignatureMethod: 'HmacSHA256',
SignatureVersion: 2,
}, params);
var sps = Object.keys(ps).map(k => k +'='+ amazEnc(ps[k])).sort().join('&');
return ('http://'+ endp + reqp +'?'+ sps +'&Signature='+
amazEnc(Utils.signHMAC(
'SHA256', 'DlSRkBtC3WDAMjA5fVJO4Fg04omvXYVXs49oNPlo',
['GET', endp, reqp, sps].join('\n'))));
}
function qst(lmn, slc){
var child = lmn && lmn.querySelector(slc)
return child ? child.textContent : ''
}
var qsat = (lmn, slc) =>
Array.map(lmn.querySelectorAll(slc), x => x.textContent)
CmdUtils.CreateCommand({
names: [Name, 'amazon.co.jp'],
icon: Jamazon +'favicon.ico',
description: Logo,
help: '<h3>Categories カテゴリーリスト</h3>'+ CategoList,
arguments: {
object: noun_arb_text,
format: CmdUtils.NounType('category カテゴリー', Categories, '^All '),
},
execute: function jam_execute({object: {text}, format: {data}}){
Utils.openUrlInBrowser(
(text = text.trim())
? Jamazon +'s/?tag=matyr-22&__mk_ja_JP='+
'%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&search-alias='+ data[1] +
'&field-keywords='+ encodeURIComponent(text)
: Jamazon);
},
preview: function jam_preview(pb, {object: {text, html}, format: {data}}){
do var cn = pb.ownerDocument.getElementById(Name);
while(!cn && (pb.innerHTML = Base));
if(!text){
cn.innerHTML = CategoList;
cn.querySelector('.'+ data[0]).style.fontWeight = 'bold';
return;
}
cn.className = 'loading';
CmdUtils.previewAjax(pb, {
url: amazSig('xml-jp.amznxslt.com', '/onca/xml', {
Service: 'AWSECommerceService',
Version: "2011-08-01",
Operation: 'ItemSearch',
Condition: 'All',
Merchant: 'All',
ResponseGroup: 'ItemAttributes,Images,Offers',
AssociateTag: "matyr-22",
SearchIndex: data[0],
Keywords: text,
}),
dataType: 'xml',
success: function jam_success(xml){
var em = xml.querySelector('Error > Message')
if(em) return ng(cn, em.textContent)
var ol = '<ol class=results>', i = 1
for(let it of Array.slice(xml.querySelectorAll('Items > Item'))){
let img = it.querySelector('SmallImage')
, attr = it.querySelector('ItemAttributes')
, price = it.querySelector('OfferSummary > LowestNewPrice')
|| attr.querySelector('ListPrice')
, label = qst(attr, 'Label')
, key = i.toString(ItemMax + 1).toUpperCase()
, author = qsat(attr, 'Author' ).join(', ')
, feats = qsat(attr, 'Feature')
let hu = H(qst(it, 'DetailPageURL'))
, li = '<li class=item><input type=button class=button'
+ ' value='+ key +' accesskey='+ key
+ ' title="'+ hu +'">'
+ ' <a href="'+ hu +'">'
+ '<span class=title>'+ H(qst(attr, 'Title')) +'</span>'
+ '</a>'
+ ' <span class=price>'
+ H(qst(price, 'FormattedPrice')) +'</span>'
if(img) li += '<img src="' + H(qst(img, 'URL' ))
+ '" width="' + qst(img, 'Width' )
+ '" height="' + qst(img, 'Height') +'">'
if(author)
li += '<div class=author>'+ H(author) +'</div>'
if(label)
li += '<div class=label>'+ H(label) +'</div>'
if(feats.length)
li += feats.reduce((ul, f) => ul +'<li>'+ f,
'<ul class=features>') + '</ul>'
ol += li
if(++i > ItemMax) break
}
cn.innerHTML = '<div class=head>'
+ '<span class=query>'+ html +'</span>'
+ '<span class=num>'
+ qst(xml, 'Items > TotalResults') +'</span>'
+ '</div>'
+ ol + '</ol><br clear=all>'
cn.addEventListener('click', onclick, false)
cn.className = ''
cn.ownerDocument.defaultView.scrollTo(0, 0)
},
error: function jam_error(x, s){
if(x.status) ng(cn, x.status, x.statusText, '('+ s +')')
},
});
},
author: {
name: 'satyr', email: 'murky.satyr\x40gmail.com',
homepage: 'http://satyr.github.io',
},
license: 'MIT',
homepage: 'http://d.hatena.ne.jp/murky-satyr/20081129/1227893155',
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment