-rw-r--r-- | content/fireflix-panel.xul | 1 | ||||
-rw-r--r-- | content/fireflix.js | 12 | ||||
-rw-r--r-- | content/flickr.js | 4 |
3 files changed, 13 insertions, 4 deletions
diff --git a/content/fireflix-panel.xul b/content/fireflix-panel.xul index b2ca7dc..af92d22 100644 --- a/content/fireflix-panel.xul +++ b/content/fireflix-panel.xul @@ -139,96 +139,97 @@ accesskey="t" /> <checkbox id="search_mine" label="&panel.search.mode.mine.label;" checked="true" accesskey="m"/> <spacer flex="1"/> <button class="lean" command="cmd_search"/> </hbox> </groupbox> <hbox> <button class="lean" command="cmd_search_prev_page"/> <spacer flex="1"/> <label id="search_page" hidden="true"/> <spacer flex="1"/> <button class="lean" command="cmd_search_next_page"/> </hbox> <tree id="searchresults" rows="2" flex="1" onselect="fireflix.foundphotos.on_select()" ondblclick="fireflix.foundphotos.on_cmd_open(event)" onkeypress="if(event.keyCode==event.DOM_VK_RETURN) fireflix.foundphotos.on_cmd_open(event)"> <treecols> <treecol id="sr_title" label="&panel.search.col.title.label;" flex="2" crop="end" align="start" /> </treecols> <treechildren/> </tree> <groupbox id="searchresult_props" orient="horizontal" hidden="true"> <vbox width="100" pack="center"> <hbox pack="center"> <image id="search_photo" ondblclick="fireflix.foundphotos.on_cmd_open(event)"/> </hbox> </vbox> <vbox flex="1"> <label id="searchresult_title" crop="end"/> <hbox flex="1" pack="center"> <div flex="1" id="searchresult_description" xmlns="http://www.w3.org/1999/xhtml"/> </hbox> <hbox pack="end"> <button command="cmd_search_open"/> </hbox> </vbox> </groupbox> </vbox> </tabpanel> <tabpanel id="tabpanel_sets" flex="1" onkeypress="if(event.keyCode==event.DOM_VK_RETURN) document.getElementById('setphotos').focus()"> <vbox flex="1"> <tree id="setslist" rows="2" onselect="fireflix.photosets.on_select()" flex="1" context="sets_menu" + ondblclick="fireflix.photosets.on_cmd_open_in_flickr(event)" > <treecols> <treecol id="sl_name" label="&panel.sets.name.label;" flex="4" crop="end" align="start" tooltiptext="&panel.sets.name.tip;"/> <splitter class="tree-splitter" /> <treecol id="sl_photos" label="&panel.sets.photos.label;" flex="1" align="end" tooltiptext="&panel.sets.photos.tip;" /> </treecols> <treechildren/> </tree> <hbox> <button command="cmd_refresh_sets" /> <button command="cmd_set_props" /> </hbox> <tree id="setphotos" rows="2" onselect="fireflix.photoset.on_select()" flex="1" ondblclick="fireflix.photoset.on_cmd_open(event)" onkeypress="if(event.keyCode==event.DOM_VK_RETURN) fireflix.photoset.on_cmd_open(event)"> <treecols> <treecol id="sp_title" label="&panel.setphotos.title.label;" flex="1" crop="end" align="start" tooltiptext="&panel.setphotos.title.tip;" /> <splitter class="tree-splitter" /> <treecol id="sp_taken" label="&panel.setphotos.taken.label;" crop="end" align="start" tooltiptext="&panel.setphotos.taken.tip;" hidden="true" /> <treecol id="sp_upload" label="&panel.setphotos.upload.label;" crop="end" align="start" tooltiptext="&panel.setphotos.upload.tip;" hidden="true" /> </treecols> <treechildren/> </tree> <groupbox id="set_photo_props" orient="horizontal"> <vbox width="100" pack="center"> <hbox pack="center"> <image id="set_photo" hidden="true" ondblclick="fireflix.photoset.on_cmd_open(event)" /> </hbox> </vbox> <spacer flex="1"/> </groupbox> </vbox> </tabpanel> <tabpanel id="tabpanel_tags"> <listbox id="tagslist" rows="8" flex="1"> <listhead> <listheader label="&panel.tagslist.tag.label;"/> </listhead> <listcols> <listcol flex="1"/> </listcols> </listbox> </tabpanel> <tabpanel id="tabpanel_upload"> <vbox flex="1"> diff --git a/content/fireflix.js b/content/fireflix.js index 24894df..48053c5 100644 --- a/content/fireflix.js +++ b/content/fireflix.js @@ -119,168 +119,172 @@ var fireflix = { getRowProperties: function(r,p) {}, getCellProperties: function(cid,cel,p) {}, getColumnProperties: function(cid,cel,p) { }, cycleHeader: function(cid,e) { }, getParentIndex: function(r) { return -1; }, drop: function(r,o) { }, canDropBeforeAfter: function(r,b) { return false }, importXPR: function(xp) { this.tree.beginUpdateBatch(); this.photos = new Array(); var n; while(n=xp.iterateNext()) { this.photos.push(new Photo(n)); } this.rowCount = this.photos.length; this.tree.endUpdateBatch(); this.selection.clearSelection(); }, load_photos: function(psid) { var _this = this; this.fireflix.flickr.api_call( { method: 'flickr.photosets.getPhotos', auth_token: 'default', photoset_id: psid, extras: 'license,date_upload,date_taken,owner_name,icon_server,original_format,last_update' }, function(xr) { var x = xr.responseXML; var xp = x.evaluate( '/rsp/photoset/photo', x, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null ); _this.importXPR(xp); }, function(x,s,c,m) { _this.fireflix.flickr_failure(x,s,c,m); } ); }, on_select: function() { if(this.selection.count==1) { var p = this.photos[this.selection.currentIndex]; this.set_photo.src = this.fireflix.flickr.get_photo_url(p.server,p.id,p.secret,'t'); this.set_photo.hidden = false; }else{ this.set_photo.hidden = true; } }, on_cmd_open: function(ev) { - if(this.selection.currentIndex<0) - return; + if(this.selection.currentIndex<0) return; var p = this.photos[this.selection.currentIndex]; - if(!p.id) - return; + if(!p.id) return; this.fireflix.openTab(this.fireflix.flickr.make_photo_url(p,'p')); } }, /* photosets treeview */ photosets: { sets: new Array(), fireflix: null, init: function(f) { this.fireflix = f; document.getElementById('setslist').view = this; }, rowCount: 0, getCellText: function(r,c) { var s = this.sets[r]; if(c.id=='sl_name') return s.title; if(c.id=='sl_photos') return s.photos; return c.id; }, setTree: function(t) { this.tree = t }, isContainer: function(r) { return false; }, isSeparator: function(r) { return false; }, isSorted: function() { return false; }, getLevel: function(r) { return 0; }, getImageSrc: function(r,c) { return null }, getRowProperties: function(r,p) {}, getCellProperties: function(cid,cel,p) { }, getColumnProperties: function(cid,cel,p) { }, cycleHeader: function(cid,e) { }, getParentIndex: function(r) { return -1; }, drop: function(r,o) { }, canDropBeforeAfter: function(r,b) { return false }, importXPR: function(xp) { this.tree.beginUpdateBatch(); this.sets = new Array(); var n; while(n=xp.iterateNext()) { this.sets.push(new Photoset(n)); } this.rowCount = this.sets.length; this.tree.endUpdateBatch(); }, refresh_sets: function() { var _this = this; this.fireflix.flickr.api_call( { method: 'flickr.photosets.getList', auth_token: 'default' }, function(xr) { var x = xr.responseXML; var xp = x.evaluate( '/rsp/photosets/photoset', x, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null ); _this.importXPR(xp); }, function(x,s,c,m) { _this.fireflix.flickr_failure(x,s,c,m); } ); }, on_select: function() { if(this.selection.count==1) { this.fireflix.cmd_set_props.setAttribute('disabled','false'); var s = this.sets[this.selection.currentIndex]; this.fireflix.photoset.load_photos(s.id); }else{ this.fireflix.cmd_set_props.setAttribute('disabled','true'); } + }, + on_cmd_open_in_flickr: function(ev) { + if(this.selection.currentIndex<0) return; + var p = this.sets[this.selection.currentIndex]; + if(!p.id) return; + this.fireflix.openTab(this.fireflix.flickr.make_photoset_url(p)); } }, refresh_user_tags: function() { var lb = document.getElementById('tagslist'); var _this = this; this.flickr.api_call( { method: 'flickr.tags.getListUser', auth_token: 'default', }, function(xr) { var x = xr.responseXML; var xp = x.evaluate( '/rsp/who/tags/tag', x, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null ); // TODO: clear list var n; while(n=xp.iterateNext()) { lb.appendItem(n.firstChild.nodeValue); } }, function(x,s,c,m) { _this.flickr_failure(x,s,c,m); } ); }, uploadObserver: { fireflix: null, init: function(f) { this.fireflix = f; }, getSupportedFlavours: function() { var rv = new FlavourSet(); rv.appendFlavour('application/x-moz-file','nsIFile'); rv.appendFlavour('application/x-moz-url'); rv.appendFlavour('text/uri-list'); rv.appendFlavour('text/unicode'); return rv; }, canHandleMultipleItems: true, onDragOver: function(ev,fl,sess) { return true; }, onDrop: function(ev,dd,s) { var ldf = null; for(var i in dd.dataList) { var di = dd.dataList[i]; var dif = di.first; if( diff --git a/content/flickr.js b/content/flickr.js index 75d1a72..b8360c1 100644 --- a/content/flickr.js +++ b/content/flickr.js @@ -226,96 +226,100 @@ Flickr.prototype = { this.user = new Object(); this.user.nsid = this.prefs.getCharPref(this.prefs_root+'.auth_user.nsid'); if(this.prefs.getPrefType(this.prefs_root+'.auth_user.username')!=this.prefs.PREF_STRING) return this._reset_token(); this.user.username = this.prefs.getCharPref(this.prefs_root+'.auth_user.username'); if(this.prefs.getPrefType(this.prefs_root+'.auth_user.fullname')!=this.prefs.PREF_STRING) return this._reset_token(); this.user.fullname = this.prefs.getCharPref(this.prefs_root+'.auth_user.fullname'); }catch(e) { return this._reset_token(); } return true; }, reset_token: function() { this._reset_token(); this.save_token(); }, get_photo_url: function(ser,id,sec,sfx,ext) { var rv = this.photo_url + ser + '/' + id + '_' + sec; if(sfx && sfx!='_') rv += '_'+sfx; rv += ext?'.'+ext:'.jpg'; return rv; }, get_image_url: function(o,sfx) { return this.get_photo_url( o.server, (o instanceof Photoset)? o.primary : o.id, o.secret, sfx, (sfx=='o')?o.originalformat:null ); }, get_photo_page_url: function(p) { if(p instanceof Photo) { // TODO: track photoset and user owner id from there? // The approach below is sheerly wrong. var o = this.user.nsid; if(p.owner && p.owner.nsid) o = p.owner.nsid; var rv = this.photos_url + o +'/' + p.id; return rv; }else // TODO: take owner into account? return this.photos_url + this.user.nsid + '/' + p; }, make_photo_url: function(p,sfx) { if(sfx=='p') return this.get_photo_page_url(p); else return this.get_image_url(p,sfx); }, + make_photoset_url: function(ps) { + // TODO: allow for using someone else's photoset? + return this.photos_url+this.user.nsid+'/sets/'+ps.id; + }, upload_file: function(f,fa,on_success,on_failure) { try { var fi = Components.classes["@mozilla.org/file/local;1"] .createInstance(Components.interfaces.nsILocalFile); fi.initWithPath( f ); var st = Components.classes["@mozilla.org/network/file-input-stream;1"] .createInstance(Components.interfaces.nsIFileInputStream); st.init(fi,0x01,00004,null); var bis = Components.classes["@mozilla.org/binaryinputstream;1"] .createInstance(Components.interfaces.nsIBinaryInputStream); bis.setInputStream(st); // allocate and initialize temp storage string var pbs = Components.classes["@mozilla.org/storagestream;1"] .createInstance(Components.interfaces.nsIStorageStream); pbs.init(1024,10000000,null); // create output stream var pbos = pbs.getOutputStream(0); // and a binaryoutputstream interface var pbbos = Components.classes["@mozilla.org/binaryoutputstream;1"] .createInstance(Components.interfaces.nsIBinaryOutputStream); pbbos.setOutputStream(pbos); /* create POST body */ var boundarytoken = 'kadaroloongazaduviaxamma'; var boundary = '--'+boundarytoken; var b = ''; var parms = { api_key: this.api_key, auth_token: this.token }; for(var p in fa) parms[p] = fa[p]; var pns = new Array(); for(var p in parms) pns.push(p); var pstr = ''; for(var p in pns.sort()) { var pn = pns[p]; pstr += pn+parms[pn]; b += boundary+'\nContent-Disposition: form-data; name="'+pn+'"\n\n'+toutf8(parms[pn])+'\n'; } b += boundary+'\nContent-Disposition: form-data; name="api_sig"\n\n'+this.api_sig(pstr)+'\n'; b += boundary+'\nContent-Disposition: form-data; name="photo"; filename="'+f+'"\nContent-Type: image/jpeg\nContent-Transfer-Encoding: binary\n\n'; pbbos.writeBytes(b,b.length); var bisbytes = bis.available(); pbbos.writeBytes(bis.readBytes(bisbytes),bisbytes); pbbos.writeBytes('\n'+boundary+'--',3+boundary.length); bis.close(); st.close(); pbbos.close(); pbos.close(); |