summaryrefslogtreecommitdiffabout
authorMichael Krelin <hacker@klever.net>2006-12-18 18:56:09 (UTC)
committer Michael Krelin <hacker@klever.net>2006-12-18 18:56:09 (UTC)
commit71a2c8a80f3c7a99e893efb32c6bbf5080e16ff1 (patch) (unidiff)
tree1f9051339dee22f5c64206568638675ca9f7636a
parent1838bc18394967371d7a1c00516db5e290f80ea3 (diff)
downloadfireflix-71a2c8a80f3c7a99e893efb32c6bbf5080e16ff1.zip
fireflix-71a2c8a80f3c7a99e893efb32c6bbf5080e16ff1.tar.gz
fireflix-71a2c8a80f3c7a99e893efb32c6bbf5080e16ff1.tar.bz2
doubleclicking files in upload
git-svn-id: http://svn.klever.net/kin/fireflix/trunk@241 fe716a7a-6dde-0310-88d9-d003556173a8
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--content/fireflix-panel.xul3
-rw-r--r--content/fireflix.js17
-rw-r--r--content/flickr.js5
3 files changed, 20 insertions, 5 deletions
diff --git a/content/fireflix-panel.xul b/content/fireflix-panel.xul
index 405804c..8aec0e4 100644
--- a/content/fireflix-panel.xul
+++ b/content/fireflix-panel.xul
@@ -199,97 +199,98 @@
199 <treecol id="sl_name" label="&panel.sets.name.label;" flex="4" crop="end" align="start" tooltiptext="&panel.sets.name.tip;"/> 199 <treecol id="sl_name" label="&panel.sets.name.label;" flex="4" crop="end" align="start" tooltiptext="&panel.sets.name.tip;"/>
200 <splitter class="tree-splitter" /> 200 <splitter class="tree-splitter" />
201 <treecol id="sl_photos" label="&panel.sets.photos.label;" flex="1" align="end" tooltiptext="&panel.sets.photos.tip;" /> 201 <treecol id="sl_photos" label="&panel.sets.photos.label;" flex="1" align="end" tooltiptext="&panel.sets.photos.tip;" />
202 </treecols> 202 </treecols>
203 <treechildren/> 203 <treechildren/>
204 </tree> 204 </tree>
205 <hbox> 205 <hbox>
206 <button command="cmd_refresh_sets" /> 206 <button command="cmd_refresh_sets" />
207 <button command="cmd_set_props" /> 207 <button command="cmd_set_props" />
208 </hbox> 208 </hbox>
209 <tree id="setphotos" rows="2" onselect="fireflix.photoset.on_select()" 209 <tree id="setphotos" rows="2" onselect="fireflix.photoset.on_select()"
210 flex="1" ondblclick="fireflix.photoset.on_cmd_open(event)" 210 flex="1" ondblclick="fireflix.photoset.on_cmd_open(event)"
211 onkeypress="if(event.keyCode==event.DOM_VK_RETURN) fireflix.photoset.on_cmd_open(event)" context="setphotos_menu"> 211 onkeypress="if(event.keyCode==event.DOM_VK_RETURN) fireflix.photoset.on_cmd_open(event)" context="setphotos_menu">
212 <treecols> 212 <treecols>
213 <treecol id="sp_title" label="&panel.setphotos.title.label;" flex="1" crop="end" align="start" tooltiptext="&panel.setphotos.title.tip;" /> 213 <treecol id="sp_title" label="&panel.setphotos.title.label;" flex="1" crop="end" align="start" tooltiptext="&panel.setphotos.title.tip;" />
214 <splitter class="tree-splitter" /> 214 <splitter class="tree-splitter" />
215 <treecol id="sp_taken" label="&panel.setphotos.taken.label;" crop="end" align="start" tooltiptext="&panel.setphotos.taken.tip;" hidden="true" /> 215 <treecol id="sp_taken" label="&panel.setphotos.taken.label;" crop="end" align="start" tooltiptext="&panel.setphotos.taken.tip;" hidden="true" />
216 <treecol id="sp_upload" label="&panel.setphotos.upload.label;" crop="end" align="start" tooltiptext="&panel.setphotos.upload.tip;" hidden="true" /> 216 <treecol id="sp_upload" label="&panel.setphotos.upload.label;" crop="end" align="start" tooltiptext="&panel.setphotos.upload.tip;" hidden="true" />
217 </treecols> 217 </treecols>
218 <treechildren/> 218 <treechildren/>
219 </tree> 219 </tree>
220 <groupbox id="set_photo_props" orient="horizontal" hidden="true"> 220 <groupbox id="set_photo_props" orient="horizontal" hidden="true">
221 <vbox width="100" pack="center"> 221 <vbox width="100" pack="center">
222 <hbox pack="center"> 222 <hbox pack="center">
223 <image id="set_photo" 223 <image id="set_photo"
224 ondblclick="fireflix.photoset.on_cmd_open(event)" /> 224 ondblclick="fireflix.photoset.on_cmd_open(event)" />
225 </hbox> 225 </hbox>
226 </vbox> 226 </vbox>
227 <spacer flex="1"/> 227 <spacer flex="1"/>
228 </groupbox> 228 </groupbox>
229 </vbox> 229 </vbox>
230 </tabpanel> 230 </tabpanel>
231 231
232 <tabpanel id="tabpanel_tags"> 232 <tabpanel id="tabpanel_tags">
233 <listbox id="tagslist" rows="8" flex="1"> 233 <listbox id="tagslist" rows="8" flex="1">
234 <listhead> 234 <listhead>
235 <listheader label="&panel.tagslist.tag.label;"/> 235 <listheader label="&panel.tagslist.tag.label;"/>
236 </listhead> 236 </listhead>
237 <listcols> 237 <listcols>
238 <listcol flex="1"/> 238 <listcol flex="1"/>
239 </listcols> 239 </listcols>
240 </listbox> 240 </listbox>
241 </tabpanel> 241 </tabpanel>
242 242
243 <tabpanel id="tabpanel_upload"> 243 <tabpanel id="tabpanel_upload">
244 <vbox flex="1"> 244 <vbox flex="1">
245 <tree id="uploadlist" rows="2" flex="1" 245 <tree id="uploadlist" rows="2" flex="1"
246 onselect="fireflix.uploads.selectionChanged()" 246 onselect="fireflix.uploads.selectionChanged()"
247 context="uploads_menu"> 247 context="uploads_menu" ondblclick="fireflix.uploads.on_cmd_open(event)"
248 onkeypress="if(event.keyCode==event.DOM_VK_RETURN) fireflix.uploads.on_cmd_open(event)" >
248 <treecols> 249 <treecols>
249 <treecol id="up_file" label="&panel.uploadlist.file.label;" flex="4" crop="start" align="start"/> 250 <treecol id="up_file" label="&panel.uploadlist.file.label;" flex="4" crop="start" align="start"/>
250 <splitter class="tree-splitter" /> 251 <splitter class="tree-splitter" />
251 <treecol id="up_title" label="&panel.uploadlist.title.label;" flex="5" crop="end" align="start" /> 252 <treecol id="up_title" label="&panel.uploadlist.title.label;" flex="5" crop="end" align="start" />
252 <splitter class="tree-splitter" /> 253 <splitter class="tree-splitter" />
253 <treecol id="up_status" label="&panel.uploadlist.status.label;" flex="1" crop="end" align="start" /> 254 <treecol id="up_status" label="&panel.uploadlist.status.label;" flex="1" crop="end" align="start" />
254 </treecols> 255 </treecols>
255 <treechildren/> 256 <treechildren/>
256 </tree> 257 </tree>
257 <progressmeter id="upload_progress" mode="undetermined" hidden="true" /> 258 <progressmeter id="upload_progress" mode="undetermined" hidden="true" />
258 <groupbox id="upload_file_props" orient="vertical" hidden="true"> 259 <groupbox id="upload_file_props" orient="vertical" hidden="true">
259 <hbox> 260 <hbox>
260 <image id="upload_file_preview" width="100" height="100" /> 261 <image id="upload_file_preview" width="100" height="100" />
261 <vbox flex="1"> 262 <vbox flex="1">
262 <grid> 263 <grid>
263 <columns> 264 <columns>
264 <column/> 265 <column/>
265 <column flex="1"/> 266 <column flex="1"/>
266 </columns> 267 </columns>
267 <rows> 268 <rows>
268 <row> 269 <row>
269 <label control="upload_filename" 270 <label control="upload_filename"
270 value="&panel.upload_props.filename.label;" /> 271 value="&panel.upload_props.filename.label;" />
271 <textbox id="upload_filename" 272 <textbox id="upload_filename"
272 oninput="fireflix.uploads.propsToSel('filename')"/> 273 oninput="fireflix.uploads.propsToSel('filename')"/>
273 </row> 274 </row>
274 <row> 275 <row>
275 <label control="upload_title" value="&panel.upload_props.title.label;" /> 276 <label control="upload_title" value="&panel.upload_props.title.label;" />
276 <textbox id="upload_title" 277 <textbox id="upload_title"
277 oninput="fireflix.uploads.propsToSel('title')"/> 278 oninput="fireflix.uploads.propsToSel('title')"/>
278 </row> 279 </row>
279 <row> 280 <row>
280 <label control="upload_tags" value="&panel.upload_props.tags.label;" /> 281 <label control="upload_tags" value="&panel.upload_props.tags.label;" />
281 <textbox id="upload_tags" 282 <textbox id="upload_tags"
282 oninput="fireflix.uploads.propsToSel('tags')"/> 283 oninput="fireflix.uploads.propsToSel('tags')"/>
283 </row> 284 </row>
284 <!-- TODO: description, public, friend, family --> 285 <!-- TODO: description, public, friend, family -->
285 </rows> 286 </rows>
286 </grid> 287 </grid>
287 <hbox> 288 <hbox>
288 <checkbox id="upload_is_public" label="&panel.upload_props.is_public;"/> 289 <checkbox id="upload_is_public" label="&panel.upload_props.is_public;"/>
289 <checkbox id="upload_is_friends" label="&panel.upload_props.is_friend;"/> 290 <checkbox id="upload_is_friends" label="&panel.upload_props.is_friend;"/>
290 <checkbox id="upload_is_family" label="&panel.upload_props.is_family;"/> 291 <checkbox id="upload_is_family" label="&panel.upload_props.is_family;"/>
291 </hbox> 292 </hbox>
292 </vbox> 293 </vbox>
293 </hbox> 294 </hbox>
294 <description id="upload_failure" hidden="true"/> 295 <description id="upload_failure" hidden="true"/>
295 </groupbox> 296 </groupbox>
diff --git a/content/fireflix.js b/content/fireflix.js
index 78e56c2..225e21c 100644
--- a/content/fireflix.js
+++ b/content/fireflix.js
@@ -583,96 +583,107 @@ var fireflix = {
583 if(prop=='filename') this.files[ff].file = this.upload_filename.value; 583 if(prop=='filename') this.files[ff].file = this.upload_filename.value;
584 if(prop=='title') this.files[ff].title = this.upload_title.value; 584 if(prop=='title') this.files[ff].title = this.upload_title.value;
585 if(prop=='tags') this.files[ff].tags = this.upload_tags.value; 585 if(prop=='tags') this.files[ff].tags = this.upload_tags.value;
586 if(prop=='is_public') this.files[ff].is_public = this.upload_is_public.checked; 586 if(prop=='is_public') this.files[ff].is_public = this.upload_is_public.checked;
587 if(prop=='is_friends') this.files[ff].is_friend = this.upload_is_friends.checked; 587 if(prop=='is_friends') this.files[ff].is_friend = this.upload_is_friends.checked;
588 if(prop=='is_family') this.files[ff].is_family = this.upload_is_family.checked; 588 if(prop=='is_family') this.files[ff].is_family = this.upload_is_family.checked;
589 this.tree.invalidateRow(ff); 589 this.tree.invalidateRow(ff);
590 } 590 }
591 } 591 }
592 }, 592 },
593 593
594 on_upload: function() { 594 on_upload: function() {
595 this.selToProps(); 595 this.selToProps();
596 this.batch_ids = new Array(); 596 this.batch_ids = new Array();
597 this.upload_progress.value=0; 597 this.upload_progress.value=0;
598 this.upload_progress.setAttribute('hidden','false'); 598 this.upload_progress.setAttribute('hidden','false');
599 this.upload_worker(); 599 this.upload_worker();
600 }, 600 },
601 on_clear: function() { 601 on_clear: function() {
602 this.clear_list(); 602 this.clear_list();
603 }, 603 },
604 on_remove: function() { 604 on_remove: function() {
605 if(this.selection.count) { 605 if(this.selection.count) {
606 this.tree.beginUpdateBatch(); 606 this.tree.beginUpdateBatch();
607 for(var i=this.files.length-1;i>=0;--i) { 607 for(var i=this.files.length-1;i>=0;--i) {
608 if(this.selection.isSelected(i)) { 608 if(this.selection.isSelected(i)) {
609 this.files.splice(i,1); 609 this.files.splice(i,1);
610 this.rowCount--; 610 this.rowCount--;
611 } 611 }
612 } 612 }
613 this.tree.endUpdateBatch(); 613 this.tree.endUpdateBatch();
614 this.selection.clearSelection(); 614 this.selection.clearSelection();
615 } 615 }
616 }, 616 },
617 on_add: function() { 617 on_add: function() {
618 var ifp = Components.interfaces.nsIFilePicker; 618 var ifp = Components.interfaces.nsIFilePicker;
619 var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(ifp); 619 var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(ifp);
620 fp.init(window, "Select a File", ifp.modeOpenMultiple); 620 fp.init(window, "Select a File", ifp.modeOpenMultiple);
621 fp.appendFilters(ifp.filterImages); 621 fp.appendFilters(ifp.filterImages);
622 var rv = fp.show(); 622 var rv = fp.show();
623 if(rv==ifp.returnOK) { 623 if(rv==ifp.returnOK) {
624 var ff = fp.files; 624 var ff = fp.files;
625 while(ff.hasMoreElements()) { 625 while(ff.hasMoreElements()) {
626 var f = ff.getNext(); 626 var f = ff.getNext();
627 f.QueryInterface(Components.interfaces.nsIFile); 627 f.QueryInterface(Components.interfaces.nsIFile);
628 this.add(f.path); 628 this.add(f.path);
629 } 629 }
630 } 630 }
631 },
632 on_cmd_open: function(ev) {
633 if(this.selection.currentIndex<0) return;
634 var f = this.files[this.selection.currentIndex];
635 if(f.photoid) {
636 this.fireflix.openTab(
637 this.fireflix.flickr.make_uploader_edit_url(f.photoid)
638 );
639 }else{
640 this.fireflix.openTab( 'file://'+f.file);
641 }
631 } 642 }
632 }, 643 },
633 644
634 on_set_props: function() { 645 on_set_props: function() {
635 var pset = this.photosets.sets[this.photosets.selection.currentIndex]; 646 var pset = this.photosets.sets[this.photosets.selection.currentIndex];
636 window.openDialog( 647 window.openDialog(
637 "chrome://fireflix/content/photoset-props.xul", 648 "chrome://fireflix/content/photoset-props.xul",
638 null, "dependent,modal,dialog,chrome", this, 649 null, "dependent,modal,dialog,chrome", this,
639 pset ); 650 pset );
640 if(pset.dirty) { 651 if(pset.dirty) {
641 var _this = this; 652 var _this = this;
642 this.flickr.api_call( 653 this.flickr.api_call(
643 { 654 {
644 method: 'flickr.photosets.editMeta', 655 method: 'flickr.photosets.editMeta',
645 auth_token: 'default', 656 auth_token: 'default',
646 photoset_id: pset.id, 657 photoset_id: pset.id,
647 title: pset.title, 658 title: pset.title,
648 description: pset.description 659 description: pset.description
649 }, function(xr) { 660 }, function(xr) {
650 pset.dirty = false; 661 pset.dirty = false;
651 _this.flickr.api_call( 662 _this.flickr.api_call(
652 { 663 {
653 method: 'flickr.photosets.getPhotos', 664 method: 'flickr.photosets.getPhotos',
654 auth_token: 'default', 665 auth_token: 'default',
655 photoset_id: pset.id 666 photoset_id: pset.id
656 }, function(xr) { 667 }, function(xr) {
657 var x = xr.responseXML; 668 var x = xr.responseXML;
658 var xp = x.evaluate( 669 var xp = x.evaluate(
659 '/rsp/photoset/photo', x, null, 670 '/rsp/photoset/photo', x, null,
660 XPathResult.ORDERED_NODE_ITERATOR_TYPE, null ); 671 XPathResult.ORDERED_NODE_ITERATOR_TYPE, null );
661 var phids = new Array(); 672 var phids = new Array();
662 var priph = null; 673 var priph = null;
663 var n; while(n=xp.iterateNext()) { 674 var n; while(n=xp.iterateNext()) {
664 var pid = n.getAttribute('id'); 675 var pid = n.getAttribute('id');
665 phids.push( pid ); 676 phids.push( pid );
666 if(pid==pset.primary && n.getAttribute('isprimary')!='1') 677 if(pid==pset.primary && n.getAttribute('isprimary')!='1')
667 priph = pid; 678 priph = pid;
668 } 679 }
669 if(priph) { 680 if(priph) {
670 _this.flickr.api_call( 681 _this.flickr.api_call(
671 { 682 {
672 method: 'flickr.photosets.editPhotos', 683 method: 'flickr.photosets.editPhotos',
673 auth_token: 'default', 684 auth_token: 'default',
674 photoset_id: pset.id, 685 photoset_id: pset.id,
675 primary_photo_id: priph, 686 primary_photo_id: priph,
676 photo_ids: phids.join(',') 687 photo_ids: phids.join(',')
677 }, function() { }, function(x,s,c,m) { /* flickr.photosets.editPhotos */ 688 }, function() { }, function(x,s,c,m) { /* flickr.photosets.editPhotos */
678 _this.flickr_failure(x,s,c,m); 689 _this.flickr_failure(x,s,c,m);
@@ -868,101 +879,99 @@ var fireflix = {
868 this.searchresult_description.appendChild(de); 879 this.searchresult_description.appendChild(de);
869 /* of all linking elements flickr only allows a */ 880 /* of all linking elements flickr only allows a */
870 var as = this.searchresult_description.getElementsByTagName('a'); 881 var as = this.searchresult_description.getElementsByTagName('a');
871 for(var a=0;a<as.length;++a) 882 for(var a=0;a<as.length;++a)
872 as.item(a).setAttribute('target','_blank'); 883 as.item(a).setAttribute('target','_blank');
873 } 884 }
874 }, 885 },
875 on_select: function() { 886 on_select: function() {
876 if(this.selection.currentIndex<0) { 887 if(this.selection.currentIndex<0) {
877 this.searchresult_props.hidden = true; 888 this.searchresult_props.hidden = true;
878 }else{ 889 }else{
879 var p = this.photos[this.selection.currentIndex]; 890 var p = this.photos[this.selection.currentIndex];
880 if(!p) { 891 if(!p) {
881 this.searchresult_props.hidden = true; 892 this.searchresult_props.hidden = true;
882 }else{ 893 }else{
883 this.search_photo.src = this.fireflix.flickr.make_photo_url(p,'t'); 894 this.search_photo.src = this.fireflix.flickr.make_photo_url(p,'t');
884 this.searchresult_title.value = p.title; 895 this.searchresult_title.value = p.title;
885 this.searchresult_title.tooltipText = p.title; 896 this.searchresult_title.tooltipText = p.title;
886 this.render_description_frame(null); 897 this.render_description_frame(null);
887 if(p.description==null && p.description==undefined) { 898 if(p.description==null && p.description==undefined) {
888 var pid = p.id; 899 var pid = p.id;
889 var ci = this.selection.currentIndex; 900 var ci = this.selection.currentIndex;
890 var _this = this; 901 var _this = this;
891 this.fireflix.flickr.api_call( 902 this.fireflix.flickr.api_call(
892 { 903 {
893 method: 'flickr.photos.getInfo', 904 method: 'flickr.photos.getInfo',
894 auth_token: 'default', 905 auth_token: 'default',
895 photo_id: p.id, 906 photo_id: p.id,
896 secret: p.secret 907 secret: p.secret
897 }, function(xr) { 908 }, function(xr) {
898 var pp = _this.photos[ci]; 909 var pp = _this.photos[ci];
899 if(ci==_this.selection.currentIndex && pp.id==pid) { 910 if(ci==_this.selection.currentIndex && pp.id==pid) {
900 var n = xp_node('/rsp/photo',xr.responseXML); 911 var n = xp_node('/rsp/photo',xr.responseXML);
901 pp.fromNode_(n); 912 pp.fromNode_(n);
902 _this.render_description_frame(pp.description); 913 _this.render_description_frame(pp.description);
903 } 914 }
904 }, function(x,s,c,m) { 915 }, function(x,s,c,m) {
905 _this.fireflix.flickr_failure(x,s,c,m); 916 _this.fireflix.flickr_failure(x,s,c,m);
906 } 917 }
907 ); 918 );
908 this.searchresult_props.hidden = false; 919 this.searchresult_props.hidden = false;
909 }else{ 920 }else{
910 this.render_description_frame(p.description); 921 this.render_description_frame(p.description);
911 } 922 }
912 } 923 }
913 } 924 }
914 }, 925 },
915 on_cmd_open: function(ev) { 926 on_cmd_open: function(ev) {
916 if(this.selection.currentIndex<0) 927 if(this.selection.currentIndex<0) return;
917 return;
918 var p = this.photos[this.selection.currentIndex]; 928 var p = this.photos[this.selection.currentIndex];
919 if(!p.id) 929 if(!p.id) return;
920 return;
921 this.fireflix.openTab(this.fireflix.flickr.make_photo_url(p,'p')); 930 this.fireflix.openTab(this.fireflix.flickr.make_photo_url(p,'p'));
922 } 931 }
923 }, 932 },
924 933
925 photo_html: function(p,i,l) { 934 photo_html: function(p,i,l) {
926 // TODO: add alt/title when possible 935 // TODO: add alt/title when possible
927 var rv = 936 var rv =
928 '<a href="'+this.flickr.make_photo_url(p,l)+'">' + 937 '<a href="'+this.flickr.make_photo_url(p,l)+'">' +
929 '<img src="'+this.flickr.make_photo_url(p,i)+'" />'+ 938 '<img src="'+this.flickr.make_photo_url(p,i)+'" />'+
930 '</a>'; 939 '</a>';
931 return rv; 940 return rv;
932 }, 941 },
933 build_html: function(photos,uti,utl) { 942 build_html: function(photos,uti,utl) {
934 var rv = ''; 943 var rv = '';
935 for(var i in photos) { 944 for(var i in photos) {
936 var p = photos[i]; 945 var p = photos[i];
937 rv += this.photo_html(p,uti,utl)+'\n'; 946 rv += this.photo_html(p,uti,utl)+'\n';
938 } 947 }
939 return rv; 948 return rv;
940 }, 949 },
941 950
942 popup_content: function(s) { 951 popup_content: function(s) {
943 window.openDialog( 952 window.openDialog(
944 "chrome://fireflix/content/generated-content.xul", 953 "chrome://fireflix/content/generated-content.xul",
945 null, "dialog,chrome", this, s ); 954 null, "dialog,chrome", this, s );
946 }, 955 },
947 copy_to_clipboard: function(s) { 956 copy_to_clipboard: function(s) {
948 var ch = Components.classes["@mozilla.org/widget/clipboardhelper;1"] 957 var ch = Components.classes["@mozilla.org/widget/clipboardhelper;1"]
949 .getService(Components.interfaces.nsIClipboardHelper); 958 .getService(Components.interfaces.nsIClipboardHelper);
950 ch.copyString(s); 959 ch.copyString(s);
951 }, 960 },
952 openTab: function(l) { 961 openTab: function(l) {
953 var wm = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService( 962 var wm = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService(
954 Components.interfaces.nsIWindowMediator ); 963 Components.interfaces.nsIWindowMediator );
955 var bw = wm.getMostRecentWindow('navigator:browser'); 964 var bw = wm.getMostRecentWindow('navigator:browser');
956 var b = bw.getBrowser(); 965 var b = bw.getBrowser();
957 var t = b.addTab(l); 966 var t = b.addTab(l);
958 b.selectedTab = t; 967 b.selectedTab = t;
959 }, 968 },
960 969
961 build_menus: function() { 970 build_menus: function() {
962 this.append_html_menu( 971 this.append_html_menu(
963 document.getElementById('sets_html_menu'), 972 document.getElementById('sets_html_menu'),
964 'stm_','m_bop','cmdset_sets','cmd_sets_html' 973 'stm_','m_bop','cmdset_sets','cmd_sets_html'
965 ); 974 );
966 this.append_html_menu( 975 this.append_html_menu(
967 document.getElementById('setphotos_html_menu'), 976 document.getElementById('setphotos_html_menu'),
968 'stm_','m_bop','cmdset_setphotos','cmd_setphotos_html' 977 'stm_','m_bop','cmdset_setphotos','cmd_setphotos_html'
diff --git a/content/flickr.js b/content/flickr.js
index b8360c1..e09d5f0 100644
--- a/content/flickr.js
+++ b/content/flickr.js
@@ -52,96 +52,97 @@ Photo.prototype = {
52 this.id = n.getAttribute('id'); this.secret = n.getAttribute('secret'); 52 this.id = n.getAttribute('id'); this.secret = n.getAttribute('secret');
53 this.server = n.getAttribute('server'); 53 this.server = n.getAttribute('server');
54 this.title = n.getAttribute('title'); 54 this.title = n.getAttribute('title');
55 this.isprimary = n.getAttribute('isprimary'); 55 this.isprimary = n.getAttribute('isprimary');
56 this.license = n.getAttribute('license'); 56 this.license = n.getAttribute('license');
57 this.dateupload = n.getAttribute('dateupload'); 57 this.dateupload = n.getAttribute('dateupload');
58 this.datetaken = n.getAttribute('datetaken'); this.datetakengranularity = n.getAttribute('datetakengranularity'); 58 this.datetaken = n.getAttribute('datetaken'); this.datetakengranularity = n.getAttribute('datetakengranularity');
59 this.ownername = n.getAttribute('ownername'); 59 this.ownername = n.getAttribute('ownername');
60 this.iconserver = n.getAttribute('iconserver'); 60 this.iconserver = n.getAttribute('iconserver');
61 this.originalformat = n.getAttribute('originalformat'); 61 this.originalformat = n.getAttribute('originalformat');
62 this.lastupdate = n.getAttribute('lastupdate'); 62 this.lastupdate = n.getAttribute('lastupdate');
63 }, 63 },
64 fromNode_: function(n) { 64 fromNode_: function(n) {
65 var t; 65 var t;
66 // TODO: @rotation @isfavorite 66 // TODO: @rotation @isfavorite
67 this.owner = {}; 67 this.owner = {};
68 t = n.getElementsByTagName('owner').item(0); 68 t = n.getElementsByTagName('owner').item(0);
69 if(t) { 69 if(t) {
70 this.owner.nsid=t.getAttribute('nsid'); 70 this.owner.nsid=t.getAttribute('nsid');
71 this.owner.username=t.getAttribute('username'); 71 this.owner.username=t.getAttribute('username');
72 this.owner.realname=t.getAttribute('realname'); 72 this.owner.realname=t.getAttribute('realname');
73 this.owner.location=t.getAttribute.location; 73 this.owner.location=t.getAttribute.location;
74 } 74 }
75 t = n.getElementsByTagName('description').item(0); 75 t = n.getElementsByTagName('description').item(0);
76 if(t && t.firstChild) { 76 if(t && t.firstChild) {
77 this.description = t.firstChild.nodeValue; 77 this.description = t.firstChild.nodeValue;
78 } 78 }
79 // TODO: visibility/@ispublic visibility/@isfriend visibility/@isfamily 79 // TODO: visibility/@ispublic visibility/@isfriend visibility/@isfamily
80 // TODO: dates/@posted dates/@taken dates/@takengranularity dates/@lastupdate 80 // TODO: dates/@posted dates/@taken dates/@takengranularity dates/@lastupdate
81 // TODO: permissions/@permcomment permsiions/@permaddmeta 81 // TODO: permissions/@permcomment permsiions/@permaddmeta
82 // TODO: editability/@canaddcomment editability/@canaddmeta 82 // TODO: editability/@canaddcomment editability/@canaddmeta
83 // TODO: comments 83 // TODO: comments
84 // TODO: notes/note/@id notes/note/@author notes/note/@authorname 84 // TODO: notes/note/@id notes/note/@author notes/note/@authorname
85 // TODO: notes/note/@x notes/note/@y notes/note/@w notes/note/@h 85 // TODO: notes/note/@x notes/note/@y notes/note/@w notes/note/@h
86 // TODO: notes/note 86 // TODO: notes/note
87 // TODO: tags/tag/@id tags/tag/@author tags/tag/@raw tags/tag 87 // TODO: tags/tag/@id tags/tag/@author tags/tag/@raw tags/tag
88 // TODO: urls/url/@type urls/url 88 // TODO: urls/url/@type urls/url
89 } 89 }
90}; 90};
91 91
92function Flickr() { } 92function Flickr() { }
93Flickr.prototype = { 93Flickr.prototype = {
94 94
95 rest_url: 'http://www.flickr.com/services/rest/', 95 rest_url: 'http://www.flickr.com/services/rest/',
96 auth_url: 'http://flickr.com/services/auth/', 96 auth_url: 'http://flickr.com/services/auth/',
97 photo_url: 'http://static.flickr.com/', 97 photo_url: 'http://static.flickr.com/',
98 photos_url: 'http://www.flickr.com/photos/', 98 photos_url: 'http://www.flickr.com/photos/',
99 upload_url: 'http://www.flickr.com/services/upload/', 99 upload_url: 'http://www.flickr.com/services/upload/',
100 uploader_edit_url: 'http://www.flickr.com/tools/uploader_edit.gne',
100 101
101 api_sig: function(paramstr) { 102 api_sig: function(paramstr) {
102 return MD5(toutf8(this.api_shs+paramstr)); 103 return MD5(toutf8(this.api_shs+paramstr));
103 }, 104 },
104 api_call_url: function(params,url) { 105 api_call_url: function(params,url) {
105 params.api_key = this.api_key; 106 params.api_key = this.api_key;
106 var pp = new Array(); 107 var pp = new Array();
107 for(var p in params) { 108 for(var p in params) {
108 pp.push(p); 109 pp.push(p);
109 } 110 }
110 var pstr = ''; 111 var pstr = '';
111 var rv = (url?url:this.rest_url)+'?'; 112 var rv = (url?url:this.rest_url)+'?';
112 for(var p in pp.sort()) { 113 for(var p in pp.sort()) {
113 var pn = pp[p]; 114 var pn = pp[p];
114 pstr += pn+params[pn]; 115 pstr += pn+params[pn];
115 rv += pn+'='+params[pn]+'&'; 116 rv += pn+'='+params[pn]+'&';
116 } 117 }
117 rv += 'api_sig='+this.api_sig(pstr); 118 rv += 'api_sig='+this.api_sig(pstr);
118 return rv; 119 return rv;
119 }, 120 },
120 api_call: function(params, on_success, on_failure) { 121 api_call: function(params, on_success, on_failure) {
121 if(params.auth_token == 'default') 122 if(params.auth_token == 'default')
122 params.auth_token = this.token; 123 params.auth_token = this.token;
123 var x = new XMLHttpRequest(); 124 var x = new XMLHttpRequest();
124 x.open("GET",this.api_call_url(params)); 125 x.open("GET",this.api_call_url(params));
125 x.onreadystatechange=function() { 126 x.onreadystatechange=function() {
126 if(x.readyState!=4) return false; 127 if(x.readyState!=4) return false;
127 if(x.status==200) { 128 if(x.status==200) {
128 var stat = x.responseXML.firstChild.getAttribute('stat'); 129 var stat = x.responseXML.firstChild.getAttribute('stat');
129 if(stat=='ok') { 130 if(stat=='ok') {
130 if(on_success) on_success(x); 131 if(on_success) on_success(x);
131 }else{ 132 }else{
132 var e = x.responseXML.getElementsByTagName('err').item(0); 133 var e = x.responseXML.getElementsByTagName('err').item(0);
133 var ecode = e.getAttribute('code'); 134 var ecode = e.getAttribute('code');
134 var emsg = e.getAttribute('msg'); 135 var emsg = e.getAttribute('msg');
135 dump(params.method+' failed: '+ecode+' '+emsg+'\n'); 136 dump(params.method+' failed: '+ecode+' '+emsg+'\n');
136 if(on_failure) on_failure(x,stat,ecode,emsg); 137 if(on_failure) on_failure(x,stat,ecode,emsg);
137 } 138 }
138 }else{ 139 }else{
139 if(on_failure) on_failure(x); 140 if(on_failure) on_failure(x);
140 } 141 }
141 return true; 142 return true;
142 } 143 }
143 x.send(null); 144 x.send(null);
144 return true; 145 return true;
145 }, 146 },
146 147
147 frob: null, 148 frob: null,
@@ -230,96 +231,100 @@ Flickr.prototype = {
230 this.user.username = this.prefs.getCharPref(this.prefs_root+'.auth_user.username'); 231 this.user.username = this.prefs.getCharPref(this.prefs_root+'.auth_user.username');
231 if(this.prefs.getPrefType(this.prefs_root+'.auth_user.fullname')!=this.prefs.PREF_STRING) 232 if(this.prefs.getPrefType(this.prefs_root+'.auth_user.fullname')!=this.prefs.PREF_STRING)
232 return this._reset_token(); 233 return this._reset_token();
233 this.user.fullname = this.prefs.getCharPref(this.prefs_root+'.auth_user.fullname'); 234 this.user.fullname = this.prefs.getCharPref(this.prefs_root+'.auth_user.fullname');
234 }catch(e) { return this._reset_token(); } 235 }catch(e) { return this._reset_token(); }
235 return true; 236 return true;
236 }, 237 },
237 reset_token: function() { 238 reset_token: function() {
238 this._reset_token(); 239 this._reset_token();
239 this.save_token(); 240 this.save_token();
240 }, 241 },
241 242
242 get_photo_url: function(ser,id,sec,sfx,ext) { 243 get_photo_url: function(ser,id,sec,sfx,ext) {
243 var rv = this.photo_url + ser + '/' + id + '_' + sec; 244 var rv = this.photo_url + ser + '/' + id + '_' + sec;
244 if(sfx && sfx!='_') rv += '_'+sfx; 245 if(sfx && sfx!='_') rv += '_'+sfx;
245 rv += ext?'.'+ext:'.jpg'; 246 rv += ext?'.'+ext:'.jpg';
246 return rv; 247 return rv;
247 }, 248 },
248 get_image_url: function(o,sfx) { 249 get_image_url: function(o,sfx) {
249 return this.get_photo_url( 250 return this.get_photo_url(
250 o.server, 251 o.server,
251 (o instanceof Photoset)? o.primary : o.id, 252 (o instanceof Photoset)? o.primary : o.id,
252 o.secret, 253 o.secret,
253 sfx, 254 sfx,
254 (sfx=='o')?o.originalformat:null 255 (sfx=='o')?o.originalformat:null
255 ); 256 );
256 }, 257 },
257 get_photo_page_url: function(p) { 258 get_photo_page_url: function(p) {
258 if(p instanceof Photo) { 259 if(p instanceof Photo) {
259 // TODO: track photoset and user owner id from there? 260 // TODO: track photoset and user owner id from there?
260 // The approach below is sheerly wrong. 261 // The approach below is sheerly wrong.
261 var o = this.user.nsid; 262 var o = this.user.nsid;
262 if(p.owner && p.owner.nsid) o = p.owner.nsid; 263 if(p.owner && p.owner.nsid) o = p.owner.nsid;
263 var rv = this.photos_url + o +'/' + p.id; 264 var rv = this.photos_url + o +'/' + p.id;
264 return rv; 265 return rv;
265 }else // TODO: take owner into account? 266 }else // TODO: take owner into account?
266 return this.photos_url + this.user.nsid + '/' + p; 267 return this.photos_url + this.user.nsid + '/' + p;
267 }, 268 },
268 make_photo_url: function(p,sfx) { 269 make_photo_url: function(p,sfx) {
269 if(sfx=='p') 270 if(sfx=='p')
270 return this.get_photo_page_url(p); 271 return this.get_photo_page_url(p);
271 else 272 else
272 return this.get_image_url(p,sfx); 273 return this.get_image_url(p,sfx);
273 }, 274 },
274 make_photoset_url: function(ps) { 275 make_photoset_url: function(ps) {
275 // TODO: allow for using someone else's photoset? 276 // TODO: allow for using someone else's photoset?
276 return this.photos_url+this.user.nsid+'/sets/'+ps.id; 277 return this.photos_url+this.user.nsid+'/sets/'+ps.id;
277 }, 278 },
279 make_uploader_edit_url: function(pid) {
280 // TODO: handle arrays
281 return this.uploader_edit_url+'?ids='+pid;
282 },
278 283
279 upload_file: function(f,fa,on_success,on_failure) { 284 upload_file: function(f,fa,on_success,on_failure) {
280 try { 285 try {
281 var fi = Components.classes["@mozilla.org/file/local;1"] 286 var fi = Components.classes["@mozilla.org/file/local;1"]
282 .createInstance(Components.interfaces.nsILocalFile); 287 .createInstance(Components.interfaces.nsILocalFile);
283 fi.initWithPath( f ); 288 fi.initWithPath( f );
284 var st = Components.classes["@mozilla.org/network/file-input-stream;1"] 289 var st = Components.classes["@mozilla.org/network/file-input-stream;1"]
285 .createInstance(Components.interfaces.nsIFileInputStream); 290 .createInstance(Components.interfaces.nsIFileInputStream);
286 st.init(fi,0x01,00004,null); 291 st.init(fi,0x01,00004,null);
287 var bis = Components.classes["@mozilla.org/binaryinputstream;1"] 292 var bis = Components.classes["@mozilla.org/binaryinputstream;1"]
288 .createInstance(Components.interfaces.nsIBinaryInputStream); 293 .createInstance(Components.interfaces.nsIBinaryInputStream);
289 bis.setInputStream(st); 294 bis.setInputStream(st);
290 295
291 // allocate and initialize temp storage string 296 // allocate and initialize temp storage string
292 var pbs = Components.classes["@mozilla.org/storagestream;1"] 297 var pbs = Components.classes["@mozilla.org/storagestream;1"]
293 .createInstance(Components.interfaces.nsIStorageStream); 298 .createInstance(Components.interfaces.nsIStorageStream);
294 pbs.init(1024,10000000,null); 299 pbs.init(1024,10000000,null);
295 // create output stream 300 // create output stream
296 var pbos = pbs.getOutputStream(0); 301 var pbos = pbs.getOutputStream(0);
297 // and a binaryoutputstream interface 302 // and a binaryoutputstream interface
298 var pbbos = Components.classes["@mozilla.org/binaryoutputstream;1"] 303 var pbbos = Components.classes["@mozilla.org/binaryoutputstream;1"]
299 .createInstance(Components.interfaces.nsIBinaryOutputStream); 304 .createInstance(Components.interfaces.nsIBinaryOutputStream);
300 pbbos.setOutputStream(pbos); 305 pbbos.setOutputStream(pbos);
301 306
302 /* create POST body */ 307 /* create POST body */
303 var boundarytoken = 'kadaroloongazaduviaxamma'; 308 var boundarytoken = 'kadaroloongazaduviaxamma';
304 var boundary = '--'+boundarytoken; 309 var boundary = '--'+boundarytoken;
305 var b = ''; 310 var b = '';
306 311
307 var parms = { api_key: this.api_key, auth_token: this.token }; 312 var parms = { api_key: this.api_key, auth_token: this.token };
308 for(var p in fa) parms[p] = fa[p]; 313 for(var p in fa) parms[p] = fa[p];
309 var pns = new Array(); 314 var pns = new Array();
310 for(var p in parms) pns.push(p); 315 for(var p in parms) pns.push(p);
311 var pstr = ''; 316 var pstr = '';
312 for(var p in pns.sort()) { 317 for(var p in pns.sort()) {
313 var pn = pns[p]; 318 var pn = pns[p];
314 pstr += pn+parms[pn]; 319 pstr += pn+parms[pn];
315 b += boundary+'\nContent-Disposition: form-data; name="'+pn+'"\n\n'+toutf8(parms[pn])+'\n'; 320 b += boundary+'\nContent-Disposition: form-data; name="'+pn+'"\n\n'+toutf8(parms[pn])+'\n';
316 } 321 }
317 b += boundary+'\nContent-Disposition: form-data; name="api_sig"\n\n'+this.api_sig(pstr)+'\n'; 322 b += boundary+'\nContent-Disposition: form-data; name="api_sig"\n\n'+this.api_sig(pstr)+'\n';
318 b += boundary+'\nContent-Disposition: form-data; name="photo"; filename="'+f+'"\nContent-Type: image/jpeg\nContent-Transfer-Encoding: binary\n\n'; 323 b += boundary+'\nContent-Disposition: form-data; name="photo"; filename="'+f+'"\nContent-Type: image/jpeg\nContent-Transfer-Encoding: binary\n\n';
319 pbbos.writeBytes(b,b.length); 324 pbbos.writeBytes(b,b.length);
320 var bisbytes = bis.available(); 325 var bisbytes = bis.available();
321 pbbos.writeBytes(bis.readBytes(bisbytes),bisbytes); 326 pbbos.writeBytes(bis.readBytes(bisbytes),bisbytes);
322 pbbos.writeBytes('\n'+boundary+'--',3+boundary.length); bis.close(); st.close(); 327 pbbos.writeBytes('\n'+boundary+'--',3+boundary.length); bis.close(); st.close();
323 328
324 pbbos.close(); pbos.close(); 329 pbbos.close(); pbos.close();
325 330