PKtNDa==imbo-1.1.1/searchindex.jsSearch.setIndex({envversion:42,terms:{represent:[1,2],all:[0,1,2,3,5,4,7,8,9,10,11],code:[],partial:[],autorotatelisten:9,addserv:3,maximum:9,skip:[1,4,11,9],originalheight:1,ctime:9,prefix:[8,11],shorturlparam:8,upsid:[],follow:[1,2,3,5,4,8,9,11],edg:10,categori:1,varnish:[],depend:[1,10,8,2],chain:2,imagetransformationcach:9,readabl:1,send:[1,3,2,4,7,9,11],queri:[1,10,11,8,2],larg:9,sha256:1,sent:[2,4,9],sourc:[0,1,3,4,8,11],everi:2,string:[3,10,2],accesstoken:[2,1,9],fals:[2,1,3],none:1,mechan:[1,3],failur:[1,3],veri:1,retriev:1,tagnam:8,brows:4,dbname:2,level:10,did:1,list:[2,1,9],upload:[1,9],"try":2,item:3,adjust:[2,8],localhost:2,maxsiz:[],quick:[2,11],somemethod:11,readthedoc:4,databasenam:2,pleas:[0,4,11,3],prevent:1,autorot:[],dimens:10,direct:1,crop:[],sign:[],consequ:2,second:[1,9,3],phpunit:4,fliphorizont:[],pass:[2,4,11,9],further:1,port:8,append:1,maxag:9,index:[],what:[1,10],"95f02d701b8dc19ee7d3710c477fd5f4633cec32087f562264e4975659029af7":2,clock:10,neg:[2,10],section:[2,1,11,7,9],advanc:2,abl:[1,11,8,2],invok:11,mysql:[],current:[1,11,10,9],delet:[],version:[1,4,8,2],fastcgi_index:8,abv:1,"new":[1,3,2,4,9,10],net:[0,11,3],"public":[2,1,11,8,5],metadata:[],cooltransform:5,full:[3,11,8,2],hash:[1,2],caveat:1,variat:[0,9],gener:[2,1,4,9],imboerrorcod:1,privat:[1,2],here:[2,8,9],bodi:1,let:3,address:9,path:[2,8,9],along:[1,11,10,2],vertic:[],modifi:[],sinc:1,valu:[1,3,2,5,9,10,11],convert:[],dec:1,otherlisten:2,koldbrann:1,checksum:[1,8,2],larger:10,errorlog:8,"3vefrpb":1,datetim:1,amount:[3,9],within:1,behat:4,earli:11,numus:1,chang:[2,1,10,8,9],overrid:[2,10,8,9],via:[1,2,4,8,10,11],apr:1,appli:[],modul:[],prefer:10,hash_hmac:1,filenam:[2,8],imagick:[],api:[],visibl:1,instal:[],decrement:3,total:1,f5f7851c40e2b76a01af9482f67bbf3f:10,unit:4,httpd:[3,8],hexadecim:10,from:[1,3,2,4,8,9,10,11],describ:[1,2],would:[8,9],commun:1,sake:1,ddthh:1,regist:[11,9],two:[1,2,8,9,10,11],coverag:4,next:8,few:8,datadir:2,handler:11,call:[2,11],f00:10,recommend:[2,8],md5:[1,2],type:[],until:1,fastcgi:8,more:[0,1,2,5,7,8,9,11],sort:1,plug:8,apc_fetch:3,relat:[1,4,8,9],notic:4,site:1,exce:9,accept:[1,10],jsonp:1,rare:10,must:[1,10,7,8,2],fly:[],topic:8,signific:8,endpoint:[],join:[0,1],hour:9,customstat:1,setup:[],work:[],uniqu:8,dev:[1,4,8],transpos:[],can:[0,1,2,3,4,7,8,9,10,11],vcl_recv:8,learn:1,purpos:[2,11],root:[4,8,9],fetch:[],control:[],sqlite:[],somethirdmethod:11,mongo:[2,6],advis:10,give:2,share:[],calcul:10,agent:[1,9],customlog:8,tag:[1,10,9],caution:11,stream_context_cr:1,want:[0,1,2,3,4,6,8,9,10,11],phrase:1,unsign:8,occur:1,ratio:[10,9],alwai:[1,8],multipl:[2,3,11,8,9],replicaset:2,thing:8,anoth:9,charset:8,getcompos:[4,8],snippet:[1,8,11],how:[1,2,7,8,9,11],copyright:[3,11],anyon:2,foreach:11,subdirectori:2,instead:[1,11,8,10],somevalu:1,config:8,updat:[],resourc:[],phpdocumentor:4,flip:[],max:[],clone:[],after:[4,8,11],tool:[2,4],befor:[1,11,8,9],wrong:1,access_log:8,date:[1,9],end:[],associ:[2,1,9,3],handl:[2,11],github:[0,1,3,4,7,8,2],imageinfo:8,ani:[0,1,2,4,9,10],condit:1,grant:11,bright:10,element:[2,1,10,9],issu:[0,4,1],callback:[1,11,2],"switch":2,sha:[1,2],combin:[2,11,8,10],allow:[2,1,5,9],callabl:11,order:[1,8,10],help:4,over:[2,8],move:2,becaus:8,jpeg:[1,10],quantumrang:10,through:[2,8],hexdigest:1,hell:1,still:9,apidoc:4,dynam:11,paramet:[1,3,2,9,10,11],style:[1,10],obviou:8,fit:[1,7,10],fix:[2,4],norwai:1,mongocli:2,better:9,com:[1,8],exchang:9,purg:9,main:[0,8],might:[2,1,4,8,9],pixel:[1,10,9],them:[1,2,7,8,9,10],good:3,"return":[1,3,2,5,8,9,10,11],thei:[1,11,10],python:1,auto:[],rake:4,handi:11,auth:[],rewriterul:8,"break":8,mention:[10,8,11],wise:[10,9],stout:1,front:2,nov:1,now:[1,4],negoti:1,strive:8,"instanceof":2,choic:[3,8],term:2,somewher:9,name:[2,4,11,8,9],changelog:8,edit:[1,2],drop:4,authent:[],separ:[2,11],easili:[1,7,8,2],achiev:[2,1,11,8,9],innodb:8,mode:[1,10],timeout:2,each:[2,10],debug:11,found:[1,4],went:1,complet:[1,4,11,9],side:10,mean:[10,11,8,9],domain:[8,9],serveralia:8,bump:8,hard:2,idea:0,crontab:9,meta:0,"static":[2,11,5],connect:[2,1,3],packagist:8,happen:9,event:[],out:[10,11],accesslog:8,accomplish:[2,1,9],storageinterfac:[2,7,11],network:0,"3rd":8,twice:1,miss:0,newli:4,req:8,vcl:8,breweri:1,primari:8,content:[],rewrit:8,etag:[],sprintf:1,print:1,got:1,merg:[2,8],correct:8,statist:[],earlier:2,insid:[2,11,10],watermark:[],migrat:2,manipul:1,originalextens:1,given:[10,11,9],free:[2,0,7,10,3],effect:[1,10,9],asc:1,small:2,reason:1,base:[],mime:[1,8],latest:8,put:[2,1,11,8,9],org:[1,4,8,2],"byte":[1,9],auto_incr:8,othercustomlisten:2,wai:[2,8,9],angl:10,could:[2,11],omit:[1,10],ff0000:10,keep:[3,11,8,2],filter:[2,1,9],turn:[2,8],gmdate:1,enforc:[],place:[0,10,9,8,1],outsid:10,retain:10,allowedorigin:9,assign:5,first:[1,4,8,2],origin:[],softwar:1,rang:10,directli:[2,8,11],upper:10,feel:[2,0,4,7,3],onc:2,arrai:[1,2,5,8,9,10,11],beer:1,qualiti:[0,10],number:[2,1,10,8,3],echo:[1,3],hook:2,alreadi:[1,9],done:[1,2],messag:1,open:[0,4,9,1],payload:[2,10],"__construct":2,size:[],prioriti:[2,11],publickei:[2,1,8,9],differ:[0,1,2,3,7,8,9,10,11],php:[0,1,2,3,4,5,6,8,9,10,11],smaller:10,allowedmethod:9,attach:[1,11,2],data:[],top:10,mkdir:8,system:[1,2],least:[2,10],getdatabas:11,downsiz:9,attack:[1,9],master:8,originalwidth:1,time:[1,10,8,9],white:9,b312ff29d5da23dcd230b61ff4db1e2515c862b9fb0bb59e7dd54ce1e4e94a53:2,store:[0,1,2,3,6,8,9,10,11],listen:[],hue:10,knowledg:2,option:[2,3,10,8,9],namespac:[3,11],travi:4,xdelet:1,ipv6:[1,9],specifi:[1,2,8,9,10,11],blacklist:[2,9],"short":[1,10,2],enclos:1,mostli:[2,11],checkout:8,kept:9,transformationpreset:[],pecl:[3,6],than:9,png:[],practic:10,kind:1,grep:1,whenev:[2,5],provid:[1,2,8,9,10,11],remov:[],structur:8,horizont:[],project:[2,0,4,1],try_fil:8,posit:10,schema:8,"3b98dde5f67989a878b8b268d82f81f0858d4f1954597cc713ae161cdffcc84a":2,browser:9,fashion:[1,2],experi:2,arg:8,mind:2,getrequest:11,packag:[3,4,11],width:[1,2,5,8,9,10],expir:3,have:[0,1,2,3,4,7,8,9,10,11],documentroot:8,need:[1,2,4,5,6,7,8,9,11],eventlisteneriniti:[],"null":[3,8,2],border:[],implod:1,"char":8,engin:8,built:11,alias:8,rout:[],expos:1,getsubscribedev:[2,11,5],client:[2,1,10,9],note:[10,9],mix:3,high:[0,10],without:[2,1,9],take:[2,1,5],which:[2,1,11,8,9],mit:[0,4],channel:[0,4],fastcgi_param:8,sure:[1,2],unless:[2,1,10,8,9],distribut:[3,11],usernam:2,listenerintefac:2,previou:11,compress:[],fd2fd87a2f5288be31c289e70e916123:1,most:[1,11,10],plai:1,preset:[],plan:[8,9],pair:[1,2],imbo1:8,imbo2:8,imbo3:8,"class":[],dai:9,appear:[10,9],simplic:1,don:[1,2],url:[1,2,5,8,10,11],doc:[1,4],later:8,cover:[2,4,8,9],uri:[1,8,9],doe:[2,1,9,7,3],initializerforcustomlisten:2,satur:10,usual:10,sum:1,dot:2,generateprivatekei:2,think:[2,1,7,3],show:1,text:8,whitelist:[2,9],random:[1,2],server_nam:8,permiss:11,hack:11,threshold:10,protocol:8,find:[0,1,2,4,8,9,10,11],addit:4,rotat:[],xml:[1,2],absolut:2,onli:[1,2,8,9,10,11],locat:[2,4,8,9],just:1,pretti:7,confgur:7,explain:1,configur:[],getargu:[11,5],tagvalu:8,w7ciqdm:1,experiment:2,black:1,local:2,decid:[1,2],hit:1,file_get_cont:1,variou:1,get:[],shorturlid:8,imageidentifi:[1,8,9],express:[1,2],stop:11,hashlib:1,setdefaultimag:10,chat:0,progress:[],increas:10,rexxar:8,storage_imag:8,gem:1,customlisten:[2,11],initializerinterfac:2,bar:1,enabl:[1,7,8,9],stoppropag:11,irc:[0,4],mon:1,patch:8,error_log:8,grai:[],bad:1,stuff:4,integr:4,contain:[1,8,2],utcnow:1,where:[1,2,4,8,9,11],view:[3,11],respond:[1,10,9],set:[1,3,2,7,8,9,10],human:1,dbal:[2,8],getmodel:1,desatur:[],gmagick:9,see:[1,2,7,8,9,11],result:[1,10],fff:10,fail:1,numimag:1,charact:[1,2],page:1,statu:[],hipsta:8,someth:2,someus:[1,2],behind:0,won:[0,9],pagin:1,between:[2,1,8,3],"import":[1,11],awai:2,numbyt:1,approach:11,thumbnail:[],altern:2,signatur:[1,9],never:[1,11,2],kei:[1,3,2,8,9,11],metal:1,"03z":1,extens:[1,2,6,8,3,10],lowercas:[2,11],entir:11,extent:10,distinguish:1,argument:[2,4,11,5],come:11,tue:1,getallowedmethod:2,both:[1,2,4,8,9,10,11],cor:[],getmanag:11,img:10,hashtwo:[],howev:9,wed:1,alon:8,equal:[1,2],against:[2,1,4,8,9],imageid:8,pdo:2,instanc:[1,3,2,6,8,9,10,11],monitor:1,somelist:1,mani:9,whole:4,strftime:1,comment:[],acceler:[2,8],simpli:[2,1,4,8,9],someotherus:[1,2],technic:9,point:8,instanti:2,guidelin:4,virtualhost:8,dispatch:11,height:[1,2,5,8,9,10],modif:1,shorturl:[],written:[0,4],non:[1,9],suppli:[1,10,2],respect:[1,4],assum:8,christer:[3,11],backend:[1,6,8,9],quit:9,xpost:1,request_filenam:8,"01t14":1,maximagesizelisten:9,compos:[],json:[1,8,2],lastmodifi:1,secret:[1,2],trigger:[2,11,10,5],f3fa1d9f0649cfad61e840a6e09b156e851858799364d1d8ee61b386e10b0c05:1,futur:[1,2],popul:[1,9],nitpick:4,strategi:9,yournam:8,field:1,imag:[],rubi:1,search:1,databaseinterfac:[2,7,11],upgrad:8,coordin:10,accident:2,corner:10,togeth:2,func:1,rememb:[2,4,8],last:[],present:[2,9],delimit:1,"case":[1,8,10],determinist:10,therefor:9,look:[2,1,4,11,5],virtual:8,properti:[],imperi:1,originalfiles:1,formatt:2,defin:[10,4,8],"while":1,abov:[2,1,11,8,9],error:[],eventinterfac:[2,11],anonym:2,privatekei:1,region:10,propag:11,layer:[2,6],openssl_random_pseudo_byt:2,increment:3,someothervalu:1,genr:1,metadatacach:9,deliv:1,exifmetadata:9,jpg:[],utf8_danish_ci:8,itself:[2,1,11,9],headernam:9,curl:[1,4,8,10],sever:[10,8,11],subscrib:[11,9],develop:[4,8],author:[3,11],receiv:[2,11,10],parti:8,make:[],script_filenam:8,cross:[],same:[1,3,2,8,9,10,11],binari:1,html:4,descend:1,timestamp:1,success:3,start:1,higher:[2,8],nameofreplicaset:2,spell:4,http:[0,1,2,4,8,9,10,11],hostnam:[3,2],imbo_storag:2,utf8:8,nest:1,driver:2,someon:5,solut:[3,2],capabl:1,temporari:2,initi:[],countri:1,canva:[],outbound:[1,10],collat:8,respons:[2,1,11,10,9],typic:[1,10],expand:[],pull:[3,4,7,2],yeah:1,lower:8,task:4,off:9,center:[1,10],scenario:4,older:9,statsaccess:[2,9],entri:2,eventmanag:[2,11],well:[0,1,2,4,8,9],phar:[4,8],person:8,exampl:[],command:[2,4,9],thi:[1,3,2,4,8,9,10,11],choos:[2,1,11,8,3],entiti:1,model:[1,2],paradigm:1,event2:11,anybodi:1,left:[10,7,8],ispropagationstop:11,load:[2,11,8,9],identifi:[2,1,10,9],basi:9,execut:[2,4,11],percent:10,imbo:[],shortimageurl:1,rest:[0,1],bandwidth:1,pdo_mysql:2,listmodel:2,aspect:[10,9],getconfig:[2,11],tone:[],yet:1,ssz:1,web:[],gather:1,easi:2,also:[0,1,2,3,4,5,6,8,9,10,11],ideal:4,param:[2,3,5,8,9],apache2:8,otherus:2,add:[],valid:[1,9],blob:8,mod_rewrit:8,foobar:1,input:1,ffffff:10,save:1,match:[2,1,8,9],gmt:1,bin:4,applic:[1,11],varchar:8,around:[1,10],format:[1,2],read:[1,2,4,8,9,11],piec:[2,11],dark:1,tabl:[2,8],know:[0,11,1],background:10,cooki:8,part:[1,3,2,4,7,9,11],password:2,paint:10,licens:[0,4,11,3],desc:1,insert:[11,9],daemon:3,resid:8,like:[1,2,6,8,9,10,11],specif:[2,1,11,8,9],header:[],graythumb:2,should:[1,2,4,7,8,3,10,11],manual:[2,8],unix:1,integ:8,server:[],collect:[],"boolean":[1,3],cogo:[3,11],either:[1,2],transvers:[],output:[1,3],resiz:[],manag:[2,11],underli:2,exceed:9,right:10,old:[1,9],xput:1,yolo:8,some:[1,3,2,4,8,9,10,11],back:1,percentag:10,certain:[2,11,9],intern:[2,1,9],sampl:8,band:1,mirror:[],digest:1,guess:2,librari:[1,8],flipvert:[],basic:[1,2],scale:[],fixedgraythumb:2,exif:[],confirm:4,allowedtag:9,setdepend:2,definit:11,rewriteengin:8,per:[2,1,10,9],getstorag:11,concaten:1,tracker:[0,4],leav:[4,9],inject:2,cidr:9,maximages:[2,9],foo:1,notabl:11,getnam:11,refer:2,encourag:1,who:1,run:[3,6,4,8],reach:8,usag:9,host:[2,8],repositori:8,offset:10,feb:1,post:[1,11,10,9],"4492acb937a1f056ae43509bc7f85d21":1,stage:4,chapter:[1,2,8,9,10,11],sub:8,about:[1,2,8,9,10,11],simplest:11,actual:[8,9],resourceinterfac:2,gama:9,fastcgi_pass:8,slightli:9,surround:10,setlist:2,degre:10,regular:[1,2],horizon:1,constructor:[2,11,9],commit:2,disabl:[2,1,9],road:1,yyyi:1,array_kei:2,lastli:2,encod:[1,2],www:[1,8],automat:[3,8,2],three:2,down:[],phase:2,rdbmss:8,someeventlisten:11,notat:9,wrap:1,caus:9,soon:1,your:[],necessari:4,leverag:[3,8],git:[],log:8,suffici:4,area:10,transfer:2,support:[],transform:[],"long":[2,9],strip:[],gif:[],singl:[1,3,2,9,10,11],interfac:[],includ:[1,2,5,4,8,9,10,11],lot:9,suit:4,"var":8,music:1,ipv4:[1,9],getrespons:[1,11,2],httpclient:1,"function":[1,2,5,3,10,11],head:[1,11,8,9],originalmimetyp:1,form:[1,4,9],forc:[1,11],regard:[1,4,8,9,10,11],server1:2,server2:2,server3:2,somedepend:2,link:8,measur:10,"n\u00f8gne":1,placement:10,line:[2,8],inlin:10,"true":[2,1,3],bug:4,freenod:[0,4],count:1,utc:1,someothermethod:11,made:[1,10,8,2],utf:2,consist:[3,2],possibl:[2,10,9],whether:1,wish:[1,9],access:[],bucket:2,displai:1,below:[1,2,8,9,10,11],varnishhashtwo:9,limit:[1,9],minor:8,cacheinterfac:[3,9],otherwis:3,inform:[1,2,3,5,6,7,8,9,11],fact:[1,11],similar:[1,4,9],care:[2,11,9],expect:[1,8,2],featur:[0,4,8,2],autorotateimag:9,creat:[],"int":[3,8],flow:11,"abstract":[2,6],sepia:[],repres:[2,1,10,9],amongst:0,avail:[],replica:2,exist:[1,3,5,4,7,8,2,10],apcu:3,file:[1,3,2,7,8,9,10,11],request:[],gethandl:11,ship:[2,3,7,8,9],rewritecond:8,check:[1,4,11,9],probabl:1,mod_accesslog:8,successfulli:4,color:[],quot:1,user:[],when:[1,2,4,8,9,10,11],detail:[1,4,11,10,2],invalid:[1,9],vendor:[4,8],"default":[],finish:8,other:[0,1,2,3,4,8,9,10,11],rdbm:[2,6,8],branch:[4,8],you:[0,1,2,3,4,5,6,7,8,9,10,11],servernam:8,stat:[],extern:1,introduc:4,pear:4,edvartsen:[3,11],releas:[2,8],embed:9,score:1,imbous:2,starzing:[3,11],stai:2,axi:10,sphinx:4,longer:1,algorithm:[2,9],directori:[1,4,8,2],bottom:10,descript:[10,4],rule:8,hmac:1,inset:10,ignor:[1,10,8,2],token:[],potenti:2,setmodel:2,understand:4,sniffer:4,profil:4,unset:8},objtypes:{},objnames:{},filenames:["index","usage/api","installation/configuration","develop/cache_adapters","develop/contributing","develop/image_transformations","installation/requirements","develop/custom_adapters","installation/installation","installation/event_listeners","usage/image-transformations","develop/event_listeners"],titles:["Imbo - Image box","Imbo’s API","Configuration","Cache adapters","Contributing to Imbo","Implement your own image transformations","Requirements","Implement your own database and/or storage adapter","Installation","Customize your Imbo installation with event listeners","Transforming images on the fly","Working with events and event listeners"],objects:{},titleterms:{comment:10,code:4,partial:1,rotat:[10,9],imbo:[0,1,2,4,9,11],mysql:8,upsid:10,web:8,varnish:[8,9],configur:[2,8],apach:8,add:[1,10],contribut:4,get:1,auto:[10,9],auth:2,nginx:8,amazon:2,requir:[6,4],header:1,transvers:10,mirror:10,authent:9,method:11,collect:1,token:[1,9],statist:1,maxsiz:10,resiz:10,remov:1,autorot:10,replac:1,crop:10,sign:1,gridf:2,doctrin:2,fliphorizont:10,apc:3,server:8,event:[2,11,9],flipvert:10,index:1,statu:1,scale:10,exif:[10,9],grai:10,databas:[2,7,8],access:[1,9],delet:1,etag:1,adapt:[3,7,2],mongodb:2,progress:10,"__invok":11,content:1,thumbnail:10,metadata:[1,9],extend:0,watermark:10,standard:4,closur:11,base:10,vertic:10,modifi:1,box:0,convert:10,cor:9,last:1,transpos:10,hashtwo:9,memcach:3,enforc:10,implement:[3,11,7,5],origin:9,own:[7,5],tone:10,color:10,appli:10,modul:10,compos:8,down:10,shorturl:1,imagick:9,api:1,strip:10,instal:[0,8,9],guid:0,storag:[2,7],your:[5,7,9],size:[10,9],git:8,listenerinterfac:11,script:4,support:1,transform:[2,5,10,9],custom:[2,0,9,3,1],avail:1,gif:10,interfac:11,type:[1,10],listen:[2,11,9],eventlisten:[2,11],lighttpd:8,transformationpreset:2,cach:[1,9,3],png:10,initi:2,fly:10,endpoint:1,"default":2,setup:8,properti:10,desatur:10,horizont:10,error:1,servic:2,fetch:1,control:1,sqlite:8,creat:10,sepia:10,share:9,jpg:10,eventlisteneriniti:2,work:11,border:10,end:0,rout:2,cross:9,write:[1,11],build:4,test:4,document:4,simpl:2,imag:[0,1,2,5,9,10],updat:1,stat:[1,9],resourc:[2,1,9],flip:10,max:[10,9],clone:8,object:11,compress:10,preset:2,user:[2,0,1],canva:10,data:10,"class":11,expand:10,request:1,exampl:2,filesystem:2,make:10}})PKtNDHbHIIimbo-1.1.1/search.html Search — Imbo 1.1.1 documentation

Read the Docs v: 1.1.1
Versions
latest
develop
1.1.1
1.0.1
0.3.3
Downloads
PDF
HTML
Epub
On Read the Docs
Project Home
Builds

Free document hosting provided by Read the Docs.
PKtNDЛimbo-1.1.1/.buildinfo# Sphinx build info version 1 # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. config: 0fe0fa7979246d2477e7f68d627a4be5 tags: efa25262f700e02b1777eb79ee109f5c PKtNDc>H>Himbo-1.1.1/genindex.html Index — Imbo 1.1.1 documentation

Index

Read the Docs v: 1.1.1
Versions
latest
develop
1.1.1
1.0.1
0.3.3
Downloads
PDF
HTML
Epub
On Read the Docs
Project Home
Builds

Free document hosting provided by Read the Docs.
PKtNDxkggimbo-1.1.1/objects.inv# Sphinx inventory version 2 # Project: Imbo # Version: 1.1 # The remainder of this file is compressed using zlib. xڽXKo6WhA1ފ6@Gk`]ě@QDH$KRI~gviG7p#cVuԺ꧆-xChgY'Lkos/M{N"sl,/,w BMÜPr2H7QzeV]L43Lڥ2h9p gSF{DWO9U+E\q́ey${p4 Ucu&*k8ikag[ c%F)"b@0v ",l> F'J: uڊJhћ#;N1 Y˖,Eң-SXŴ;UKQwftZz$RvG,mKxܳiB"5o !|#O|[4| juˍoFTwsRK[ (%Eb"6PR9QOtgO)}Ί)@MNʤ1=?pd('$A: EQV+{qL{ m1ʌ{CF /qgXiP]s%26; wp-Q Iy'kr~u{0pxuWQo}%ݍu oFZ< < )YO2)h߼dY[ޚI@)Wc0<|@O$[&[ Z:VMafz%IJ` gM׶S[V< n!FaOx~st \ukf.>zrQBz;쀲2tKmؚZB1D^h+3b;=6=c_K&Ķ9:Q8T PKsNDdeӆӆimbo-1.1.1/index.html Imbo - Image box — Imbo 1.1.1 documentation

Imbo - Image box

Imbo is an image “server” that can be used to add/get/delete images using a RESTful HTTP API. There is also support for adding meta data to the images stored in Imbo. The main idea behind Imbo is to have a place to store high quality original images and to use the API to fetch variations of the images. Imbo will resize, rotate and crop (amongst other transformations) images on the fly so you won’t have to store all the different variations.

Imbo is an open source (MIT licensed) project written in PHP and is available on GitHub. If you find any issues or missing features please add an issue in the issue tracker. If you want to know more feel free to join the #imbo channel on the Freenode IRC network (chat.freenode.net) as well.

Read the Docs v: 1.1.1
Versions
latest
develop
1.1.1
1.0.1
0.3.3
Downloads
PDF
HTML
Epub
On Read the Docs
Project Home
Builds

Free document hosting provided by Read the Docs.
PKtND9yy+imbo-1.1.1/usage/image-transformations.html Transforming images on the fly — Imbo 1.1.1 documentation

Transforming images on the fly

What you as an end-user of an Imbo installation will be doing most of the time, is working with images. This is what Imbo was originally made for, and this chapter includes details about all the different image transformations Imbo supports.

All image transformations can be triggered by specifying the t query parameter. This parameter must be used as an array so that you can provide several image transformations. The transformations will be applied to the image in the same order as they appear in the URL. Each element in this array represents a single transformation with optional parameters, specified as a string. If the t query parameter is not an array or if any of its elements are not strings, Imbo will respond with HTTP 400.

Below you will find all image transformations supported “out of the box”, along with their parameters. Some transformations are rarely used with HTTP GET, but are instead used by event listeners that transform images when they are added to Imbo (HTTP POST). If this is the case it will be mentioned in the description of the transformation.

Auto rotate image based on EXIF data - t[]=autoRotate

This transformation will auto rotate the image based on EXIF data stored in the image. This transformation is rarely used per request, but is typically used by the Auto rotate image event listener when adding images to Imbo.

Examples:

  • t[]=autoRotate

Add an image border - t[]=border

This transformation will apply a border around the image.

Parameters:

color
Color of the border in hexadecimal. Defaults to 000000 (You can also specify short values like f00 (ff0000)).
width
Width of the border in pixels on the left and right sides of the image. Defaults to 1.
height
Height of the border in pixels on the top and bottom sides of the image. Defaults to 1.
mode
Mode of the border. Can be inline or outbound. Defaults to outbound. Outbound places the border outside of the image, increasing the dimensions of the image. inline paints the border inside of the image, retaining the original width and height of the image.

Examples:

  • t[]=border
  • t[]=border:mode=inline
  • t[]=border:color=000
  • t[]=border:color=f00,width=2,height=2

Expand the image canvas - t[]=canvas

This transformation can be used to change the canvas of the original image.

Parameters:

width
Width of the surrounding canvas in pixels. If omitted the width of <image> will be used.
height
Height of the surrounding canvas in pixels. If omitted the height of <image> will be used.
mode
The placement mode of the original image. free, center, center-x and center-y are available values. Defaults to free.
x
X coordinate of the placement of the upper left corner of the existing image. Only used for modes: free and center-y.
y
Y coordinate of the placement of the upper left corner of the existing image. Only used for modes: free and center-x.
bg
Background color of the canvas. Defaults to ffffff (also supports short values like f00 (ff0000)).

Examples:

  • t[]=canvas:width=200,mode=center
  • t[]=canvas:width=200,height=200,x=10,y=10,bg=000
  • t[]=canvas:width=200,height=200,x=10,mode=center-y
  • t[]=canvas:width=200,height=200,y=10,mode=center-x

Compress the image - t[]=compress

This transformation compresses images on the fly resulting in a smaller payload. It is advisable to only use this transformation in combination with an image type in the URL (for instance .jpg or .png). This transformation is not applied to images of type image/gif.

Parameters:

level
The level of the compression applied to the image. The effect this parameter has on the image depends on the type of the image. If the image in the response is an image/jpeg a high level means high quality, usually resulting in larger files. If the image in the response is an image/png a high level means high compression, usually resulting in smaller files. If you do not specify an image type in the URL the result of this transformation is not deterministic as clients have different preferences with regards to the type of images they want to receive (via the Accept request header).

Examples:

  • t[]=compress:level=40

Convert the image type - .jpg/.gif/.png

This transformation can be used to change the image type. It is not applied like the other transformations, but is triggered when specifying a custom extension to the <image>. Currently Imbo can convert to:

  • image/jpeg
  • image/png
  • image/gif

Examples:

  • curl http://imbo/users/<user>/images/<image>.gif
  • curl http://imbo/users/<user>/images/<image>.jpg
  • curl http://imbo/users/<user>/images/<image>.png

Crop the image - t[]=crop

This transformation is used to crop the image.

Parameters:

x
The X coordinate of the cropped region’s top left corner.
y
The Y coordinate of the cropped region’s top left corner.
width
The width of the crop in pixels.
height
The height of the crop in pixels.
mode

The crop mode (optional). Possible values are:

center
When using the center mode the x and y parameters are ignored, and the center of the cropped area is placed in the center of the original image.
center-x
Center the crop on the x-axis. Use the y parameter to control the upper edge of the crop.
center-y
Center the crop on the y-axis. Use the x parameter to control the left edge of the crop.

Examples:

  • t[]=crop:x=10,y=25,width=250,height=150
  • t[]=crop:width=100,height=100,mode=center
  • t[]=crop:width=50,height=50,mode=center-x,y=15
  • t[]=crop:width=50,height=50,mode=center-y,x=15

Make a gray scaled image - t[]=desaturate

This transformation desaturates the image (in practice, gray scales it).

Examples:

  • t[]=desaturate

Make a mirror image - t[]=flipHorizontally

This transformation flips the image horizontally.

Examples:

  • t[]=flipHorizontally

Flip the image upside down - t[]=flipVertically

This transformation flips the image vertically.

Examples:

  • t[]=flipVertically

Enforce a max size of an image - t[]=maxSize

This transformation will resize the image using the original aspect ratio. Two parameters are supported and at least one of them must be supplied to apply the transformation.

Note the difference from the resize transformation: given both width and height, the resulting image will not be the same width and height as specified unless the aspect ratio is the same.

Parameters:

width
The max width of the resulting image in pixels. If not specified the width will be calculated using the same aspect ratio as the original image.
height
The max height of the resulting image in pixels. If not specified the height will be calculated using the same aspect ratio as the original image.

Examples:

  • t[]=maxSize:width=100
  • t[]=maxSize:height=100
  • t[]=maxSize:width=100,height=50

Modulate the image - t[]=modulate

This transformation can be used to control the brightness, saturation and hue of the image.

Parameters:

b
Brightness of the image in percent. Defaults to 100.
s
Saturation of the image in percent. Defaults to 100.
h
Hue percentage. Defaults to 100.

Examples:

  • t[]=modulate:b=150
  • t[]=modulate:b=120,s=130,h=90

Make a progressive image - t[]=progressive

This transformation makes the image progressive.

Examples:

  • t[]=progressive

Resize the image - t[]=resize

This transformation will resize the image. Two parameters are supported and at least one of them must be supplied to apply the transformation.

Parameters:

width
The width of the resulting image in pixels. If not specified the width will be calculated using the same aspect ratio as the original image.
height
The height of the resulting image in pixels. If not specified the height will be calculated using the same aspect ratio as the original image.

Examples:

  • t[]=resize:width=100
  • t[]=resize:height=100
  • t[]=resize:width=100,height=50

Rotate the image - t[]=rotate

This transformation will rotate the image clock-wise.

Parameters:

angle
The number of degrees to rotate the image (clock-wise).
bg
Background color in hexadecimal. Defaults to 000000 (also supports short values like f00 (ff0000)).

Examples:

  • t[]=rotate:angle=90
  • t[]=rotate:angle=45,bg=fff

Apply a sepia color tone - t[]=sepia

This transformation will apply a sepia color tone transformation to the image.

Parameters:

threshold
Threshold ranges from 0 to QuantumRange and is a measure of the extent of the sepia toning. Defaults to 80

Examples:

  • t[]=sepia
  • t[]=sepia:threshold=70

Strip image properties and comments - t[]=strip

This transformation removes all properties and comments from the image. If you want to strip EXIF tags from the image for instance, this transformation will do that for you.

Examples:

  • t[]=strip

Create a thumbnail of the image - t[]=thumbnail

This transformation creates a thumbnail of <image>.

Parameters:

width
Width of the thumbnail in pixels. Defaults to 50.
height
Height of the thumbnail in pixels. Defaults to 50.
fit
Fit style. Possible values are: inset or outbound. Default to outbound.

Examples:

  • t[]=thumbnail
  • t[]=thumbnail:width=20,height=20,fit=inset

Create a vertical mirror image - t[]=transpose

This transformation transposes the image.

Examples:

  • t[]=transpose

Create a horizontal mirror image - t[]=transverse

This transformation transverses the image.

Examples:

  • t[]=transverse

Add a watermark to the image - t[]=watermark

This transformation can be used to apply a watermark on top of the original image.

Parameters:

img
Image identifier of the image to apply as watermark. Can be set to a default value in configuration by using <setDefaultImage>.
width
Width of the watermark image in pixels. If omitted the width of <img> will be used.
height
Height of the watermark image in pixels. If omitted the height of <img> will be used.
position
The placement of the watermark image. top-left, top-right, bottom-left, bottom-right and center are available values. Defaults to top-left.
x
Number of pixels in the X-axis the watermark image should be offset from the original position (defined by the position parameter). Supports negative numbers. Defaults to 0
y
Number of pixels in the Y-axis the watermark image should be offset from the original position (defined by the position parameter). Supports negative numbers. Defaults to 0

Examples:

  • t[]=watermark:img=f5f7851c40e2b76a01af9482f67bbf3f
  • t[]=watermark:img=f5f7851c40e2b76a01af9482f67bbf3f,width=200,x=5
  • t[]=watermark:img=f5f7851c40e2b76a01af9482f67bbf3f,height=50,x=-5,y=-5,position=bottom-right

If you want to set the default watermark image you will have to do so in the configuration:

<?php
return array(
    // ...

    'eventListeners' => array(
        'watermark' => function() {
            $transformation = new Imbo\Image\Transformation\Watermark();
            $transformation->setDefaultImage('some image identifier');

            return $transformation;
        },
    ),

    // ...
);

When you have specified a default watermark image you are not required to use the img option for the transformation, but if you do so it will override the default one.

Read the Docs v: 1.1.1
Versions
latest
develop
1.1.1
1.0.1
0.3.3
Downloads
PDF
HTML
Epub
On Read the Docs
Project Home
Builds

Free document hosting provided by Read the Docs.
PKsNDDimbo-1.1.1/usage/api.html Imbo’s API — Imbo 1.1.1 documentation

Imbo’s API

In this chapter you will learn more about how Imbo’s API works, and how you as a user are able to read from and write to Imbo. Most examples listed in this chapter will use cURL, so while playing around with the API it’s encouraged to have cURL easily available. For the sake of simplicity the access tokens and authentication information is not used in the examples. See the Access tokens and Signing write requests sections for more information regarding this.

Resources/endpoints

In this section you will find information on the different resources Imbo’s RESTful API expose, along with their capabilities:

Index resource - /

The index resource shows the version of the Imbo installation along with some external URL’s for Imbo-related information, and some internal URL’s for the available endpoints.

curl -H"Accept: application/json" http://imbo

results in:

{
  "version": "dev",
  "urls": {
    "site": "http://www.imbo-project.org",
    "source": "https://github.com/imbo/imbo",
    "issues": "https://github.com/imbo/imbo/issues",
    "docs": "http://docs.imbo-project.org"
  },
  "endpoints": {
    "status": "http://imbo/status",
    "stats": "http://imbo/stats",
    "user": "http://imbo/users/{publicKey}",
    "images": "http://imbo/users/{publicKey}/images",
    "image": "http://imbo/users/{publicKey}/images/{imageIdentifier}",
    "shortImageUrl": "http://imbo/s/{id}",
    "metadata": "http://imbo/users/{publicKey}/images/{imageIdentifier}/metadata"
  }
}

This resource does not support any extensions in the URI, so you will need to use the Accept header to fetch different representations of the data.

The index resource does not require any authentication per default.

Typical response codes:

  • 200 Hell Yeah

Note

The index resource is not cache-able.

Stats resource - /stats

Imbo provides an endpoint for fetching simple statistics about the data stored in Imbo.

curl http://imbo/stats.json

results in:

{
  "users": {
    "someuser": {
      "numImages": 11,
      "numBytes": 3817197
    },
    "someotheruser": {
      "numImages": 1,
      "numBytes": 81097
    }
  },
  "total": {
    "numImages": 12,
    "numUsers": 2,
    "numBytes": 3898294
  },
  "custom": {}
}

if the client making the request is allowed access.

Access control

The access control for the stats endpoint is controlled by an event listener, which is enabled per default, and only allows connections from 127.0.0.1 (IPv4) and ::1 (IPv6). Read more about how to configure this event listener in the Stats access event listener section.

Custom statistics

The stats resource enables users to attach custom statistics via event listeners by using the data model as a regular associative array. The following example attaches a simple event listener in the configuration file that populates some custom data in the statistics model:

<?php
return array(
    // ...

    'eventListeners' => array(
        'customStats' => array(
            'events' => array('stats.get'),
            'callback' => function($event) {
                // Fetch the model from the response
                $model = $event->getResponse()->getModel();

                // Set some values
                $model['someValue'] = 123;
                $model['someOtherValue'] = array(
                    'foo' => 'bar',
                );
                $model['someList'] = array(1, 2, 3);
            }
        ),
    ),

    // ...
);

When requesting the stats endpoint, the output will look like this:

{
  "users": {
    "someuser": {
      "numImages": 11,
      "numBytes": 3817197
    },
    "someotheruser": {
      "numImages": 1,
      "numBytes": 81097
    }
  },
  "total": {
    "numImages": 12,
    "numUsers": 2,
    "numBytes": 3898294
  },
  "custom": {
    "someValue": 123,
    "someOtherValue": {
      "foo": "bar"
    },
    "someList": [1, 2, 3]
  }
}

Use cases for this might be to simply store data in some backend in various events (for instance image.get or metadata.get) and then fetch these and display then when requesting the stats endpoint (stats.get).

Note

The stats resource is not cache-able.

Status resource - /status

Imbo includes a simple status resource that can be used with for instance monitoring software.

curl http://imbo/status.json

results in:

{
  "timestamp": "Tue, 24 Apr 2012 14:12:58 GMT",
  "database": true,
  "storage": true
}

where timestamp is the current timestamp on the server, and database and storage are boolean values informing of the status of the current database and storage adapters respectively. If both are true the HTTP status code is 200 OK, and if one or both are false the status code is 503. When the status code is 503 the reason phrase will inform you whether it’s the database or the storage adapter (or both) that is having issues. As soon as the status code does not equal 200 Imbo will no longer work as expected.

The reason for adapter failures depends on what kind of adapter you are using. The file system storage adapter will for instance return a failure if it can no longer write to the storage directory. The MongoDB and Doctrine database adapters will fail if they can no longer connect to the server they are configured to communicate with.

Typical response codes:

  • 200 OK
  • 503 Database error
  • 503 Storage error
  • 503 Storage and database error

Note

The status resource is not cache-able.

User resource - /users/<user>

The user resource represents a single user on the current Imbo installation. The output contains basic user information:

curl http://imbo/users/<user>.json

results in:

{
  "publicKey": "<user>",
  "numImages": 42,
  "lastModified": "Wed, 18 Apr 2012 15:12:52 GMT"
}

where publicKey is the public key of the user (the same used in the URI of the request), numImages is the number of images the user has stored in Imbo and lastModified is when the user last uploaded or deleted an image, or when the user last updated metadata of an image. If the user has not added any images yet, the lastModified value will be set to the current time on the server.

Typical response codes:

  • 200 OK
  • 304 Not modified
  • 404 Public key not found

Images resource - /users/<user>/images

The images resource is the collection of images owned by a specific user. This resource can be used to search added images, and is also used to add new images to a collection.

Add an image

To be able to display images stored in Imbo you will first need to add one or more images. This is done by requesting this endpoint with an image attached to the request body, and changing the HTTP METHOD to POST. The body of the response for such a request contains a JSON object containing the image identifier of the added image:

curl -XPOST http://imbo/users/<user>/images --data-binary @<file to add>

results in:

{
  "imageIdentifier": "<imageIdentifier>",
  "width": <width>,
  "height": <height>,
  "extension": "<extension>"
}

The <imageIdentifier> in the response is the identifier of the added image. This is used with the image resource<>. The response body also contains the width, height and extension of the image that was just added.

Typical response codes:

  • 200 OK
  • 201 Created
  • 400 Bad request

Get image collections

The images resource can also be used to gather information on which images a user owns. This is done by requesting this resource using HTTP GET. Supported query parameters are:

page
The page number. Defaults to 1.
limit
Number of images per page. Defaults to 20.
metadata
Whether or not to include metadata in the output. Defaults to 0, set to 1 to enable.
from
Fetch images starting from this Unix timestamp.
to
Fetch images up until this timestamp.
fields[]
An array with fields to display. When not specified all fields will be displayed.
sort[]
An array with fields to sort by. The direction of the sort is specified by appending asc or desc to the field, delimited by :. If no direction is specified asc will be used. Example: ?sort[]=size&sort[]=width:desc is the same as ?sort[]=size:asc&sort[]=width:desc. If no sort is specified Imbo will sort by the date the images was added, in a descending fashion.
ids[]
An array of image identifiers to filter the results by.
checksums[]
An array of image checksums to filter the results by.
curl "http://imbo/users/<user>/images.json?limit=1&metadata=1"

results in:

{
  "search": {
    "hits": 3,
    "page": 1,
    "limit": 1,
    "count": 1
  },
  "images": [
    {
      "added": "Mon, 10 Dec 2012 11:57:51 GMT",
      "extension": "png",
      "height": 77,
      "imageIdentifier": "<image>",
      "metadata": {
        "key": "value",
        "foo": "bar"
      },
      "mime": "image/png",
      "publicKey": "<user>",
      "size": 6791,
      "updated": "Mon, 10 Dec 2012 11:57:51 GMT",
      "width": 1306
    }
  ]
}

The search object is data related to pagination, where hits is the number of images found by your query, page is the current page, limit is the current limit, and count is the number of images in the visible collection.

The images list contains image objects, where added is a formatted date of when the image was added to Imbo, extension is the original image extension, height is the height of the image in pixels, imageIdentifier is the image identifier (MD5 checksum of the file itself), metadata is a JSON object containing metadata attached to the image, mime is the mime type of the image, publicKey is the public key of the user who owns the image, size is the size of the image in bytes, updated is a formatted date of when the image was last updated (read: when metadata attached to the image was last updated, as the image itself never changes), and width is the width of the image in pixels. The fact that the image identifier is the MD5 checksum of the image is an implementation detail and might change in the future.

The metadata field is only available if you used the metadata query parameter described above.

Typical response codes:

  • 200 OK
  • 304 Not modified
  • 404 Public key not found

Image resource - /users/<user>/images/<image>

The image resource represents specific images owned by a user. This resource is used to retrieve and remove images. It’s also responsible for transforming the images based on the transformation parameters in the query.

Fetch images

Fetching images added to Imbo is done by requesting the image identifiers (checksum) of the images.

curl http://imbo/users/<user>/images/<image>

results in:

<binary data of the original image>

When fetching images Imbo also sends a set of custom HTTP response headers related to the image:

X-Imbo-Originalextension: png
X-Imbo-Originalmimetype: image/png
X-Imbo-Originalfilesize: 45826
X-Imbo-Originalheight: 390
X-Imbo-Originalwidth: 380
X-Imbo-ShortUrl: http://imbo/s/w7CiqDM

These are all related to the image that was just requested.

How to use this resource to generate image transformations is described in the Transforming images on the fly chapter.

Typical response codes:

  • 200 OK
  • 304 Not modified
  • 400 Bad request
  • 404 Image not found

Delete images

Deleting images from Imbo is accomplished by requesting the image URIs using HTTP DELETE. All metadata attached to the image will be removed as well.

curl -XDELETE http://imbo/users/<user>/images/<image>

results in:

{
  "imageIdentifier": "<image>"
}

where <image> is the image identifier of the image that was just deleted (the same as the one used in the URI).

Typical response codes:

  • 200 OK
  • 400 Bad request
  • 404 Image not found

ShortURL resource - /s/<id>

Images in Imbo have short URLs associated with them, which are generated on request when you access an image (with or without image transformations) for the first time. These URLs do not take any query parameters and can be used in place for original image URLs. To fetch these URLs you can request an image using HTTP HEAD, then look for the X-Imbo-ShortUrl header in the response:

curl -Ig "http://imbo/users/<user>/images/<image>?t[]=thumbnail&t[]=desaturate&t[]=border&accessToken=f3fa1d9f0649cfad61e840a6e09b156e851858799364d1d8ee61b386e10b0c05"|grep Imbo

results in (some headers omitted):

X-Imbo-OriginalMimeType: image/gif
X-Imbo-OriginalWidth: 771
X-Imbo-OriginalHeight: 771
X-Imbo-OriginalFileSize: 152066
X-Imbo-OriginalExtension: gif
X-Imbo-ShortUrl: http://imbo/s/3VEFrpB
X-Imbo-ImageIdentifier: 4492acb937a1f056ae43509bc7f85d21

The value of the X-Imbo-ShortUrl can be used to request the image with the applied transformations, and does not require an access token query parameter.

The format of the random ID part of the short URL can be matched with the following regular expression:

/^[a-zA-Z0-9]{7}$/

There are some caveats regarding the short URLs:

  1. If the URL used to generate the short URL contained an image extension, content negotiation will not be applied to the short URL. You will always get the mime type associated with the extension used to generate the short URL.
  2. If the URL used to generate the short URL did not contain an image extension you can use the Accept header to decide the mime type of the generated image when requesting the short URL.
  3. Short URLs do not support extensions, so you can not append .jpg to force image/jpeg. If you need to make sure the image is always a JPEG, simply append .jpg to the URL when generating the short URL.

Note

In Imbo only images have short URL’s

Metadata resource - /users/<user>/images/<image>/metadata

Imbo can also be used to attach metadata to the stored images. The metadata is based on a simple key => value model, for instance:

  • category: Music
  • band: Koldbrann
  • genre: Black metal
  • country: Norway

Values can be nested key => value pairs.

Adding/replacing metadata

To add (or replace all existing metadata) on an image a client should make a request against this resource using HTTP PUT with the metadata attached in the request body as a JSON object.

curl -XPUT http://imbo/users/<user>/images/<image>/metadata.json -d '{
  "beer":"Dark Horizon First Edition",
  "brewery":"Nøgne Ø",
  "style":"Imperial Stout"
}'

results in:

{
  "imageIdentifier": "<image>"
}

where <image> is the image that just got updated.

Note

When using the Doctrine database adapter, metadata keys can not contain ::.

Typical response codes:

  • 200 OK
  • 400 Bad request
  • 400 Invalid metadata (when using the Doctrine adapter, and keys contain ::)
  • 404 Image not found

Partially updating metadata

Partial updates to metadata attached to an image is done by making a request with HTTP POST and attaching metadata to the request body as a JSON object. If the object contains keys that already exists in the metadata on the server the old values will be replaced by the ones found in the request body. New keys will be added to the metadata.

curl -XPOST http://imbo/users/<user>/images/<image>/metadata.json -d '{
  "ABV":"16%",
  "score":"100/100"
}'

results in:

{
  "imageIdentifier": "<image>"
}

where <image> is the image that just got updated.

Note

When using the Doctrine database adapter, metadata keys can not contain ::.

Typical response codes:

  • 200 OK
  • 400 Bad request
  • 400 Invalid metadata (when using the Doctrine adapter, and keys contain ::)
  • 404 Image not found

Fetch metadata

Requests using HTTP GET on this resource returns all metadata attached to an image.

curl http://imbo/users/<user>/images/<image>/metadata.json

results in:

{}

when there is no metadata stored, or for example

{
  "category": "Music",
  "band": "Koldbrann",
  "genre": "Black metal",
  "country": "Norway"
}

if the image has metadata attached to it.

Typical response codes:

  • 200 OK
  • 304 Not modified
  • 404 Image not found

Remove metadata

To remove metadata attached to an image a request using HTTP DELETE can be made.

curl -XDELETE http://imbo/users/<user>/images/<image>/metadata.json

results in:

{
  "imageIdentifier":"<image>"
}

where <image> is the image identifier of the image that just got all its metadata deleted.

Typical response codes:

  • 200 OK
  • 400 Bad request
  • 404 Image not found

Access tokens

Access tokens are enforced by an event listener that is enabled in the default configuration file. The access tokens are used to prevent DoS attacks so think twice before you disable the event listener.

An access token, when enforced by the event listener, must be supplied in the URI using the accessToken query parameter and without it, most GET and HEAD requests will result in a 400 Bad request response. The value of the accessToken parameter is a Hash-based Message Authentication Code (HMAC). The code is a SHA-256 hash of the URI itself using the private key of the user as the secret key. It is very important that the URI is not URL-encoded when generating the hash. Below is an example on how to generate a valid access token for a specific image using PHP:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<?php
$publicKey  = "<user>";         // The public key of the user
$privateKey = "<secret value>"; // The private key of the user
$image      = "<image>";        // The image identifier

// Image transformations
$query = implode("&", array(
    "t[]=thumbnail:width=40,height=40,fit=outbound",
    "t[]=border:width=3,height=3,color=000",
    "t[]=canvas:width=100,height=100,mode=center"
));

// The URI
$uri = sprintf("http://imbo/users/%s/images/%s?%s", $publicKey, $image, $query);

// Generate the token
$accessToken = hash_hmac("sha256", $uri, $privateKey);

// Output the URI with the access token
echo sprintf("%s&accessToken=%s", $uri, $accessToken);

and Python:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
from hashlib import sha256
import hmac

publicKey  = "<user>"         # The public key of the user
privateKey = "<secret value>" # The private key of the user
image      = "<image>"        # The image identifier

# Image transformations
query = "&".join([
    "t[]=thumbnail:width=40,height=40,fit=outbound",
    "t[]=border:width=3,height=3,color=000",
    "t[]=canvas:width=100,height=100,mode=center"
])

# The URI
uri = "http://imbo/users/%s/images/%s?%s" % (publicKey, image, query)

# Generate the token
accessToken = hmac.new(privateKey, uri, sha256)

# Output the URI with the access token
print "%s&accessToken=%s" % (uri, accessToken.hexdigest())

and Ruby:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
require "digest"

publicKey  = "<user>"         # The public key of the user
privateKey = "<secret value>" # The private key of the user
image      = "<image>"        # The image identifier

# Image transformations
query = [
    "t[]=thumbnail:width=40,height=40,fit=outbound",
    "t[]=border:width=3,height=3,color=000",
    "t[]=canvas:width=100,height=100,mode=center"
].join("&")

# The URI
uri = "http://imbo/users/#{publicKey}/images/#{image}?#{query}"

# Generate the token
accessToken = Digest::HMAC.hexdigest(uri, privateKey, Digest::SHA256)

# Output the URI with the access token
puts "#{uri}&accessToken=#{accessToken}"

If the event listener enforcing the access token check is removed, Imbo will ignore the accessToken query parameter completely. If you wish to implement your own form of access token you can do this by implementing an event listener of your own (see Writing an event listener for more information).

Signing write requests

To be able to write to Imbo the user agent will have to specify two request headers: X-Imbo-Authenticate-Signature and X-Imbo-Authenticate-Timestamp.

X-Imbo-Authenticate-Signature is, like the access token, an HMAC (also using SHA-256 and the private key of the user).

The data for the hash is generated using the following elements:

  • HTTP method (PUT, POST or DELETE)
  • The URI
  • Public key of the user
  • GMT timestamp (YYYY-MM-DDTHH:MM:SSZ, for instance: 2011-02-01T14:33:03Z)

These elements are concatenated in the above order with | as a delimiter character, and a hash is generated using the private key of the user. The following snippet shows how this can be accomplished in PHP when deleting an image:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php
$publicKey  = "<user>";                 // The public key of the user
$privateKey = "<secret value>";         // The private key of the user
$timestamp  = gmdate("Y-m-d\TH:i:s\Z"); // Current timestamp (UTC)
$image      = "<image>";                // The image identifier
$method     = "DELETE";                 // HTTP method to use

// The URI
$uri = sprintf("http://imbo/users/%s/images/%s", $publicKey, $image);

// Data for the hash
$data = implode("|", array($method, $uri, $publicKey, $timestamp));

// Generate the token
$signature = hash_hmac("sha256", $data, $privateKey);

// Request the URI
$response = file_get_contents($uri, false, stream_context_create(array(
    "http" => array(
        "method" => $method,
        "header" => array(
            "X-Imbo-Authenticate-Signature: " . $signature,
            "X-Imbo-Authenticate-Timestamp: " . $timestamp,
        ),
    ),
)));

and Python (using the Requests library):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import hmac, requests
from hashlib import sha256
from datetime import datetime

publicKey  = "<user>"                                         # The public key of the user
privateKey = "<secret value>"                                 # The private key of the user
timestamp  = datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ") # Current timestamp (UTC)
image      = "<image>"                                        # The image identifier
method     = "DELETE"                                         # HTTP method to use

# The URI
uri = "http://imbo/users/%s/images/%s" % (publicKey, image)

# Data for the hash
data = "|".join([method, uri, publicKey, timestamp])

# Generate the token
signature = hmac.new(privateKey, data, sha256).hexdigest()

# Request the URI
response = requests.delete(uri, headers = {
    "X-Imbo-Authenticate-Signature": signature,
    "X-Imbo-Authenticate-Timestamp": timestamp
})

and Ruby (using the httpclient gem):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
require "digest"
require "httpclient"

publicKey  = "<user>"                                    # The public key of the user
privateKey = "<secret value>"                            # The private key of the user
timestamp  = Time.now.utc.strftime("%Y-%m-%dT%H:%M:%SZ") # Current timestamp (UTC)
image      = "<image>"                                   # The image identifier
method     = "DELETE"                                    # HTTP method to use

# The URI
uri = "http://imbo/users/#{publicKey}/images/#{image}"

# Data for the hash
data = [method, uri, publicKey, timestamp].join("|")

# Generate the token
signature = Digest::HMAC.hexdigest(data, privateKey, Digest::SHA256)

# Request the URI
client = HTTPClient.new
response = client.delete(uri, {}, {
    "X-Imbo-Authenticate-Signature" => signature,
    "X-Imbo-Authenticate-Timestamp" => timestamp
})

Imbo requires that X-Imbo-Authenticate-Timestamp is within ± 120 seconds of the current time on the server.

As with the access token the signature check is enforced by an event listener that can also be disabled. If you disable this event listener you effectively open up for writing from anybody, which you probably don’t want to do.

If you want to implement your own authentication paradigm you can do this by creating a custom event listener.

Supported content types

Imbo currently responds with images (jpg, gif and png), JSON and XML, but only accepts images (jpg, gif and png) and JSON as input.

Imbo will do content negotiation using the Accept header found in the request, unless you specify a file extension, in which case Imbo will deliver the type requested without looking at the Accept header.

The default content type for non-image responses is JSON. Examples in this chapter uses the .json extension. Change it to .xml to get the XML representation instead. You can also skip the extension and force a specific content type using the Accept header:

curl http://imbo/status.json

and

curl -H "Accept: application/json" http://imbo/status

will end up with the same content type. Use application/xml for XML.

If you use JSON you can wrap the content in a function (JSONP) by using one of the following query parameters:

  • callback
  • jsonp
  • json
curl http://imbo/status.json?callback=func

will result in:

func(
  {
    "date": "Mon, 05 Nov 2012 19:18:40 GMT",
    "database": true,
    "storage": true
  }
)

For images the default mime-type is the original mime-type of the image. If you add an image/gif image and fetch that image with Accept: */* or Accept: image/* the mime-type of the image returned will be image/gif. To choose a different mime type either change the Accept header, or use .jpg or .png (for image/jpeg and image/png respectively).

Cache headers

Most responses from Imbo includes a set of cache-related headers that enables shared caches and user agents to cache content.

Cache-Control

Some responses from Imbo are not cache-able. These will typically include Cache-Control: max-age=0, no-store, private. The following resources are not cache-able:

All other resources will include Cache-Control: public. The image and short url resources will also set a max-age, resulting in the following header: Cache-Control: max-age=31536000, public.

ETag

Imbo provides entity tags for cache validation mechanisms. User agents can use the ETag response header to do conditional requests further down the road (by specifying the original ETag value in the If-None-Match request header). This results in saved bandwidth as web caches and Imbo servers no longer need to send the response body, as the one cached by the user agent can be re-used. This is achieved by sending 304 Not Modified back to the user agent, instead of 200 OK.

The following resources in Imbo will include an ETag:

The value of the ETag header is simply the MD5 sum of the content in the response body, enclosed in quotes. For instance ETag: "fd2fd87a2f5288be31c289e70e916123".

Last-Modified

Imbo also includes a Last-Modified response header for resources that has a know last modification date, and these resources are:

User agents can use the value of the Last-Modified header in the If-Modified-Since request header to make a conditional request. The value of the Last-Modified header is an HTTP-date, for instance Last-Modified: Wed, 12 Feb 2014 09:46:02 GMT.

Errors

When an error occurs Imbo will respond with a fitting HTTP response code along with a JSON object explaining what went wrong.

curl -g "http://imbo/users/<user>/foobar"

results in:

{
  "error": {
    "imboErrorCode": 0,
    "date": "Wed, 12 Dec 2012 21:15:01 GMT",
    "message": "Not Found",
    "code": 404
  }
}

The code is the HTTP response code, message is a human readable error message, date is when the error occurred on the server, and imboErrorCode is an internal error code that can be used by the user agent to distinguish between similar errors (such as 400 Bad request).

The JSON object will also include imageIdentifier if the request was made against the image or the metadata resource.

Read the Docs v: 1.1.1
Versions
latest
develop
1.1.1
1.0.1
0.3.3
Downloads
PDF
HTML
Epub
On Read the Docs
Project Home
Builds

Free document hosting provided by Read the Docs.
PKsNDj'imbo-1.1.1/.doctrees/environment.pickle(csphinx.environment BuildEnvironment qoq}q(Udlfilesqcsphinx.util FilenameUniqDict q)qc__builtin__ set q]RqbUappq NU _warnfuncq NUtitlesq }q (Xindexq cdocutils.nodes title q)q}q(U rawsourceqUU attributesq}q(Udupnamesq]Uclassesq]Ubackrefsq]Uidsq]Unamesq]uUchildrenq]qcdocutils.nodes Text qXImbo - Image boxqq}q(hXImbo - Image boxqUparentq hubaUtagnameq!Utitleq"ubX usage/apiq#h)q$}q%(hUh}q&(h]h]h]h]h]uh]q'hX Imbo's APIq(q)}q*(hX Imbo's APIq+h h$ubah!h"ubXdevelop/cache_adaptersq,h)q-}q.(hUh}q/(h]h]h]h]h]uh]q0hXCache adaptersq1q2}q3(hXCache adaptersq4h h-ubah!h"ubXinstallation/event_listenersq5h)q6}q7(hUh}q8(h]h]h]h]h]uh]q9hX5Customize your Imbo installation with event listenersq:q;}q<(hX5Customize your Imbo installation with event listenersq=h h6ubah!h"ubXinstallation/requirementsq>h)q?}q@(hUh}qA(h]h]h]h]h]uh]qBhX RequirementsqCqD}qE(hX RequirementsqFh h?ubah!h"ubXdevelop/image_transformationsqGh)qH}qI(hUh}qJ(h]h]h]h]h]uh]qKhX(Implement your own image transformationsqLqM}qN(hX(Implement your own image transformationsqOh hHubah!h"ubXdevelop/contributingqPh)qQ}qR(hUh}qS(h]h]h]h]h]uh]qThXContributing to ImboqUqV}qW(hXContributing to ImboqXh hQubah!h"ubXdevelop/custom_adaptersqYh)qZ}q[(hUh}q\(h]h]h]h]h]uh]q]hX2Implement your own database and/or storage adapterq^q_}q`(hX2Implement your own database and/or storage adapterqah hZubah!h"ubXinstallation/installationqbh)qc}qd(hUh}qe(h]h]h]h]h]uh]qfhX Installationqgqh}qi(hX Installationqjh hcubah!h"ubXinstallation/configurationqkh)ql}qm(hUh}qn(h]h]h]h]h]uh]qohX Configurationqpqq}qr(hX Configurationqsh hlubah!h"ubXusage/image-transformationsqth)qu}qv(hUh}qw(h]h]h]h]h]uh]qxhXTransforming images on the flyqyqz}q{(hXTransforming images on the flyq|h huubah!h"ubXdevelop/event_listenersq}h)q~}q(hUh}q(h]h]h]h]h]uh]qhX'Working with events and event listenersqq}q(hX'Working with events and event listenersqh h~ubah!h"ubuU domaindataq}q(Ustdq}q(UversionqKU anonlabelsq}q(Xstatus-resourceqh#Ustatus-resourceqXdatabase-setupqhbUdatabase-setupqXthumbnail-transformationqhtUthumbnail-transformationqX auto-rotate-image-event-listenerqh5U auto-rotate-image-event-listenerqUmodindexqU py-modindexUXmax-size-transformationqhtUmax-size-transformationqXmodulate-transformationqhtUmodulate-transformationqXflip-vertically-transformationqhtUflip-vertically-transformationqXimage-transformationsqhtUimage-transformationsqXfilesystem-storage-adapterqhkUfilesystem-storage-adapterqXcustom-image-transformationsqhGUcustom-image-transformationsqXindex-resourceqh#Uindex-resourceqXdefault-storage-adapterqhkUdefault-storage-adapterqXcrop-transformationqhtUcrop-transformationqX git-cloneqhbU git-cloneqXthe-event-objectqh}Uthe-event-objectqXimagick-event-listenerqh5Uimagick-event-listenerqXcustom-event-listenersqh}Ucustom-event-listenersqXusing-composerqhbUusing-composerqXtranspose-transformationqhtUtranspose-transformationqX contributingqhPU contributingqXgridfs-storage-adapterqhkUgridfs-storage-adapterqXcors-event-listenerqh5Ucors-event-listenerqXsepia-transformationqhtUsepia-transformationqXdefault-database-adapterqhkUdefault-database-adapterqXprogressive-transformationqhtUprogressive-transformationqX apc-cacheqh,U apc-cacheqXcanvas-transformationqhtUcanvas-transformationqÆXcompress-transformationqhtUcompress-transformationqņXmax-image-size-event-listenerqh5Umax-image-size-event-listenerqdžXstrip-transformationqhtUstrip-transformationqɆUgenindexqhUXmemcached-cacheqh,Umemcached-cacheq̆X access-tokensqh#U access-tokensqΆXimage-transformations-configqhkUimage-transformations-configqІXsigning-write-requestsqh#Usigning-write-requestsq҆Xborder-transformationqhtUborder-transformationqԆXresize-transformationqhtUresize-transformationqֆXimage-resourceqh#Uimage-resourceq؆Xauthenticate-event-listenerqh5Uauthenticate-event-listenerqچX flip-horizontally-transformationqhtU flip-horizontally-transformationq܆Xmetadata-resourceqh#Umetadata-resourceqކXs3-storage-adapterqhkUs3-storage-adapterqXimages-resourceqh#Uimages-resourceqX configurationqhkU configurationqXtransverse-transformationqhtUtransverse-transformationqXmongodb-database-adapterqhkUmongodb-database-adapterqXcustom-cache-adapterqh,Ucustom-cache-adapterqXstorage-configurationqhkUstorage-configurationqXdatabase-configurationqhkUdatabase-configurationqUsearchqUsearchUX installationqhbU installationqXstats-access-event-listenerqh5Ustats-access-event-listenerqXauto-rotate-transformationqhtUauto-rotate-transformationqXdoctrine-database-adapterqhkUdoctrine-database-adapterqXconfiguration-event-listenersqhkUconfiguration-event-listenersqXrotate-transformationqhtUrotate-transformationqXstats-resourceqh#Ustats-resourceqXconvert-transformationqhtUconvert-transformationqXaccess-token-event-listenerrh5Uaccess-token-event-listenerrXdesaturate-transformationrhtUdesaturate-transformationrXwatermark-transformationrhtUwatermark-transformationrX)configuration-event-listener-initializersrhkU)configuration-event-listener-initializersrX user-resourcerh#U user-resourcer Xshorturl-resourcer h#Ushorturl-resourcer uUlabelsr }r (hh#hXStatus resource - /statushhbhXDatabase setuphhthX/Create a thumbnail of the image - t[]=thumbnailhh5hXAuto rotate imagehU py-modindexUcsphinx.locale _TranslationProxy rcsphinx.locale mygettext rU Module IndexrrjjrbhhthX,Enforce a max size of an image - t[]=maxSizehhthX!Modulate the image - t[]=modulatehhthX/Flip the image upside down - t[]=flipVerticallyhhthXTransforming images on the flyhhkhX FilesystemhhGhX(Implement your own image transformationshh#hXIndex resource - /hhkhXGridFShhthXCrop the image - t[]=crophhbhXUsing git clonehh}hXThe event objecthh5hXImagickhh}hXWriting an event listenerhhbhXUsing composerhhthX.Create a vertical mirror image - t[]=transposehhPhXContributing to ImbohhkhXGridFShh5hX$CORS (Cross-Origin Resource Sharing)hhthX$Apply a sepia color tone - t[]=sepiahhkhXMongoDBhhthX*Make a progressive image - t[]=progressivehh,hXAPChhthX$Expand the image canvas - t[]=canvashhthX!Compress the image - t[]=compresshh5hXMax image sizehhthX/Strip image properties and comments - t[]=striphhUjjUIndexrrjjrbhh,hX Memcachedhh#hX Access tokenshhkhX7Event listener initializers - eventListenerInitializershh#hXSigning write requestshhthX Add an image border - t[]=borderhhthXResize the image - t[]=resizehh#hX-Image resource - /users//images/hh5hX AuthenticatehhthX*Make a mirror image - t[]=flipHorizontallyhh#hX9Metadata resource - /users//images//metadatahhkhXAmazon Simple Storage Servicehh#hX&Images resource - /users//imageshhkhX ConfigurationhhthX1Create a horizontal mirror image - t[]=transversehhkhXMongoDBhh,hX Implement a custom cache adapterhhkhXStorage configuration - storagehhkhX!Database configuration - databasehhUjjU Search PagerrjjrbhhbhX Installationhh5hX Stats accesshhthX5Auto rotate image based on EXIF data - t[]=autoRotatehhkhXDoctrinehhkhX Event listeners - eventListenershhthXRotate the image - t[]=rotatehh#hXStats resource - /statshhthX'Convert the image type - .jpg/.gif/.pngjh5jX Access tokenjhtjX)Make a gray scaled image - t[]=desaturatejhtjX,Add a watermark to the image - t[]=watermarkjhkjX7Event listener initializers - eventListenerInitializersjh#j XUser resource - /users/j h#j XShortURL resource - /s/uU progoptionsr}rUobjectsr}ruUc}r(j}rhKuUpyr}r (j}r!Umodulesr"}r#hKuUjsr$}r%(j}r&hKuUrstr'}r((j}r)hKuUcppr*}r+(j}r,hKuUphpr-}r.(j}r/hKU namespacesr0}r1uuU glob_toctreesr2h]Rr3U reread_alwaysr4h]Rr5U doctreedirr6XF/var/build/user_builds/imbo/checkouts/1.1.1/docs/_build/html/.doctreesr7Uversioning_conditionr8U citationsr9}hK*Usrcdirr:X0/var/build/user_builds/imbo/checkouts/1.1.1/docsr;Uconfigr<csphinx.config Config r=)r>}r?(Uhtml_theme_optionsr@}UprojectrAXImborBU html_stylerCNU source_suffixrDU.rstUlanguagerEXenrFU copyrightrGX2011-2014, Christer EdvartsenUtemplates_pathrH]rI(UA/home/docs/checkouts/readthedocs.org/readthedocs/templates/sphinxrJjJU _templatesrKeU overridesrL}rMjEjFsUexclude_patternsrN]rOU_buildrPaU master_docrQUindexrRUhtmlhelp_basenamerSUImbodochU1.1U extensionsrT]rU(Usphinxcontrib.phpdomainrVUreadthedocs_ext.readthedocsrWU"readthedocs_ext.readthedocshtmldirrXjWjXeUhtml_static_pathrY]rZ(U_staticr[UI/home/docs/checkouts/readthedocs.org/readthedocs/templates/sphinx/_staticr\j\eU html_themer]Usphinx_rtd_themer^Ureleaser_U1.1.1r`Uhtml_theme_pathra]rb(U_themesrcjJjJeUsetuprdNU html_contextre}rf(U using_themej]j^Ucurrent_versionrgj`U canonical_urlUUPRODUCTION_DOMAINUreadthedocs.orgU github_userUimborhU new_themeUanalytics_codeUUsingle_versionUdisplay_githubU downloads]ri(UPDFrjU5https://media.readthedocs.org/pdf/imbo/1.1.1/imbo.pdfrkUHTMLU9https://media.readthedocs.org/htmlzip/imbo/1.1.1/imbo.ziprlUEpubU7https://media.readthedocs.org/epub/imbo/1.1.1/imbo.epubrmeU READTHEDOCSU conf_py_pathU/docs/U github_repojhU rtd_languageXenUslugrnjhUapi_hostUhttps://readthedocs.orgUnamerojBUversions]rp(UlatestU /en/latest/rqUdevelopU /en/develop/rrj`U /en/1.1.1/rsU1.0.1U /en/1.0.1/rtU0.3.3U /en/0.3.3/rueUgithub_versionj`U MEDIA_URLrvUhttps://media.readthedocs.org/uubUmetadatarw}rx(h }h#}h,}h5}h>}hG}hP}hY}hb}hk}ht}h}}uUversionchangesry}Utoc_num_entriesrz}r{(h Kh#Kh,Kh5K h>KhGKhPKhYKhbK hkKhtKh}KuUimagesr|h)r}h]Rr~bUnumbered_toctreesrh]RrU found_docsrh]r(h h#h,h5h>hGhPhYhbhkhth}eRrU longtitlesr}r(h hh#h$h,h-h5h6h>h?hGhHhPhQhYhZhbhchkhlhthuh}h~uU dependenciesr}r(h,h]rX3develop/../../library/Imbo/Cache/CacheInterface.phpraRrh#h]r(X)usage/../examples/generateAccessToken.phprX/usage/../examples/generateSignatureForDelete.rbrX(usage/../examples/generateAccessToken.pyrX(usage/../examples/generateAccessToken.rbrX/usage/../examples/generateSignatureForDelete.pyrX0usage/../examples/generateSignatureForDelete.phpreRrhbh]r(X+installation/../../setup/doctrine.mysql.sqlrX1installation/../../config/imbo.lighttpd.conf.distrX,installation/../../setup/doctrine.sqlite.sqlrX/installation/../../config/imbo.apache.conf.distrX.installation/../../config/imbo.nginx.conf.distreRrh}h]rX>develop/../../library/Imbo/EventListener/ListenerInterface.phpraRruUtoctree_includesr}rh ]r(Xinstallation/requirementsrXinstallation/installationrXinstallation/configurationrXinstallation/event_listenersrX usage/apirXusage/image-transformationsrXdevelop/event_listenersrXdevelop/custom_adaptersrXdevelop/image_transformationsrXdevelop/cache_adaptersrXdevelop/contributingresU temp_datar}Utocsr}r(h cdocutils.nodes bullet_list r)r}r(hUh}r(h]h]h]h]h]uh]rcdocutils.nodes list_item r)r}r(hUh}r(h]h]h]h]h]uh jh]r(csphinx.addnodes compact_paragraph r)r}r(hUh}r(h]h]h]h]h]uh jh]rcdocutils.nodes reference r)r}r(hUh}r(U anchornameUUrefurih h]h]h]h]h]Uinternaluh jh]rhXImbo - Image boxrr}r(hhh jubah!U referencerubah!Ucompact_paragraphrubj)r}r(hUh}r(h]h]h]h]h]uh jh]r(j)r}r(hUh}r(h]h]h]h]h]uh jh]r(j)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU#installation-guideUrefurih h]h]h]h]h]Uinternaluh jh]rhXInstallation guiderr}r(hXInstallation guideh jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jh]rcsphinx.addnodes toctree r)r}r(hUh}r(UnumberedKUparenth U titlesonlyUglobh]h]h]h]h]Uentries]r(NjrNjrNjrNjreUhiddenUmaxdepthKU includefiles]r(jjjjeU includehiddenuh jh]h!Utoctreerubah!U bullet_listrubeh!U list_itemrubj)r}r(hUh}r(h]h]h]h]h]uh jh]r(j)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU#end-user-guideUrefurih h]h]h]h]h]Uinternaluh jh]rhXEnd user guiderr}r(hXEnd user guideh jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(UnumberedKUparenth U titlesonlyUglobh]h]h]h]h]Uentries]r(NjrNjreUhiddenUmaxdepthKU includefiles]r(jjeU includehiddenuh jh]h!jubah!jubeh!jubj)r}r(hUh}r(h]h]h]h]h]uh jh]r(j)r }r (hUh}r (h]h]h]h]h]uh jh]r j)r }r(hUh}r(U anchornameU#extending-customizing-imboUrefurih h]h]h]h]h]Uinternaluh j h]rhXExtending/customizing Imborr}r(hXExtending/customizing Imboh j ubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(UnumberedKUparenth U titlesonlyUglobh]h]h]h]h]Uentries]r(NjrNjrNjrNjrNjr eUhiddenUmaxdepthKU includefiles]r!(jjjjjeU includehiddenuh jh]h!jubah!jubeh!jubeh!jubeh!jubah!jubh#j)r"}r#(hUh}r$(h]h]h]h]h]uh]r%j)r&}r'(hUh}r((h]h]h]h]h]uh j"h]r)(j)r*}r+(hUh}r,(h]h]h]h]h]uh j&h]r-j)r.}r/(hUh}r0(U anchornameUUrefurih#h]h]h]h]h]Uinternaluh j*h]r1hX Imbo's APIr2r3}r4(hh+h j.ubah!jubah!jubj)r5}r6(hUh}r7(h]h]h]h]h]uh j&h]r8(j)r9}r:(hUh}r;(h]h]h]h]h]uh j5h]r<(j)r=}r>(hUh}r?(h]h]h]h]h]uh j9h]r@j)rA}rB(hUh}rC(U anchornameU#resources-endpointsUrefurih#h]h]h]h]h]Uinternaluh j=h]rDhXResources/endpointsrErF}rG(hXResources/endpointsrHh jAubah!jubah!jubj)rI}rJ(hUh}rK(h]h]h]h]h]uh j9h]rL(j)rM}rN(hUh}rO(h]h]h]h]h]uh jIh]rPj)rQ}rR(hUh}rS(h]h]h]h]h]uh jMh]rTj)rU}rV(hUh}rW(U anchornameU#index-resourceUrefurih#h]h]h]h]h]Uinternaluh jQh]rX(hXIndex resource - rYrZ}r[(hXIndex resource - r\h jUubcdocutils.nodes literal r])r^}r_(hX``/``r`h}ra(h]h]h]h]h]uh jUh]rbhX/rc}rd(hUh j^ubah!Uliteralreubeh!jubah!jubah!jubj)rf}rg(hUh}rh(h]h]h]h]h]uh jIh]ri(j)rj}rk(hUh}rl(h]h]h]h]h]uh jfh]rmj)rn}ro(hUh}rp(U anchornameU#stats-resource-statsUrefurih#h]h]h]h]h]Uinternaluh jjh]rq(hXStats resource - rrrs}rt(hXStats resource - ruh jnubj])rv}rw(hX ``/stats``rxh}ry(h]h]h]h]h]uh jnh]rzhX/statsr{r|}r}(hUh jvubah!jeubeh!jubah!jubj)r~}r(hUh}r(h]h]h]h]h]uh jfh]r(j)r}r(hUh}r(h]h]h]h]h]uh j~h]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU#access-controlUrefurih#h]h]h]h]h]Uinternaluh jh]rhXAccess controlrr}r(hXAccess controlrh jubah!jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh j~h]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU#custom-statisticsUrefurih#h]h]h]h]h]Uinternaluh jh]rhXCustom statisticsrr}r(hXCustom statisticsrh jubah!jubah!jubah!jubeh!jubeh!jubj)r}r(hUh}r(h]h]h]h]h]uh jIh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU#status-resource-statusUrefurih#h]h]h]h]h]Uinternaluh jh]r(hXStatus resource - rr}r(hXStatus resource - rh jubj])r}r(hX ``/status``rh}r(h]h]h]h]h]uh jh]rhX/statusrr}r(hUh jubah!jeubeh!jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jIh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU#user-resource-users-userUrefurih#h]h]h]h]h]Uinternaluh jh]r(hXUser resource - rr}r(hXUser resource - rh jubj])r}r(hX``/users/``rh}r(h]h]h]h]h]uh jh]rhX /users/rr}r(hUh jubah!jeubeh!jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jIh]r(j)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU"#images-resource-users-user-imagesUrefurih#h]h]h]h]h]Uinternaluh jh]r(hXImages resource - rr}r(hXImages resource - rh jubj])r}r(hX``/users//images``rh}r(h]h]h]h]h]uh jh]rhX/users//imagesrr}r(hUh jubah!jeubeh!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jh]r(j)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU #add-an-imageUrefurih#h]h]h]h]h]Uinternaluh jh]rhX Add an imagerr}r(hX Add an imagerh jubah!jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU#get-image-collectionsUrefurih#h]h]h]h]h]Uinternaluh jh]r hXGet image collectionsr r }r (hXGet image collectionsr h jubah!jubah!jubah!jubeh!jubeh!jubj)r}r(hUh}r(h]h]h]h]h]uh jIh]r(j)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU'#image-resource-users-user-images-imageUrefurih#h]h]h]h]h]Uinternaluh jh]r(hXImage resource - rr}r(hXImage resource - rh jubj])r}r(hX ``/users//images/``r h}r!(h]h]h]h]h]uh jh]r"hX/users//images/r#r$}r%(hUh jubah!jeubeh!jubah!jubj)r&}r'(hUh}r((h]h]h]h]h]uh jh]r)(j)r*}r+(hUh}r,(h]h]h]h]h]uh j&h]r-j)r.}r/(hUh}r0(h]h]h]h]h]uh j*h]r1j)r2}r3(hUh}r4(U anchornameU #fetch-imagesUrefurih#h]h]h]h]h]Uinternaluh j.h]r5hX Fetch imagesr6r7}r8(hX Fetch imagesr9h j2ubah!jubah!jubah!jubj)r:}r;(hUh}r<(h]h]h]h]h]uh j&h]r=j)r>}r?(hUh}r@(h]h]h]h]h]uh j:h]rAj)rB}rC(hUh}rD(U anchornameU#delete-imagesUrefurih#h]h]h]h]h]Uinternaluh j>h]rEhX Delete imagesrFrG}rH(hX Delete imagesrIh jBubah!jubah!jubah!jubeh!jubeh!jubj)rJ}rK(hUh}rL(h]h]h]h]h]uh jIh]rMj)rN}rO(hUh}rP(h]h]h]h]h]uh jJh]rQj)rR}rS(hUh}rT(U anchornameU#shorturl-resource-s-idUrefurih#h]h]h]h]h]Uinternaluh jNh]rU(hXShortURL resource - rVrW}rX(hXShortURL resource - rYh jRubj])rZ}r[(hX ``/s/``r\h}r](h]h]h]h]h]uh jRh]r^hX/s/r_r`}ra(hUh jZubah!jeubeh!jubah!jubah!jubj)rb}rc(hUh}rd(h]h]h]h]h]uh jIh]re(j)rf}rg(hUh}rh(h]h]h]h]h]uh jbh]rij)rj}rk(hUh}rl(U anchornameU3#metadata-resource-users-user-images-image-metadataUrefurih#h]h]h]h]h]Uinternaluh jfh]rm(hXMetadata resource - rnro}rp(hXMetadata resource - rqh jjubj])rr}rs(hX)``/users//images//metadata``rth}ru(h]h]h]h]h]uh jjh]rvhX%/users//images//metadatarwrx}ry(hUh jrubah!jeubeh!jubah!jubj)rz}r{(hUh}r|(h]h]h]h]h]uh jbh]r}(j)r~}r(hUh}r(h]h]h]h]h]uh jzh]rj)r}r(hUh}r(h]h]h]h]h]uh j~h]rj)r}r(hUh}r(U anchornameU#adding-replacing-metadataUrefurih#h]h]h]h]h]Uinternaluh jh]rhXAdding/replacing metadatarr}r(hXAdding/replacing metadatarh jubah!jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jzh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU#partially-updating-metadataUrefurih#h]h]h]h]h]Uinternaluh jh]rhXPartially updating metadatarr}r(hXPartially updating metadatarh jubah!jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jzh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU#fetch-metadataUrefurih#h]h]h]h]h]Uinternaluh jh]rhXFetch metadatarr}r(hXFetch metadatarh jubah!jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jzh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU#remove-metadataUrefurih#h]h]h]h]h]Uinternaluh jh]rhXRemove metadatarr}r(hXRemove metadatarh jubah!jubah!jubah!jubeh!jubeh!jubeh!jubeh!jubj)r}r(hUh}r(h]h]h]h]h]uh j5h]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU#access-tokensUrefurih#h]h]h]h]h]Uinternaluh jh]rhX Access tokensrr}r(hX Access tokensrh jubah!jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh j5h]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU#signing-write-requestsUrefurih#h]h]h]h]h]Uinternaluh jh]rhXSigning write requestsrr}r(hXSigning write requestsrh jubah!jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh j5h]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU#supported-content-typesUrefurih#h]h]h]h]h]Uinternaluh jh]rhXSupported content typesrr}r(hXSupported content typesrh jubah!jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh j5h]r(j)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU#cache-headersUrefurih#h]h]h]h]h]Uinternaluh jh]rhX Cache headersrr}r(hX Cache headersrh jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jh]r(j)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]r j)r }r (hUh}r (U anchornameU#cache-controlUrefurih#h]h]h]h]h]Uinternaluh jh]r hX Cache-Controlrr}r(hX Cache-Controlrh j ubah!jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU#etagUrefurih#h]h]h]h]h]Uinternaluh jh]rhXETagrr}r (hXETagr!h jubah!jubah!jubah!jubj)r"}r#(hUh}r$(h]h]h]h]h]uh jh]r%j)r&}r'(hUh}r((h]h]h]h]h]uh j"h]r)j)r*}r+(hUh}r,(U anchornameU#last-modifiedUrefurih#h]h]h]h]h]Uinternaluh j&h]r-hX Last-Modifiedr.r/}r0(hX Last-Modifiedr1h j*ubah!jubah!jubah!jubeh!jubeh!jubj)r2}r3(hUh}r4(h]h]h]h]h]uh j5h]r5j)r6}r7(hUh}r8(h]h]h]h]h]uh j2h]r9j)r:}r;(hUh}r<(U anchornameU#errorsUrefurih#h]h]h]h]h]Uinternaluh j6h]r=hXErrorsr>r?}r@(hXErrorsrAh j:ubah!jubah!jubah!jubeh!jubeh!jubah!jubh,j)rB}rC(hUh}rD(h]h]h]h]h]uh]rEj)rF}rG(hUh}rH(h]h]h]h]h]uh jBh]rI(j)rJ}rK(hUh}rL(h]h]h]h]h]uh jFh]rMj)rN}rO(hUh}rP(U anchornameUUrefurih,h]h]h]h]h]Uinternaluh jJh]rQhXCache adaptersrRrS}rT(hh4h jNubah!jubah!jubj)rU}rV(hUh}rW(h]h]h]h]h]uh jFh]rX(j)rY}rZ(hUh}r[(h]h]h]h]h]uh jUh]r\j)r]}r^(hUh}r_(h]h]h]h]h]uh jYh]r`j)ra}rb(hUh}rc(U anchornameU#apcUrefurih,h]h]h]h]h]Uinternaluh j]h]rdhXAPCrerf}rg(hXAPCh jaubah!jubah!jubah!jubj)rh}ri(hUh}rj(h]h]h]h]h]uh jUh]rkj)rl}rm(hUh}rn(h]h]h]h]h]uh jhh]roj)rp}rq(hUh}rr(U anchornameU #memcachedUrefurih,h]h]h]h]h]Uinternaluh jlh]rshX Memcachedrtru}rv(hX Memcachedh jpubah!jubah!jubah!jubj)rw}rx(hUh}ry(h]h]h]h]h]uh jUh]rzj)r{}r|(hUh}r}(h]h]h]h]h]uh jwh]r~j)r}r(hUh}r(U anchornameU!#implement-a-custom-cache-adapterUrefurih,h]h]h]h]h]Uinternaluh j{h]rhX Implement a custom cache adapterrr}r(hX Implement a custom cache adapterh jubah!jubah!jubah!jubeh!jubeh!jubah!jubh5j)r}r(hUh}r(h]h]h]h]h]uh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]r(j)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameUUrefurih5h]h]h]h]h]Uinternaluh jh]rhX5Customize your Imbo installation with event listenersrr}r(hh=h jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jh]r(j)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU #access-tokenUrefurih5h]h]h]h]h]Uinternaluh jh]rhX Access tokenrr}r(hX Access tokenrh jubah!jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU #authenticateUrefurih5h]h]h]h]h]Uinternaluh jh]rhX Authenticaterr}r(hX Authenticaterh jubah!jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU#auto-rotate-imageUrefurih5h]h]h]h]h]Uinternaluh jh]rhXAuto rotate imagerr}r(hXAuto rotate imagerh jubah!jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU##cors-cross-origin-resource-sharingUrefurih5h]h]h]h]h]Uinternaluh jh]rhX$CORS (Cross-Origin Resource Sharing)rr}r(hX$CORS (Cross-Origin Resource Sharing)rh jubah!jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU#exif-metadataUrefurih5h]h]h]h]h]Uinternaluh jh]rhX EXIF metadatarr}r(hX EXIF metadatarh jubah!jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU#image-transformation-cacheUrefurih5h]h]h]h]h]Uinternaluh jh]rhXImage transformation cacherr}r(hXImage transformation cacherh jubah!jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU#imagickUrefurih5h]h]h]h]h]Uinternaluh jh]rhXImagickr r }r (hXImagickr h jubah!jubah!jubah!jubj)r }r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(h]h]h]h]h]uh j h]rj)r}r(hUh}r(U anchornameU#max-image-sizeUrefurih5h]h]h]h]h]Uinternaluh jh]rhXMax image sizerr}r(hXMax image sizerh jubah!jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jh]r j)r!}r"(hUh}r#(h]h]h]h]h]uh jh]r$j)r%}r&(hUh}r'(U anchornameU#metadata-cacheUrefurih5h]h]h]h]h]Uinternaluh j!h]r(hXMetadata cacher)r*}r+(hXMetadata cacher,h j%ubah!jubah!jubah!jubj)r-}r.(hUh}r/(h]h]h]h]h]uh jh]r0j)r1}r2(hUh}r3(h]h]h]h]h]uh j-h]r4j)r5}r6(hUh}r7(U anchornameU #stats-accessUrefurih5h]h]h]h]h]Uinternaluh j1h]r8hX Stats accessr9r:}r;(hX Stats accessr<h j5ubah!jubah!jubah!jubj)r=}r>(hUh}r?(h]h]h]h]h]uh jh]r@j)rA}rB(hUh}rC(h]h]h]h]h]uh j=h]rDj)rE}rF(hUh}rG(U anchornameU#varnish-hashtwoUrefurih5h]h]h]h]h]Uinternaluh jAh]rHhXVarnish HashTworIrJ}rK(hXVarnish HashTworLh jEubah!jubah!jubah!jubeh!jubeh!jubah!jubh>j)rM}rN(hUh}rO(h]h]h]h]h]uh]rPj)rQ}rR(hUh}rS(h]h]h]h]h]uh jMh]rTj)rU}rV(hUh}rW(h]h]h]h]h]uh jQh]rXj)rY}rZ(hUh}r[(U anchornameUUrefurih>h]h]h]h]h]Uinternaluh jUh]r\hX Requirementsr]r^}r_(hhFh jYubah!jubah!jubah!jubah!jubhGj)r`}ra(hUh}rb(h]h]h]h]h]uh]rcj)rd}re(hUh}rf(h]h]h]h]h]uh j`h]rgj)rh}ri(hUh}rj(h]h]h]h]h]uh jdh]rkj)rl}rm(hUh}rn(U anchornameUUrefurihGh]h]h]h]h]Uinternaluh jhh]rohX(Implement your own image transformationsrprq}rr(hhOh jlubah!jubah!jubah!jubah!jubhPj)rs}rt(hUh}ru(h]h]h]h]h]uh]rvj)rw}rx(hUh}ry(h]h]h]h]h]uh jsh]rz(j)r{}r|(hUh}r}(h]h]h]h]h]uh jwh]r~j)r}r(hUh}r(U anchornameUUrefurihPh]h]h]h]h]Uinternaluh j{h]rhXContributing to Imborr}r(hhXh jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jwh]r(j)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU #build-scriptUrefurihPh]h]h]h]h]Uinternaluh jh]rhX Build scriptrr}r(hX Build scripth jubah!jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jh]r(j)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU #requirementsUrefurihPh]h]h]h]h]Uinternaluh jh]rhX Requirementsrr}r(hX Requirementsh jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jh]r(j)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU#coding-standardUrefurihPh]h]h]h]h]Uinternaluh jh]rhXCoding standardrr}r(hXCoding standardh jubah!jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU#testsUrefurihPh]h]h]h]h]Uinternaluh jh]rhXTestsrr}r(hXTestsh jubah!jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU#documentationUrefurihPh]h]h]h]h]Uinternaluh jh]rhX Documentationrr}r(hX Documentationh jubah!jubah!jubah!jubeh!jubeh!jubeh!jubeh!jubah!jubhYj)r}r(hUh}r(h]h]h]h]h]uh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameUUrefurihYh]h]h]h]h]Uinternaluh jh]rhX2Implement your own database and/or storage adapterrr}r(hhah jubah!jubah!jubah!jubah!jubhbj)r}r(hUh}r(h]h]h]h]h]uh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]r(j)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameUUrefurihbh]h]h]h]h]Uinternaluh jh]rhX Installationrr}r(hhjh jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jh]r(j)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r (h]h]h]h]h]uh jh]r j)r }r (hUh}r (U anchornameU#using-composerUrefurihbh]h]h]h]h]Uinternaluh jh]rhXUsing composerrr}r(hXUsing composerrh j ubah!jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU#using-git-cloneUrefurihbh]h]h]h]h]Uinternaluh jh]rhXUsing git clonerr }r!(hXUsing git cloner"h jubah!jubah!jubah!jubj)r#}r$(hUh}r%(h]h]h]h]h]uh jh]r&(j)r'}r((hUh}r)(h]h]h]h]h]uh j#h]r*j)r+}r,(hUh}r-(U anchornameU#web-server-configurationUrefurihbh]h]h]h]h]Uinternaluh j'h]r.hXWeb server configurationr/r0}r1(hXWeb server configurationr2h j+ubah!jubah!jubj)r3}r4(hUh}r5(h]h]h]h]h]uh j#h]r6(j)r7}r8(hUh}r9(h]h]h]h]h]uh j3h]r:j)r;}r<(hUh}r=(h]h]h]h]h]uh j7h]r>j)r?}r@(hUh}rA(U anchornameU#id3Urefurihbh]h]h]h]h]Uinternaluh j;h]rBhXApacherCrD}rE(hXApacherFh j?ubah!jubah!jubah!jubj)rG}rH(hUh}rI(h]h]h]h]h]uh j3h]rJj)rK}rL(hUh}rM(h]h]h]h]h]uh jGh]rNj)rO}rP(hUh}rQ(U anchornameU#id4Urefurihbh]h]h]h]h]Uinternaluh jKh]rRhXNginxrSrT}rU(hXNginxrVh jOubah!jubah!jubah!jubj)rW}rX(hUh}rY(h]h]h]h]h]uh j3h]rZj)r[}r\(hUh}r](h]h]h]h]h]uh jWh]r^j)r_}r`(hUh}ra(U anchornameU #lighttpdUrefurihbh]h]h]h]h]Uinternaluh j[h]rbhXLighttpdrcrd}re(hXLighttpdrfh j_ubah!jubah!jubah!jubj)rg}rh(hUh}ri(h]h]h]h]h]uh j3h]rjj)rk}rl(hUh}rm(h]h]h]h]h]uh jgh]rnj)ro}rp(hUh}rq(U anchornameU#id5Urefurihbh]h]h]h]h]Uinternaluh jkh]rrhXVarnishrsrt}ru(hXVarnishrvh joubah!jubah!jubah!jubeh!jubeh!jubj)rw}rx(hUh}ry(h]h]h]h]h]uh jh]rz(j)r{}r|(hUh}r}(h]h]h]h]h]uh jwh]r~j)r}r(hUh}r(U anchornameU#database-setupUrefurihbh]h]h]h]h]Uinternaluh j{h]rhXDatabase setuprr}r(hXDatabase setuprh jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jwh]r(j)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU#mysqlUrefurihbh]h]h]h]h]Uinternaluh jh]rhXMySQLrr}r(hXMySQLrh jubah!jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU#sqliteUrefurihbh]h]h]h]h]Uinternaluh jh]rhXSQLiterr}r(hXSQLiterh jubah!jubah!jubah!jubeh!jubeh!jubeh!jubeh!jubah!jubhkj)r}r(hUh}r(h]h]h]h]h]uh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]r(j)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameUUrefurihkh]h]h]h]h]Uinternaluh jh]rhX Configurationrr}r(hhsh jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jh]r(j)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU#imbo-users-authUrefurihkh]h]h]h]h]Uinternaluh jh]r(hX Imbo users - rr}r(hX Imbo users - rh jubj])r}r(hX``auth``rh}r(h]h]h]h]h]uh jh]rhXauthrr}r(hUh jubah!jeubeh!jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jh]r(j)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU #database-configuration-databaseUrefurihkh]h]h]h]h]Uinternaluh jh]r(hXDatabase configuration - rr}r(hXDatabase configuration - rh jubj])r}r(hX ``database``rh}r(h]h]h]h]h]uh jh]rhXdatabaserr}r(hUh jubah!jeubeh!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jh]r(j)r}r(hUh}r(h]h]h]h]h]uh jh]r(j)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU #doctrineUrefurihkh]h]h]h]h]Uinternaluh jh]rhXDoctrinerr}r(hXDoctrinerh jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jh]r j)r }r (hUh}r (h]h]h]h]h]uh jh]r j)r}r(hUh}r(h]h]h]h]h]uh j h]rj)r}r(hUh}r(U anchornameU #examplesUrefurihkh]h]h]h]h]Uinternaluh jh]rhXExamplesrr}r(hXExamplesrh jubah!jubah!jubah!jubah!jubeh!jubj)r}r(hUh}r(h]h]h]h]h]uh jh]r(j)r}r(hUh}r (h]h]h]h]h]uh jh]r!j)r"}r#(hUh}r$(U anchornameU#mongodbUrefurihkh]h]h]h]h]Uinternaluh jh]r%hXMongoDBr&r'}r((hXMongoDBr)h j"ubah!jubah!jubj)r*}r+(hUh}r,(h]h]h]h]h]uh jh]r-j)r.}r/(hUh}r0(h]h]h]h]h]uh j*h]r1j)r2}r3(hUh}r4(h]h]h]h]h]uh j.h]r5j)r6}r7(hUh}r8(U anchornameU#id4Urefurihkh]h]h]h]h]Uinternaluh j2h]r9hXExamplesr:r;}r<(hXExamplesr=h j6ubah!jubah!jubah!jubah!jubeh!jubj)r>}r?(hUh}r@(h]h]h]h]h]uh jh]rAj)rB}rC(hUh}rD(h]h]h]h]h]uh j>h]rEj)rF}rG(hUh}rH(U anchornameU#custom-database-adapterUrefurihkh]h]h]h]h]Uinternaluh jBh]rIhXCustom database adapterrJrK}rL(hXCustom database adapterrMh jFubah!jubah!jubah!jubeh!jubeh!jubj)rN}rO(hUh}rP(h]h]h]h]h]uh jh]rQ(j)rR}rS(hUh}rT(h]h]h]h]h]uh jNh]rUj)rV}rW(hUh}rX(U anchornameU#storage-configuration-storageUrefurihkh]h]h]h]h]Uinternaluh jRh]rY(hXStorage configuration - rZr[}r\(hXStorage configuration - r]h jVubj])r^}r_(hX ``storage``r`h}ra(h]h]h]h]h]uh jVh]rbhXstoragercrd}re(hUh j^ubah!jeubeh!jubah!jubj)rf}rg(hUh}rh(h]h]h]h]h]uh jNh]ri(j)rj}rk(hUh}rl(h]h]h]h]h]uh jfh]rm(j)rn}ro(hUh}rp(h]h]h]h]h]uh jjh]rqj)rr}rs(hUh}rt(U anchornameU#amazon-simple-storage-serviceUrefurihkh]h]h]h]h]Uinternaluh jnh]ruhXAmazon Simple Storage Servicervrw}rx(hXAmazon Simple Storage Serviceryh jrubah!jubah!jubj)rz}r{(hUh}r|(h]h]h]h]h]uh jjh]r}j)r~}r(hUh}r(h]h]h]h]h]uh jzh]rj)r}r(hUh}r(h]h]h]h]h]uh j~h]rj)r}r(hUh}r(U anchornameU#id6Urefurihkh]h]h]h]h]Uinternaluh jh]rhXExamplesrr}r(hXExamplesrh jubah!jubah!jubah!jubah!jubeh!jubj)r}r(hUh}r(h]h]h]h]h]uh jfh]r(j)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU#id7Urefurihkh]h]h]h]h]Uinternaluh jh]rhXDoctrinerr}r(hXDoctrinerh jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU#id10Urefurihkh]h]h]h]h]Uinternaluh jh]rhXExamplesrr}r(hXExamplesrh jubah!jubah!jubah!jubah!jubeh!jubj)r}r(hUh}r(h]h]h]h]h]uh jfh]r(j)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU #filesystemUrefurihkh]h]h]h]h]Uinternaluh jh]rhX Filesystemrr}r(hX Filesystemrh jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU#id11Urefurihkh]h]h]h]h]Uinternaluh jh]rhXExamplesrr}r(hXExamplesrh jubah!jubah!jubah!jubah!jubeh!jubj)r}r(hUh}r(h]h]h]h]h]uh jfh]r(j)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU#gridfsUrefurihkh]h]h]h]h]Uinternaluh jh]rhXGridFSrr}r(hXGridFSrh jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU#id13Urefurihkh]h]h]h]h]Uinternaluh jh]rhXExamplesrr}r(hXExamplesrh jubah!jubah!jubah!jubah!jubeh!jubj)r}r(hUh}r(h]h]h]h]h]uh jfh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU#custom-storage-adapterUrefurihkh]h]h]h]h]Uinternaluh jh]rhXCustom storage adapterrr}r(hXCustom storage adapterr h jubah!jubah!jubah!jubeh!jubeh!jubj)r }r (hUh}r (h]h]h]h]h]uh jh]r (j)r}r(hUh}r(h]h]h]h]h]uh j h]rj)r}r(hUh}r(U anchornameU#event-listeners-eventlistenersUrefurihkh]h]h]h]h]Uinternaluh jh]r(hXEvent listeners - rr}r(hXEvent listeners - rh jubj])r}r(hX``eventListeners``rh}r(h]h]h]h]h]uh jh]rhXeventListenersrr }r!(hUh jubah!jeubeh!jubah!jubj)r"}r#(hUh}r$(h]h]h]h]h]uh j h]r%j)r&}r'(hUh}r((h]h]h]h]h]uh j"h]r)j)r*}r+(hUh}r,(h]h]h]h]h]uh j&h]r-j)r.}r/(hUh}r0(U anchornameU#listeners-added-by-defaultUrefurihkh]h]h]h]h]Uinternaluh j*h]r1hXListeners added by defaultr2r3}r4(hXListeners added by defaultr5h j.ubah!jubah!jubah!jubah!jubeh!jubj)r6}r7(hUh}r8(h]h]h]h]h]uh jh]r9j)r:}r;(hUh}r<(h]h]h]h]h]uh j6h]r=j)r>}r?(hUh}r@(U anchornameU6#event-listener-initializers-eventlistenerinitializersUrefurihkh]h]h]h]h]Uinternaluh j:h]rA(hXEvent listener initializers - rBrC}rD(hXEvent listener initializers - rEh j>ubj])rF}rG(hX``eventListenerInitializers``rHh}rI(h]h]h]h]h]uh j>h]rJhXeventListenerInitializersrKrL}rM(hUh jFubah!jeubeh!jubah!jubah!jubj)rN}rO(hUh}rP(h]h]h]h]h]uh jh]rQj)rR}rS(hUh}rT(h]h]h]h]h]uh jNh]rUj)rV}rW(hUh}rX(U anchornameU3#image-transformation-presets-transformationpresetsUrefurihkh]h]h]h]h]Uinternaluh jRh]rY(hXImage transformation presets - rZr[}r\(hXImage transformation presets - r]h jVubj])r^}r_(hX``transformationPresets``r`h}ra(h]h]h]h]h]uh jVh]rbhXtransformationPresetsrcrd}re(hUh j^ubah!jeubeh!jubah!jubah!jubj)rf}rg(hUh}rh(h]h]h]h]h]uh jh]rij)rj}rk(hUh}rl(h]h]h]h]h]uh jfh]rmj)rn}ro(hUh}rp(U anchornameU1#custom-resources-and-routes-resources-and-routesUrefurihkh]h]h]h]h]Uinternaluh jjh]rq(hXCustom resources and routes - rrrs}rt(hXCustom resources and routes - ruh jnubj])rv}rw(hX ``resources``rxh}ry(h]h]h]h]h]uh jnh]rzhX resourcesr{r|}r}(hUh jvubah!jeubhX and r~r}r(hX and rh jnubj])r}r(hX ``routes``rh}r(h]h]h]h]h]uh jnh]rhXroutesrr}r(hUh jubah!jeubeh!jubah!jubah!jubeh!jubeh!jubah!jubhtj)r}r(hUh}r(h]h]h]h]h]uh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]r(j)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameUUrefurihth]h]h]h]h]Uinternaluh jh]rhXTransforming images on the flyrr}r(hh|h jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jh]r(j)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU2#auto-rotate-image-based-on-exif-data-t-autorotateUrefurihth]h]h]h]h]Uinternaluh jh]r(hX'Auto rotate image based on EXIF data - rr}r(hX'Auto rotate image based on EXIF data - rh jubj])r}r(hX``t[]=autoRotate``rh}r(h]h]h]h]h]uh jh]rhXt[]=autoRotaterr}r(hUh jubah!jeubeh!jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU#add-an-image-border-t-borderUrefurihth]h]h]h]h]Uinternaluh jh]r(hXAdd an image border - rr}r(hXAdd an image border - rh jubj])r}r(hX``t[]=border``rh}r(h]h]h]h]h]uh jh]rhX t[]=borderrr}r(hUh jubah!jeubeh!jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU!#expand-the-image-canvas-t-canvasUrefurihth]h]h]h]h]Uinternaluh jh]r(hXExpand the image canvas - rr}r(hXExpand the image canvas - rh jubj])r}r(hX``t[]=canvas``rh}r(h]h]h]h]h]uh jh]rhX t[]=canvasrr}r(hUh jubah!jeubeh!jubah!jubah!jubj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(h]h]h]h]h]uh jh]rj)r}r(hUh}r(U anchornameU#compress-the-image-t-compressUrefurihth]h]h]h]h]Uinternaluh jh]r(hXCompress the image - rr}r(hXCompress the image - rh jubj])r}r(hX``t[]=compress``rh}r(h]h]h]h]h]uh jh]rhX t[]=compressrr}r (hUh jubah!jeubeh!jubah!jubah!jubj)r }r (hUh}r (h]h]h]h]h]uh jh]r j)r }r (hUh}r (h]h]h]h]h]uh j h]r j)r }r (hUh}r (U anchornameU##convert-the-image-type-jpg-gif-pngUrefurihth]h]h]h]h]Uinternaluh j h]r (hXConvert the image type - r r }r (hXConvert the image type - r h j ubj])r }r (hX``.jpg/.gif/.png``r h}r (h]h]h]h]h]uh j h]r hX.jpg/.gif/.pngr r }r (hUh j ubah!jeubeh!jubah!jubah!jubj)r }r (hUh}r (h]h]h]h]h]uh jh]r j)r }r (hUh}r (h]h]h]h]h]uh j h]r j)r! }r" (hUh}r# (U anchornameU#crop-the-image-t-cropUrefurihth]h]h]h]h]Uinternaluh j h]r$ (hXCrop the image - r% r& }r' (hXCrop the image - r( h j! ubj])r) }r* (hX ``t[]=crop``r+ h}r, (h]h]h]h]h]uh j! h]r- hXt[]=cropr. r/ }r0 (hUh j) ubah!jeubeh!jubah!jubah!jubj)r1 }r2 (hUh}r3 (h]h]h]h]h]uh jh]r4 j)r5 }r6 (hUh}r7 (h]h]h]h]h]uh j1 h]r8 j)r9 }r: (hUh}r; (U anchornameU&#make-a-gray-scaled-image-t-desaturateUrefurihth]h]h]h]h]Uinternaluh j5 h]r< (hXMake a gray scaled image - r= r> }r? (hXMake a gray scaled image - r@ h j9 ubj])rA }rB (hX``t[]=desaturate``rC h}rD (h]h]h]h]h]uh j9 h]rE hXt[]=desaturaterF rG }rH (hUh jA ubah!jeubeh!jubah!jubah!jubj)rI }rJ (hUh}rK (h]h]h]h]h]uh jh]rL j)rM }rN (hUh}rO (h]h]h]h]h]uh jI h]rP j)rQ }rR (hUh}rS (U anchornameU'#make-a-mirror-image-t-fliphorizontallyUrefurihth]h]h]h]h]Uinternaluh jM h]rT (hXMake a mirror image - rU rV }rW (hXMake a mirror image - rX h jQ ubj])rY }rZ (hX``t[]=flipHorizontally``r[ h}r\ (h]h]h]h]h]uh jQ h]r] hXt[]=flipHorizontallyr^ r_ }r` (hUh jY ubah!jeubeh!jubah!jubah!jubj)ra }rb (hUh}rc (h]h]h]h]h]uh jh]rd j)re }rf (hUh}rg (h]h]h]h]h]uh ja h]rh j)ri }rj (hUh}rk (U anchornameU,#flip-the-image-upside-down-t-flipverticallyUrefurihth]h]h]h]h]Uinternaluh je h]rl (hXFlip the image upside down - rm rn }ro (hXFlip the image upside down - rp h ji ubj])rq }rr (hX``t[]=flipVertically``rs h}rt (h]h]h]h]h]uh ji h]ru hXt[]=flipVerticallyrv rw }rx (hUh jq ubah!jeubeh!jubah!jubah!jubj)ry }rz (hUh}r{ (h]h]h]h]h]uh jh]r| j)r} }r~ (hUh}r (h]h]h]h]h]uh jy h]r j)r }r (hUh}r (U anchornameU)#enforce-a-max-size-of-an-image-t-maxsizeUrefurihth]h]h]h]h]Uinternaluh j} h]r (hX!Enforce a max size of an image - r r }r (hX!Enforce a max size of an image - r h j ubj])r }r (hX``t[]=maxSize``r h}r (h]h]h]h]h]uh j h]r hX t[]=maxSizer r }r (hUh j ubah!jeubeh!jubah!jubah!jubj)r }r (hUh}r (h]h]h]h]h]uh jh]r j)r }r (hUh}r (h]h]h]h]h]uh j h]r j)r }r (hUh}r (U anchornameU#modulate-the-image-t-modulateUrefurihth]h]h]h]h]Uinternaluh j h]r (hXModulate the image - r r }r (hXModulate the image - r h j ubj])r }r (hX``t[]=modulate``r h}r (h]h]h]h]h]uh j h]r hX t[]=modulater r }r (hUh j ubah!jeubeh!jubah!jubah!jubj)r }r (hUh}r (h]h]h]h]h]uh jh]r j)r }r (hUh}r (h]h]h]h]h]uh j h]r j)r }r (hUh}r (U anchornameU'#make-a-progressive-image-t-progressiveUrefurihth]h]h]h]h]Uinternaluh j h]r (hXMake a progressive image - r r }r (hXMake a progressive image - r h j ubj])r }r (hX``t[]=progressive``r h}r (h]h]h]h]h]uh j h]r hXt[]=progressiver r }r (hUh j ubah!jeubeh!jubah!jubah!jubj)r }r (hUh}r (h]h]h]h]h]uh jh]r j)r }r (hUh}r (h]h]h]h]h]uh j h]r j)r }r (hUh}r (U anchornameU#resize-the-image-t-resizeUrefurihth]h]h]h]h]Uinternaluh j h]r (hXResize the image - r r }r (hXResize the image - r h j ubj])r }r (hX``t[]=resize``r h}r (h]h]h]h]h]uh j h]r hX t[]=resizer r }r (hUh j ubah!jeubeh!jubah!jubah!jubj)r }r (hUh}r (h]h]h]h]h]uh jh]r j)r }r (hUh}r (h]h]h]h]h]uh j h]r j)r }r (hUh}r (U anchornameU#rotate-the-image-t-rotateUrefurihth]h]h]h]h]Uinternaluh j h]r (hXRotate the image - r r }r (hXRotate the image - r h j ubj])r }r (hX``t[]=rotate``r h}r (h]h]h]h]h]uh j h]r hX t[]=rotater r }r (hUh j ubah!jeubeh!jubah!jubah!jubj)r }r (hUh}r (h]h]h]h]h]uh jh]r j)r }r (hUh}r (h]h]h]h]h]uh j h]r j)r }r (hUh}r (U anchornameU!#apply-a-sepia-color-tone-t-sepiaUrefurihth]h]h]h]h]Uinternaluh j h]r (hXApply a sepia color tone - r r }r (hXApply a sepia color tone - r h j ubj])r }r (hX ``t[]=sepia``r h}r (h]h]h]h]h]uh j h]r hX t[]=sepiar r }r (hUh j ubah!jeubeh!jubah!jubah!jubj)r }r (hUh}r (h]h]h]h]h]uh jh]r j)r }r (hUh}r (h]h]h]h]h]uh j h]r j)r }r (hUh}r (U anchornameU,#strip-image-properties-and-comments-t-stripUrefurihth]h]h]h]h]Uinternaluh j h]r (hX&Strip image properties and comments - r r }r (hX&Strip image properties and comments - r h j ubj])r }r (hX ``t[]=strip``r h}r (h]h]h]h]h]uh j h]r hX t[]=stripr r }r (hUh j ubah!jeubeh!jubah!jubah!jubj)r! }r" (hUh}r# (h]h]h]h]h]uh jh]r$ j)r% }r& (hUh}r' (h]h]h]h]h]uh j! h]r( j)r) }r* (hUh}r+ (U anchornameU,#create-a-thumbnail-of-the-image-t-thumbnailUrefurihth]h]h]h]h]Uinternaluh j% h]r, (hX"Create a thumbnail of the image - r- r. }r/ (hX"Create a thumbnail of the image - r0 h j) ubj])r1 }r2 (hX``t[]=thumbnail``r3 h}r4 (h]h]h]h]h]uh j) h]r5 hX t[]=thumbnailr6 r7 }r8 (hUh j1 ubah!jeubeh!jubah!jubah!jubj)r9 }r: (hUh}r; (h]h]h]h]h]uh jh]r< j)r= }r> (hUh}r? (h]h]h]h]h]uh j9 h]r@ j)rA }rB (hUh}rC (U anchornameU+#create-a-vertical-mirror-image-t-transposeUrefurihth]h]h]h]h]Uinternaluh j= h]rD (hX!Create a vertical mirror image - rE rF }rG (hX!Create a vertical mirror image - rH h jA ubj])rI }rJ (hX``t[]=transpose``rK h}rL (h]h]h]h]h]uh jA h]rM hX t[]=transposerN rO }rP (hUh jI ubah!jeubeh!jubah!jubah!jubj)rQ }rR (hUh}rS (h]h]h]h]h]uh jh]rT j)rU }rV (hUh}rW (h]h]h]h]h]uh jQ h]rX j)rY }rZ (hUh}r[ (U anchornameU.#create-a-horizontal-mirror-image-t-transverseUrefurihth]h]h]h]h]Uinternaluh jU h]r\ (hX#Create a horizontal mirror image - r] r^ }r_ (hX#Create a horizontal mirror image - r` h jY ubj])ra }rb (hX``t[]=transverse``rc h}rd (h]h]h]h]h]uh jY h]re hXt[]=transverserf rg }rh (hUh ja ubah!jeubeh!jubah!jubah!jubj)ri }rj (hUh}rk (h]h]h]h]h]uh jh]rl j)rm }rn (hUh}ro (h]h]h]h]h]uh ji h]rp j)rq }rr (hUh}rs (U anchornameU)#add-a-watermark-to-the-image-t-watermarkUrefurihth]h]h]h]h]Uinternaluh jm h]rt (hXAdd a watermark to the image - ru rv }rw (hXAdd a watermark to the image - rx h jq ubj])ry }rz (hX``t[]=watermark``r{ h}r| (h]h]h]h]h]uh jq h]r} hX t[]=watermarkr~ r }r (hUh jy ubah!jeubeh!jubah!jubah!jubeh!jubeh!jubah!jubh}j)r }r (hUh}r (h]h]h]h]h]uh]r j)r }r (hUh}r (h]h]h]h]h]uh j h]r (j)r }r (hUh}r (h]h]h]h]h]uh j h]r j)r }r (hUh}r (U anchornameUUrefurih}h]h]h]h]h]Uinternaluh j h]r hX'Working with events and event listenersr r }r (hhh j ubah!jubah!jubj)r }r (hUh}r (h]h]h]h]h]uh j h]r (j)r }r (hUh}r (h]h]h]h]h]uh j h]r j)r }r (hUh}r (h]h]h]h]h]uh j h]r j)r }r (hUh}r (U anchornameU#eventsUrefurih}h]h]h]h]h]Uinternaluh j h]r hXEventsr r }r (hXEventsh j ubah!jubah!jubah!jubj)r }r (hUh}r (h]h]h]h]h]uh j h]r (j)r }r (hUh}r (h]h]h]h]h]uh j h]r j)r }r (hUh}r (U anchornameU#writing-an-event-listenerUrefurih}h]h]h]h]h]Uinternaluh j h]r hXWriting an event listenerr r }r (hXWriting an event listenerh j ubah!jubah!jubj)r }r (hUh}r (h]h]h]h]h]uh j h]r (j)r }r (hUh}r (h]h]h]h]h]uh j h]r j)r }r (hUh}r (h]h]h]h]h]uh j h]r j)r }r (hUh}r (U anchornameU=#implement-the-imbo-eventlistener-listenerinterface-interfaceUrefurih}h]h]h]h]h]Uinternaluh j h]r (hXImplement the r r }r (hXImplement the h j ubj])r }r (hX(``Imbo\EventListener\ListenerInterface``h}r (h]h]h]h]h]uh j h]r hX$Imbo\EventListener\ListenerInterfacer r }r (hUh j ubah!jeubhX interfacer r }r (hX interfaceh j ubeh!jubah!jubah!jubj)r }r (hUh}r (h]h]h]h]h]uh j h]r j)r }r (hUh}r (h]h]h]h]h]uh j h]r j)r }r (hUh}r (U anchornameU"#use-a-class-with-an-invoke-methodUrefurih}h]h]h]h]h]Uinternaluh j h]r (hXUse a class with an r r }r (hXUse a class with an h j ubj])r }r (hX ``__invoke``h}r (h]h]h]h]h]uh j h]r hX__invoker r }r (hUh j ubah!jeubhX methodr r }r (hX methodh j ubeh!jubah!jubah!jubj)r }r (hUh}r (h]h]h]h]h]uh j h]r j)r }r (hUh}r (h]h]h]h]h]uh j h]r j)r }r (hUh}r (U anchornameU#use-a-closureUrefurih}h]h]h]h]h]Uinternaluh j h]r hX Use a Closurer r }r (hX Use a Closureh j ubah!jubah!jubah!jubeh!jubeh!jubj)r }r (hUh}r (h]h]h]h]h]uh j h]r j)r }r (hUh}r (h]h]h]h]h]uh j h]r j)r }r (hUh}r (U anchornameU#the-event-objectUrefurih}h]h]h]h]h]Uinternaluh j h]r hXThe event objectr r }r (hXThe event objecth j ubah!jubah!jubah!jubeh!jubeh!jubah!jubuU indexentriesr }r (h ]h#]h,]h5]h>]hG]hP]hY]hb]hk]ht]h}]uUall_docsr }r (h GAԿvU"h#GAԿvOh,GAԿvK6mh5GAԿvo#h>GAԿvv=.hGGAԿvTdhPGAԿvMʒhYGAԿvNIhbGAԿvu7hkGAԿvf htGAԿvRh}GAԿvSuUsettingsr }r (Ucloak_email_addressesr Utrim_footnote_reference_spacer U halt_levelr KUsectsubtitle_xformr Uembed_stylesheetr U pep_base_urlr Uhttp://www.python.org/dev/peps/r Udoctitle_xformr Uwarning_streamr csphinx.util.nodes WarningStream r )r }r (U_rer cre _compile r U+\((DEBUG|INFO|WARNING|ERROR|SEVERE)/[0-4]\)r KRr Uwarnfuncr NubUenvr! hU rfc_base_urlr" Uhttp://tools.ietf.org/html/r# Ufile_insertion_enabledr$ Ugettext_compactr% Uinput_encodingr& U utf-8-sigr' uUfiles_to_rebuildr( }r) (jh]r* h aRr+ jh]r, h aRr- jh]r. h aRr/ jh]r0 h aRr1 jh]r2 h aRr3 jh]r4 h aRr5 jh]r6 h aRr7 jh]r8 h aRr9 jh]r: h aRr; jh]r< h aRr= jh]r> h aRr? uUtoc_secnumbersr@ }U_nitpick_ignorerA h]RrB ub.PKrND?XY"Y""imbo-1.1.1/.doctrees/index.doctreecdocutils.nodes document q)q}q(U nametypesq}q(Xinstallation guideqNXfreenode irc networkqX mit licensedqXextending/customizing imboq NXend user guideq NX issue trackerq Xavailable on githubq Xphpq Ximbo - image boxqNuUsubstitution_defsq}qUparse_messagesq]qUcurrent_sourceqNU decorationqNUautofootnote_startqKUnameidsq}q(hUinstallation-guideqhUfreenode-irc-networkqhU mit-licensedqh Uextending-customizing-imboqh Uend-user-guideqh U issue-trackerqh Uavailable-on-githubqh UphpqhUimbo-image-boxq uUchildrenq!]q"cdocutils.nodes section q#)q$}q%(U rawsourceq&UUparentq'hUsourceq(cdocutils.nodes reprunicode q)X:/var/build/user_builds/imbo/checkouts/1.1.1/docs/index.rstq*q+}q,bUtagnameq-Usectionq.U attributesq/}q0(Udupnamesq1]Uclassesq2]Ubackrefsq3]Uidsq4]q5h aUnamesq6]q7hauUlineq8KUdocumentq9hh!]q:(cdocutils.nodes title q;)q<}q=(h&XImbo - Image boxq>h'h$h(h+h-Utitleq?h/}q@(h1]h2]h3]h4]h6]uh8Kh9hh!]qAcdocutils.nodes Text qBXImbo - Image boxqCqD}qE(h&h>h'h`_) project written in `PHP `_ and is `available on GitHub `_. If you find any issues or missing features please add an issue in the `issue tracker `_. If you want to know more feel free to join the #imbo channel on the `Freenode IRC network `_ (chat.freenode.net) as well.qRh'h$h(h+h-hJh/}qS(h1]h2]h3]h4]h6]uh8Kh9hh!]qT(hBXImbo is an open source (qUqV}qW(h&XImbo is an open source (h'hPubcdocutils.nodes reference qX)qY}qZ(h&X4`MIT licensed `_h/}q[(UnameX MIT licensedUrefuriq\X"http://opensource.org/licenses/MITq]h4]h3]h1]h2]h6]uh'hPh!]q^hBX MIT licensedq_q`}qa(h&Uh'hYubah-U referenceqbubcdocutils.nodes target qc)qd}qe(h&X% U referencedqfKh'hPh-Utargetqgh/}qh(Urefurih]h4]qihah3]h1]h2]h6]qjhauh!]ubhBX) project written in qkql}qm(h&X) project written in h'hPubhX)qn}qo(h&X`PHP `_h/}qp(UnameXPHPh\Xhttp://php.netqqh4]h3]h1]h2]h6]uh'hPh!]qrhBXPHPqsqt}qu(h&Uh'hnubah-hbubhc)qv}qw(h&X hfKh'hPh-hgh/}qx(Urefurihqh4]qyhah3]h1]h2]h6]qzh auh!]ubhBX and is q{q|}q}(h&X and is h'hPubhX)q~}q(h&X5`available on GitHub `_h/}q(UnameXavailable on GitHubh\Xhttps://github.com/imbo/imboqh4]h3]h1]h2]h6]uh'hPh!]qhBXavailable on GitHubqq}q(h&Uh'h~ubah-hbubhc)q}q(h&X hfKh'hPh-hgh/}q(Urefurihh4]qhah3]h1]h2]h6]qh auh!]ubhBXH. If you find any issues or missing features please add an issue in the qq}q(h&XH. If you find any issues or missing features please add an issue in the h'hPubhX)q}q(h&X6`issue tracker `_h/}q(UnameX issue trackerh\X#https://github.com/imbo/imbo/issuesqh4]h3]h1]h2]h6]uh'hPh!]qhBX issue trackerqq}q(h&Uh'hubah-hbubhc)q}q(h&X& hfKh'hPh-hgh/}q(Urefurihh4]qhah3]h1]h2]h6]qh auh!]ubhBXF. If you want to know more feel free to join the #imbo channel on the qq}q(h&XF. If you want to know more feel free to join the #imbo channel on the h'hPubhX)q}q(h&X-`Freenode IRC network `_h/}q(UnameXFreenode IRC networkh\Xhttp://freenode.netqh4]h3]h1]h2]h6]uh'hPh!]qhBXFreenode IRC networkqq}q(h&Uh'hubah-hbubhc)q}q(h&X hfKh'hPh-hgh/}q(Urefurihh4]qhah3]h1]h2]h6]qhauh!]ubhBX (chat.freenode.net) as well.qq}q(h&X (chat.freenode.net) as well.h'hPubeubh#)q}q(h&Uh'h$h(h+h-h.h/}q(h1]h2]h3]h4]qhah6]qhauh8K h9hh!]q(h;)q}q(h&XInstallation guideqh'hh(h+h-h?h/}q(h1]h2]h3]h4]h6]uh8K h9hh!]qhBXInstallation guideqq}q(h&hh'hubaubcdocutils.nodes compound q)q}q(h&Uh'hh(h+h-Ucompoundqh/}q(h1]h2]qUtoctree-wrapperqah3]h4]h6]uh8Nh9hh!]qcsphinx.addnodes toctree q)q}q(h&Uh'hh(h+h-Utoctreeqh/}q(UnumberedqKU includehiddenqʉh'XindexqU titlesonlyq̉Uglobq͉h4]h3]h1]h2]h6]Uentriesq]q(NXinstallation/requirementsqІqNXinstallation/installationq҆qNXinstallation/configurationqԆqNXinstallation/event_listenersqֆqeUhiddenq؉U includefilesq]q(hhhheUmaxdepthqKuh8K h!]ubaubeubh#)q}q(h&Uh'h$h(h+h-h.h/}q(h1]h2]h3]h4]qhah6]qh auh8Kh9hh!]q(h;)q}q(h&XEnd user guideqh'hh(h+h-h?h/}q(h1]h2]h3]h4]h6]uh8Kh9hh!]qhBXEnd user guideq煁q}q(h&hh'hubaubh)q}q(h&Uh'hh(h+h-hh/}q(h1]h2]qhah3]h4]h6]uh8Nh9hh!]qh)q}q(h&Uh'hh(h+h-hh/}q(hKhʉh'hh̉h͉h4]h3]h1]h2]h6]h]q(NX usage/apiqqNXusage/image-transformationsqqeh؉h]q(hhehKuh8Kh!]ubaubeubh#)q}q(h&Uh'h$h(h+h-h.h/}q(h1]h2]h3]h4]qhah6]qh auh8Kh9hh!]q(h;)q}q(h&XExtending/customizing Imborh'hh(h+h-h?h/}r(h1]h2]h3]h4]h6]uh8Kh9hh!]rhBXExtending/customizing Imborr}r(h&jh'hubaubh)r}r(h&Uh'hh(h+h-hh/}r(h1]h2]r hah3]h4]h6]uh8Nh9hh!]r h)r }r (h&Uh'jh(h+h-hh/}r (hKhʉh'hh̉h͉h4]h3]h1]h2]h6]h]r(NXdevelop/event_listenersrrNXdevelop/custom_adaptersrrNXdevelop/image_transformationsrrNXdevelop/cache_adaptersrrNXdevelop/contributingrreh؉h]r(jjjjjehKuh8Kh!]ubaubeubeubah&UU transformerrNU footnote_refsr}rUrefnamesr}rUsymbol_footnotesr]r Uautofootnote_refsr!]r"Usymbol_footnote_refsr#]r$U citationsr%]r&h9hU current_liner'NUtransform_messagesr(]r)Ureporterr*NUid_startr+KU autofootnotesr,]r-U citation_refsr.}r/Uindirect_targetsr0]r1Usettingsr2(cdocutils.frontend Values r3or4}r5(Ufootnote_backlinksr6KUrecord_dependenciesr7NU rfc_base_urlr8Uhttp://tools.ietf.org/html/r9U tracebackr:Upep_referencesr;NUstrip_commentsr<NU toc_backlinksr=Uentryr>U language_coder?Uenr@U datestamprANU report_levelrBKU _destinationrCNU halt_levelrDKU strip_classesrENh?NUerror_encoding_error_handlerrFUbackslashreplacerGUdebugrHNUembed_stylesheetrIUoutput_encoding_error_handlerrJUstrictrKU sectnum_xformrLKUdump_transformsrMNU docinfo_xformrNKUwarning_streamrONUpep_file_url_templaterPUpep-%04drQUexit_status_levelrRKUconfigrSNUstrict_visitorrTNUcloak_email_addressesrUUtrim_footnote_reference_spacerVUenvrWNUdump_pseudo_xmlrXNUexpose_internalsrYNUsectsubtitle_xformrZU source_linkr[NUrfc_referencesr\NUoutput_encodingr]Uutf-8r^U source_urlr_NUinput_encodingr`U utf-8-sigraU_disable_configrbNU id_prefixrcUU tab_widthrdKUerror_encodingreUUTF-8rfU_sourcergU:/var/build/user_builds/imbo/checkouts/1.1.1/docs/index.rstrhUgettext_compactriU generatorrjNUdump_internalsrkNU smart_quotesrlU pep_base_urlrmUhttp://www.python.org/dev/peps/rnUsyntax_highlightroUlongrpUinput_encoding_error_handlerrqjKUauto_id_prefixrrUidrsUdoctitle_xformrtUstrip_elements_with_classesruNU _config_filesrv]Ufile_insertion_enabledrwU raw_enabledrxKU dump_settingsryNubUsymbol_footnote_startrzKUidsr{}r|(hhhhdh h$hhhhhhhhhhvhhuUsubstitution_namesr}}r~h-h9h/}r(h1]h4]h3]Usourceh+h2]h6]uU footnotesr]rUrefidsr}rub.PKsNDBb558imbo-1.1.1/.doctrees/usage/image-transformations.doctreecdocutils.nodes document q)q}q(U nametypesq}q(Xcrop the image - t[]=cropqNXthumbnail-transformationqX5auto rotate image based on exif data - t[]=autorotateqNXmax-size-transformationq X.create a vertical mirror image - t[]=transposeq NX,enforce a max size of an image - t[]=maxsizeq NXcrop-transformationq X/strip image properties and comments - t[]=stripq NXdesaturate-transformationqX1create a horizontal mirror image - t[]=transverseqNXsepia-transformationqX add an image border - t[]=borderqNXwatermark-transformationqXcanvas-transformationqXcompress-transformationqXstrip-transformationqXmodulate-transformationqXresize-transformationqXrotate the image - t[]=rotateqNX/flip the image upside down - t[]=flipverticallyqNXborder-transformationqXflip-vertically-transformationqXtransforming images on the flyqNXprogressive-transformationqX flip-horizontally-transformationqX!compress the image - t[]=compressqNX/create a thumbnail of the image - t[]=thumbnailq NX$expand the image canvas - t[]=canvasq!NXtranspose-transformationq"X!modulate the image - t[]=modulateq#NXresize the image - t[]=resizeq$NX,add a watermark to the image - t[]=watermarkq%NXauto-rotate-transformationq&X*make a mirror image - t[]=fliphorizontallyq'NX$apply a sepia color tone - t[]=sepiaq(NXrotate-transformationq)Xconvert-transformationq*Xtransverse-transformationq+X)make a gray scaled image - t[]=desaturateq,NX*make a progressive image - t[]=progressiveq-NX'convert the image type - .jpg/.gif/.pngq.NXimage-transformationsq/uUsubstitution_defsq0}q1Uparse_messagesq2]q3Ucurrent_sourceq4NU decorationq5NUautofootnote_startq6KUnameidsq7}q8(hUcrop-the-image-t-cropq9hUthumbnail-transformationq:hU1auto-rotate-image-based-on-exif-data-t-autorotateq;h Umax-size-transformationqh Ucrop-transformationq?h U+strip-image-properties-and-comments-t-stripq@hUdesaturate-transformationqAhU-create-a-horizontal-mirror-image-t-transverseqBhUsepia-transformationqChUadd-an-image-border-t-borderqDhUwatermark-transformationqEhUcanvas-transformationqFhUcompress-transformationqGhUstrip-transformationqHhUmodulate-transformationqIhUresize-transformationqJhUrotate-the-image-t-rotateqKhU+flip-the-image-upside-down-t-flipverticallyqLhUborder-transformationqMhUflip-vertically-transformationqNhUtransforming-images-on-the-flyqOhUprogressive-transformationqPhU flip-horizontally-transformationqQhUcompress-the-image-t-compressqRh U+create-a-thumbnail-of-the-image-t-thumbnailqSh!U expand-the-image-canvas-t-canvasqTh"Utranspose-transformationqUh#Umodulate-the-image-t-modulateqVh$Uresize-the-image-t-resizeqWh%U(add-a-watermark-to-the-image-t-watermarkqXh&Uauto-rotate-transformationqYh'U&make-a-mirror-image-t-fliphorizontallyqZh(U apply-a-sepia-color-tone-t-sepiaq[h)Urotate-transformationq\h*Uconvert-transformationq]h+Utransverse-transformationq^h,U%make-a-gray-scaled-image-t-desaturateq_h-U&make-a-progressive-image-t-progressiveq`h.U"convert-the-image-type-jpg-gif-pngqah/Uimage-transformationsqbuUchildrenqc]qd(cdocutils.nodes target qe)qf}qg(U rawsourceqhX.. _image-transformations:UparentqihUsourceqjcdocutils.nodes reprunicode qkXP/var/build/user_builds/imbo/checkouts/1.1.1/docs/usage/image-transformations.rstqlqm}qnbUtagnameqoUtargetqpU attributesqq}qr(Uidsqs]Ubackrefsqt]Udupnamesqu]Uclassesqv]Unamesqw]UrefidqxhbuUlineqyKUdocumentqzhhc]ubcdocutils.nodes section q{)q|}q}(hhUhihhjhmUexpect_referenced_by_nameq~}qh/hfshoUsectionqhq}q(hu]hv]ht]hs]q(hOhbehw]q(hh/euhyKhzhUexpect_referenced_by_idq}qhbhfshc]q(cdocutils.nodes title q)q}q(hhXTransforming images on the flyqhih|hjhmhoUtitleqhq}q(hu]hv]ht]hs]hw]uhyKhzhhc]qcdocutils.nodes Text qXTransforming images on the flyqq}q(hhhhihubaubcdocutils.nodes paragraph q)q}q(hhXWhat you as an end-user of an Imbo installation will be doing most of the time, is working with images. This is what Imbo was originally made for, and this chapter includes details about all the different image transformations Imbo supports.qhih|hjhmhoU paragraphqhq}q(hu]hv]ht]hs]hw]uhyKhzhhc]qhXWhat you as an end-user of an Imbo installation will be doing most of the time, is working with images. This is what Imbo was originally made for, and this chapter includes details about all the different image transformations Imbo supports.qq}q(hhhhihubaubh)q}q(hhXAll image transformations can be triggered by specifying the ``t`` query parameter. This parameter must be used as an array so that you can provide several image transformations. The transformations will be applied to the image in the same order as they appear in the URL. Each element in this array represents a single transformation with optional parameters, specified as a string. If the ``t`` query parameter is not an array or if any of its elements are not strings, Imbo will respond with ``HTTP 400``.qhih|hjhmhohhq}q(hu]hv]ht]hs]hw]uhyKhzhhc]q(hX=All image transformations can be triggered by specifying the qq}q(hhX=All image transformations can be triggered by specifying the hihubcdocutils.nodes literal q)q}q(hhX``t``hq}q(hu]hv]ht]hs]hw]uhihhc]qhXtq}q(hhUhihubahoUliteralqubhXE query parameter. This parameter must be used as an array so that you can provide several image transformations. The transformations will be applied to the image in the same order as they appear in the URL. Each element in this array represents a single transformation with optional parameters, specified as a string. If the qq}q(hhXE query parameter. This parameter must be used as an array so that you can provide several image transformations. The transformations will be applied to the image in the same order as they appear in the URL. Each element in this array represents a single transformation with optional parameters, specified as a string. If the hihubh)q}q(hhX``t``hq}q(hu]hv]ht]hs]hw]uhihhc]qhXtq}q(hhUhihubahohubhXc query parameter is not an array or if any of its elements are not strings, Imbo will respond with qq}q(hhXc query parameter is not an array or if any of its elements are not strings, Imbo will respond with hihubh)q}q(hhX ``HTTP 400``hq}q(hu]hv]ht]hs]hw]uhihhc]qhXHTTP 400qq}q(hhUhihubahohubhX.q}q(hhX.hihubeubh)q}q(hhX\Below you will find all image transformations supported "out of the box", along with their parameters. Some transformations are rarely used with ``HTTP GET``, but are instead used by event listeners that transform images when they are added to Imbo (``HTTP POST``). If this is the case it will be mentioned in the description of the transformation.qhih|hjhmhohhq}q(hu]hv]ht]hs]hw]uhyK hzhhc]q(hXBelow you will find all image transformations supported "out of the box", along with their parameters. Some transformations are rarely used with qƅq}q(hhXBelow you will find all image transformations supported "out of the box", along with their parameters. Some transformations are rarely used with hihubh)q}q(hhX ``HTTP GET``hq}q(hu]hv]ht]hs]hw]uhihhc]qhXHTTP GETqͅq}q(hhUhihubahohubhX], but are instead used by event listeners that transform images when they are added to Imbo (qЅq}q(hhX], but are instead used by event listeners that transform images when they are added to Imbo (hihubh)q}q(hhX ``HTTP POST``hq}q(hu]hv]ht]hs]hw]uhihhc]qhX HTTP POSTqׅq}q(hhUhihubahohubhXU). If this is the case it will be mentioned in the description of the transformation.qڅq}q(hhXU). If this is the case it will be mentioned in the description of the transformation.hihubeubhe)q}q(hhX.. _auto-rotate-transformation:hih|hjhmhohphq}q(hs]ht]hu]hv]hw]hxhYuhyK hzhhc]ubh{)q}q(hhUhih|hjhmh~}qh&hshohhq}q(hu]hv]ht]hs]q(h;hYehw]q(hh&euhyKhzhh}qhYhshc]q(h)q}q(hhX9Auto rotate image based on EXIF data - ``t[]=autoRotate``qhihhjhmhohhq}q(hu]hv]ht]hs]hw]uhyKhzhhc]q(hX'Auto rotate image based on EXIF data - q텁q}q(hhX'Auto rotate image based on EXIF data - qhihubh)q}q(hhX``t[]=autoRotate``qhq}q(hu]hv]ht]hs]hw]uhihhc]qhXt[]=autoRotateqq}q(hhUhihubahohubeubh)q}q(hhXThis transformation will auto rotate the image based on EXIF data stored in the image. This transformation is rarely used per request, but is typically used by the :ref:`auto-rotate-image-event-listener` event listener when adding images to Imbo.qhihhjhmhohhq}q(hu]hv]ht]hs]hw]uhyKhzhhc]q(hXThis transformation will auto rotate the image based on EXIF data stored in the image. This transformation is rarely used per request, but is typically used by the qq}r(hhXThis transformation will auto rotate the image based on EXIF data stored in the image. This transformation is rarely used per request, but is typically used by the hihubcsphinx.addnodes pending_xref r)r}r(hhX':ref:`auto-rotate-image-event-listener`rhihhjhmhoU pending_xrefrhq}r(UreftypeXrefUrefwarnrU reftargetrX auto-rotate-image-event-listenerU refdomainXstdr hs]ht]U refexplicithu]hv]hw]Urefdocr Xusage/image-transformationsr uhyKhc]r cdocutils.nodes emphasis r )r}r(hhjhq}r(hu]hv]r(Uxrefrj Xstd-refreht]hs]hw]uhijhc]rhX auto-rotate-image-event-listenerrr}r(hhUhijubahoUemphasisrubaubhX+ event listener when adding images to Imbo.rr}r(hhX+ event listener when adding images to Imbo.hihubeubh)r}r(hhX **Examples:**rhihhjhmhohhq}r(hu]hv]ht]hs]hw]uhyKhzhhc]r cdocutils.nodes strong r!)r"}r#(hhjhq}r$(hu]hv]ht]hs]hw]uhijhc]r%hX Examples:r&r'}r((hhUhij"ubahoUstrongr)ubaubcdocutils.nodes bullet_list r*)r+}r,(hhUhihhjhmhoU bullet_listr-hq}r.(Ubulletr/X*hs]ht]hu]hv]hw]uhyKhzhhc]r0cdocutils.nodes list_item r1)r2}r3(hhX``t[]=autoRotate`` hij+hjhmhoU list_itemr4hq}r5(hu]hv]ht]hs]hw]uhyNhzhhc]r6h)r7}r8(hhX``t[]=autoRotate``r9hij2hjhmhohhq}r:(hu]hv]ht]hs]hw]uhyKhc]r;h)r<}r=(hhj9hq}r>(hu]hv]ht]hs]hw]uhij7hc]r?hXt[]=autoRotater@rA}rB(hhUhij<ubahohubaubaubaubhe)rC}rD(hhX.. _border-transformation:hihhjhmhohphq}rE(hs]ht]hu]hv]hw]hxhMuhyKhzhhc]ubeubh{)rF}rG(hhUhih|hjhmh~}rHhjCshohhq}rI(hu]hv]ht]hs]rJ(hDhMehw]rK(hheuhyKhzhh}rLhMjCshc]rM(h)rN}rO(hhX$Add an image border - ``t[]=border``rPhijFhjhmhohhq}rQ(hu]hv]ht]hs]hw]uhyKhzhhc]rR(hXAdd an image border - rSrT}rU(hhXAdd an image border - rVhijNubh)rW}rX(hhX``t[]=border``rYhq}rZ(hu]hv]ht]hs]hw]uhijNhc]r[hX t[]=borderr\r]}r^(hhUhijWubahohubeubh)r_}r`(hhX9This transformation will apply a border around the image.rahijFhjhmhohhq}rb(hu]hv]ht]hs]hw]uhyKhzhhc]rchX9This transformation will apply a border around the image.rdre}rf(hhjahij_ubaubh)rg}rh(hhX**Parameters:**rihijFhjhmhohhq}rj(hu]hv]ht]hs]hw]uhyKhzhhc]rkj!)rl}rm(hhjihq}rn(hu]hv]ht]hs]hw]uhijghc]rohX Parameters:rprq}rr(hhUhijlubahoj)ubaubcdocutils.nodes definition_list rs)rt}ru(hhUhijFhjhmhoUdefinition_listrvhq}rw(hu]hv]ht]hs]hw]uhyNhzhhc]rx(cdocutils.nodes definition_list_item ry)rz}r{(hhX``color`` Color of the border in hexadecimal. Defaults to ``000000`` (You can also specify short values like ``f00`` (``ff0000``)). hijthjhmhoUdefinition_list_itemr|hq}r}(hu]hv]ht]hs]hw]uhyK!hc]r~(cdocutils.nodes term r)r}r(hhX ``color``rhijzhjhmhoUtermrhq}r(hu]hv]ht]hs]hw]uhyK!hc]rh)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhXcolorrr}r(hhUhijubahohubaubcdocutils.nodes definition r)r}r(hhUhq}r(hu]hv]ht]hs]hw]uhijzhc]rh)r}r(hhXyColor of the border in hexadecimal. Defaults to ``000000`` (You can also specify short values like ``f00`` (``ff0000``)).hijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyK!hc]r(hX0Color of the border in hexadecimal. Defaults to rr}r(hhX0Color of the border in hexadecimal. Defaults to hijubh)r}r(hhX ``000000``hq}r(hu]hv]ht]hs]hw]uhijhc]rhX000000rr}r(hhUhijubahohubhX) (You can also specify short values like rr}r(hhX) (You can also specify short values like hijubh)r}r(hhX``f00``hq}r(hu]hv]ht]hs]hw]uhijhc]rhXf00rr}r(hhUhijubahohubhX (rr}r(hhX (hijubh)r}r(hhX ``ff0000``hq}r(hu]hv]ht]hs]hw]uhijhc]rhXff0000rr}r(hhUhijubahohubhX)).rr}r(hhX)).hijubeubahoU definitionrubeubjy)r}r(hhXe``width`` Width of the border in pixels on the left and right sides of the image. Defaults to ``1``. hijthjhmhoj|hq}r(hu]hv]ht]hs]hw]uhyK$hzhhc]r(j)r}r(hhX ``width``rhijhjhmhojhq}r(hu]hv]ht]hs]hw]uhyK$hc]rh)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhXwidthrr}r(hhUhijubahohubaubj)r}r(hhUhq}r(hu]hv]ht]hs]hw]uhijhc]rh)r}r(hhXZWidth of the border in pixels on the left and right sides of the image. Defaults to ``1``.hijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyK$hc]r(hXTWidth of the border in pixels on the left and right sides of the image. Defaults to rr}r(hhXTWidth of the border in pixels on the left and right sides of the image. Defaults to hijubh)r}r(hhX``1``hq}r(hu]hv]ht]hs]hw]uhijhc]rhX1r}r(hhUhijubahohubhX.r}r(hhX.hijubeubahojubeubjy)r}r(hhXg``height`` Height of the border in pixels on the top and bottom sides of the image. Defaults to ``1``. hijthjhmhoj|hq}r(hu]hv]ht]hs]hw]uhyK'hzhhc]r(j)r}r(hhX ``height``rhijhjhmhojhq}r(hu]hv]ht]hs]hw]uhyK'hc]rh)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhXheightrr}r(hhUhijubahohubaubj)r}r(hhUhq}r(hu]hv]ht]hs]hw]uhijhc]rh)r}r(hhX[Height of the border in pixels on the top and bottom sides of the image. Defaults to ``1``.hijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyK'hc]r(hXUHeight of the border in pixels on the top and bottom sides of the image. Defaults to rr}r(hhXUHeight of the border in pixels on the top and bottom sides of the image. Defaults to hijubh)r}r(hhX``1``hq}r(hu]hv]ht]hs]hw]uhijhc]rhX1r}r(hhUhijubahohubhX.r}r(hhX.hijubeubahojubeubjy)r}r(hhX``mode`` Mode of the border. Can be ``inline`` or ``outbound``. Defaults to ``outbound``. Outbound places the border outside of the image, increasing the dimensions of the image. ``inline`` paints the border inside of the image, retaining the original width and height of the image. hijthjhmhoj|hq}r(hu]hv]ht]hs]hw]uhyK*hzhhc]r(j)r}r(hhX``mode``rhijhjhmhojhq}r(hu]hv]ht]hs]hw]uhyK*hc]rh)r}r(hhjhq}r (hu]hv]ht]hs]hw]uhijhc]r hXmoder r }r (hhUhijubahohubaubj)r}r(hhUhq}r(hu]hv]ht]hs]hw]uhijhc]rh)r}r(hhXMode of the border. Can be ``inline`` or ``outbound``. Defaults to ``outbound``. Outbound places the border outside of the image, increasing the dimensions of the image. ``inline`` paints the border inside of the image, retaining the original width and height of the image.hijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyK*hc]r(hXMode of the border. Can be rr}r(hhXMode of the border. Can be hijubh)r}r(hhX ``inline``hq}r(hu]hv]ht]hs]hw]uhijhc]rhXinlinerr}r(hhUhijubahohubhX or r r!}r"(hhX or hijubh)r#}r$(hhX ``outbound``hq}r%(hu]hv]ht]hs]hw]uhijhc]r&hXoutboundr'r(}r)(hhUhij#ubahohubhX. Defaults to r*r+}r,(hhX. Defaults to hijubh)r-}r.(hhX ``outbound``hq}r/(hu]hv]ht]hs]hw]uhijhc]r0hXoutboundr1r2}r3(hhUhij-ubahohubhX[. Outbound places the border outside of the image, increasing the dimensions of the image. r4r5}r6(hhX[. Outbound places the border outside of the image, increasing the dimensions of the image. hijubh)r7}r8(hhX ``inline``hq}r9(hu]hv]ht]hs]hw]uhijhc]r:hXinliner;r<}r=(hhUhij7ubahohubhX] paints the border inside of the image, retaining the original width and height of the image.r>r?}r@(hhX] paints the border inside of the image, retaining the original width and height of the image.hijubeubahojubeubeubh)rA}rB(hhX **Examples:**rChijFhjhmhohhq}rD(hu]hv]ht]hs]hw]uhyK,hzhhc]rEj!)rF}rG(hhjChq}rH(hu]hv]ht]hs]hw]uhijAhc]rIhX Examples:rJrK}rL(hhUhijFubahoj)ubaubj*)rM}rN(hhUhijFhjhmhoj-hq}rO(j/X*hs]ht]hu]hv]hw]uhyK.hzhhc]rP(j1)rQ}rR(hhX``t[]=border``rShijMhjhmhoj4hq}rT(hu]hv]ht]hs]hw]uhyNhzhhc]rUh)rV}rW(hhjShijQhjhmhohhq}rX(hu]hv]ht]hs]hw]uhyK.hc]rYh)rZ}r[(hhjShq}r\(hu]hv]ht]hs]hw]uhijVhc]r]hX t[]=borderr^r_}r`(hhUhijZubahohubaubaubj1)ra}rb(hhX``t[]=border:mode=inline``rchijMhjhmhoj4hq}rd(hu]hv]ht]hs]hw]uhyNhzhhc]reh)rf}rg(hhjchijahjhmhohhq}rh(hu]hv]ht]hs]hw]uhyK/hc]rih)rj}rk(hhjchq}rl(hu]hv]ht]hs]hw]uhijfhc]rmhXt[]=border:mode=inlinernro}rp(hhUhijjubahohubaubaubj1)rq}rr(hhX``t[]=border:color=000``rshijMhjhmhoj4hq}rt(hu]hv]ht]hs]hw]uhyNhzhhc]ruh)rv}rw(hhjshijqhjhmhohhq}rx(hu]hv]ht]hs]hw]uhyK0hc]ryh)rz}r{(hhjshq}r|(hu]hv]ht]hs]hw]uhijvhc]r}hXt[]=border:color=000r~r}r(hhUhijzubahohubaubaubj1)r}r(hhX*``t[]=border:color=f00,width=2,height=2`` hijMhjhmhoj4hq}r(hu]hv]ht]hs]hw]uhyNhzhhc]rh)r}r(hhX)``t[]=border:color=f00,width=2,height=2``rhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyK1hc]rh)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhX%t[]=border:color=f00,width=2,height=2rr}r(hhUhijubahohubaubaubeubhe)r}r(hhX.. _canvas-transformation:hijFhjhmhohphq}r(hs]ht]hu]hv]hw]hxhFuhyK3hzhhc]ubeubh{)r}r(hhUhih|hjhmh~}rhjshohhq}r(hu]hv]ht]hs]r(hThFehw]r(h!heuhyK6hzhh}rhFjshc]r(h)r}r(hhX(Expand the image canvas - ``t[]=canvas``rhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyK6hzhhc]r(hXExpand the image canvas - rr}r(hhXExpand the image canvas - rhijubh)r}r(hhX``t[]=canvas``rhq}r(hu]hv]ht]hs]hw]uhijhc]rhX t[]=canvasrr}r(hhUhijubahohubeubh)r}r(hhXKThis transformation can be used to change the canvas of the original image.rhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyK8hzhhc]rhXKThis transformation can be used to change the canvas of the original image.rr}r(hhjhijubaubh)r}r(hhX**Parameters:**rhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyK:hzhhc]rj!)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhX Parameters:rr}r(hhUhijubahoj)ubaubjs)r}r(hhUhijhjhmhojvhq}r(hu]hv]ht]hs]hw]uhyNhzhhc]r(jy)r}r(hhXg``width`` Width of the surrounding canvas in pixels. If omitted the width of ```` will be used. hijhjhmhoj|hq}r(hu]hv]ht]hs]hw]uhyK=hc]r(j)r}r(hhX ``width``rhijhjhmhojhq}r(hu]hv]ht]hs]hw]uhyK=hc]rh)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhXwidthrr}r(hhUhijubahohubaubj)r}r(hhUhq}r(hu]hv]ht]hs]hw]uhijhc]rh)r}r(hhX\Width of the surrounding canvas in pixels. If omitted the width of ```` will be used.hijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyK=hc]r(hXCWidth of the surrounding canvas in pixels. If omitted the width of rr}r(hhXCWidth of the surrounding canvas in pixels. If omitted the width of hijubh)r}r(hhX ````hq}r(hu]hv]ht]hs]hw]uhijhc]rhXrr}r(hhUhijubahohubhX will be used.rr}r(hhX will be used.hijubeubahojubeubjy)r}r(hhXj``height`` Height of the surrounding canvas in pixels. If omitted the height of ```` will be used. hijhjhmhoj|hq}r(hu]hv]ht]hs]hw]uhyK@hzhhc]r(j)r}r(hhX ``height``rhijhjhmhojhq}r(hu]hv]ht]hs]hw]uhyK@hc]rh)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhXheightrr}r(hhUhijubahohubaubj)r}r(hhUhq}r(hu]hv]ht]hs]hw]uhijhc]rh)r}r(hhX^Height of the surrounding canvas in pixels. If omitted the height of ```` will be used.hijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyK@hc]r(hXEHeight of the surrounding canvas in pixels. If omitted the height of rr}r(hhXEHeight of the surrounding canvas in pixels. If omitted the height of hijubh)r}r(hhX ````hq}r(hu]hv]ht]hs]hw]uhijhc]rhXr r }r (hhUhijubahohubhX will be used.r r }r(hhX will be used.hijubeubahojubeubjy)r}r(hhX``mode`` The placement mode of the original image. ``free``, ``center``, ``center-x`` and ``center-y`` are available values. Defaults to ``free``. hijhjhmhoj|hq}r(hu]hv]ht]hs]hw]uhyKChzhhc]r(j)r}r(hhX``mode``rhijhjhmhojhq}r(hu]hv]ht]hs]hw]uhyKChc]rh)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhXmoderr}r(hhUhijubahohubaubj)r}r (hhUhq}r!(hu]hv]ht]hs]hw]uhijhc]r"h)r#}r$(hhXThe placement mode of the original image. ``free``, ``center``, ``center-x`` and ``center-y`` are available values. Defaults to ``free``.hijhjhmhohhq}r%(hu]hv]ht]hs]hw]uhyKChc]r&(hX*The placement mode of the original image. r'r(}r)(hhX*The placement mode of the original image. hij#ubh)r*}r+(hhX``free``hq}r,(hu]hv]ht]hs]hw]uhij#hc]r-hXfreer.r/}r0(hhUhij*ubahohubhX, r1r2}r3(hhX, hij#ubh)r4}r5(hhX ``center``hq}r6(hu]hv]ht]hs]hw]uhij#hc]r7hXcenterr8r9}r:(hhUhij4ubahohubhX, r;r<}r=(hhX, hij#ubh)r>}r?(hhX ``center-x``hq}r@(hu]hv]ht]hs]hw]uhij#hc]rAhXcenter-xrBrC}rD(hhUhij>ubahohubhX and rErF}rG(hhX and hij#ubh)rH}rI(hhX ``center-y``hq}rJ(hu]hv]ht]hs]hw]uhij#hc]rKhXcenter-yrLrM}rN(hhUhijHubahohubhX# are available values. Defaults to rOrP}rQ(hhX# are available values. Defaults to hij#ubh)rR}rS(hhX``free``hq}rT(hu]hv]ht]hs]hw]uhij#hc]rUhXfreerVrW}rX(hhUhijRubahohubhX.rY}rZ(hhX.hij#ubeubahojubeubjy)r[}r\(hhX``x`` X coordinate of the placement of the upper left corner of the existing image. Only used for modes: ``free`` and ``center-y``. hijhjhmhoj|hq}r](hu]hv]ht]hs]hw]uhyKFhzhhc]r^(j)r_}r`(hhX``x``rahij[hjhmhojhq}rb(hu]hv]ht]hs]hw]uhyKFhc]rch)rd}re(hhjahq}rf(hu]hv]ht]hs]hw]uhij_hc]rghXxrh}ri(hhUhijdubahohubaubj)rj}rk(hhUhq}rl(hu]hv]ht]hs]hw]uhij[hc]rmh)rn}ro(hhX}X coordinate of the placement of the upper left corner of the existing image. Only used for modes: ``free`` and ``center-y``.hijjhjhmhohhq}rp(hu]hv]ht]hs]hw]uhyKFhc]rq(hXcX coordinate of the placement of the upper left corner of the existing image. Only used for modes: rrrs}rt(hhXcX coordinate of the placement of the upper left corner of the existing image. Only used for modes: hijnubh)ru}rv(hhX``free``hq}rw(hu]hv]ht]hs]hw]uhijnhc]rxhXfreeryrz}r{(hhUhijuubahohubhX and r|r}}r~(hhX and hijnubh)r}r(hhX ``center-y``hq}r(hu]hv]ht]hs]hw]uhijnhc]rhXcenter-yrr}r(hhUhijubahohubhX.r}r(hhX.hijnubeubahojubeubjy)r}r(hhX``y`` Y coordinate of the placement of the upper left corner of the existing image. Only used for modes: ``free`` and ``center-x``. hijhjhmhoj|hq}r(hu]hv]ht]hs]hw]uhyKIhzhhc]r(j)r}r(hhX``y``rhijhjhmhojhq}r(hu]hv]ht]hs]hw]uhyKIhc]rh)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhXyr}r(hhUhijubahohubaubj)r}r(hhUhq}r(hu]hv]ht]hs]hw]uhijhc]rh)r}r(hhX}Y coordinate of the placement of the upper left corner of the existing image. Only used for modes: ``free`` and ``center-x``.hijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyKIhc]r(hXcY coordinate of the placement of the upper left corner of the existing image. Only used for modes: rr}r(hhXcY coordinate of the placement of the upper left corner of the existing image. Only used for modes: hijubh)r}r(hhX``free``hq}r(hu]hv]ht]hs]hw]uhijhc]rhXfreerr}r(hhUhijubahohubhX and rr}r(hhX and hijubh)r}r(hhX ``center-x``hq}r(hu]hv]ht]hs]hw]uhijhc]rhXcenter-xrr}r(hhUhijubahohubhX.r}r(hhX.hijubeubahojubeubjy)r}r(hhXv``bg`` Background color of the canvas. Defaults to ``ffffff`` (also supports short values like ``f00`` (``ff0000``)). hijhjhmhoj|hq}r(hu]hv]ht]hs]hw]uhyKLhzhhc]r(j)r}r(hhX``bg``rhijhjhmhojhq}r(hu]hv]ht]hs]hw]uhyKLhc]rh)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhXbgrr}r(hhUhijubahohubaubj)r}r(hhUhq}r(hu]hv]ht]hs]hw]uhijhc]rh)r}r(hhXnBackground color of the canvas. Defaults to ``ffffff`` (also supports short values like ``f00`` (``ff0000``)).hijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyKLhc]r(hX,Background color of the canvas. Defaults to rr}r(hhX,Background color of the canvas. Defaults to hijubh)r}r(hhX ``ffffff``hq}r(hu]hv]ht]hs]hw]uhijhc]rhXffffffrr}r(hhUhijubahohubhX" (also supports short values like rr}r(hhX" (also supports short values like hijubh)r}r(hhX``f00``hq}r(hu]hv]ht]hs]hw]uhijhc]rhXf00rr}r(hhUhijubahohubhX (rr}r(hhX (hijubh)r}r(hhX ``ff0000``hq}r(hu]hv]ht]hs]hw]uhijhc]rhXff0000rr}r(hhUhijubahohubhX)).rr}r(hhX)).hijubeubahojubeubeubh)r}r(hhX **Examples:**rhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyKNhzhhc]rj!)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhX Examples:rr}r(hhUhijubahoj)ubaubj*)r}r(hhUhijhjhmhoj-hq}r(j/X*hs]ht]hu]hv]hw]uhyKPhzhhc]r(j1)r}r(hhX$``t[]=canvas:width=200,mode=center``rhijhjhmhoj4hq}r(hu]hv]ht]hs]hw]uhyNhzhhc]rh)r}r(hhjhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyKPhc]rh)r}r(hhjhq}r (hu]hv]ht]hs]hw]uhijhc]r hX t[]=canvas:width=200,mode=centerr r }r (hhUhijubahohubaubaubj1)r}r(hhX4``t[]=canvas:width=200,height=200,x=10,y=10,bg=000``rhijhjhmhoj4hq}r(hu]hv]ht]hs]hw]uhyNhzhhc]rh)r}r(hhjhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyKQhc]rh)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhX0t[]=canvas:width=200,height=200,x=10,y=10,bg=000rr}r(hhUhijubahohubaubaubj1)r}r(hhX6``t[]=canvas:width=200,height=200,x=10,mode=center-y``r hijhjhmhoj4hq}r!(hu]hv]ht]hs]hw]uhyNhzhhc]r"h)r#}r$(hhj hijhjhmhohhq}r%(hu]hv]ht]hs]hw]uhyKRhc]r&h)r'}r((hhj hq}r)(hu]hv]ht]hs]hw]uhij#hc]r*hX2t[]=canvas:width=200,height=200,x=10,mode=center-yr+r,}r-(hhUhij'ubahohubaubaubj1)r.}r/(hhX7``t[]=canvas:width=200,height=200,y=10,mode=center-x`` hijhjhmhoj4hq}r0(hu]hv]ht]hs]hw]uhyNhzhhc]r1h)r2}r3(hhX6``t[]=canvas:width=200,height=200,y=10,mode=center-x``r4hij.hjhmhohhq}r5(hu]hv]ht]hs]hw]uhyKShc]r6h)r7}r8(hhj4hq}r9(hu]hv]ht]hs]hw]uhij2hc]r:hX2t[]=canvas:width=200,height=200,y=10,mode=center-xr;r<}r=(hhUhij7ubahohubaubaubeubhe)r>}r?(hhX.. _compress-transformation:hijhjhmhohphq}r@(hs]ht]hu]hv]hw]hxhGuhyKUhzhhc]ubeubh{)rA}rB(hhUhih|hjhmh~}rChj>shohhq}rD(hu]hv]ht]hs]rE(hRhGehw]rF(hheuhyKXhzhh}rGhGj>shc]rH(h)rI}rJ(hhX%Compress the image - ``t[]=compress``rKhijAhjhmhohhq}rL(hu]hv]ht]hs]hw]uhyKXhzhhc]rM(hXCompress the image - rNrO}rP(hhXCompress the image - rQhijIubh)rR}rS(hhX``t[]=compress``rThq}rU(hu]hv]ht]hs]hw]uhijIhc]rVhX t[]=compressrWrX}rY(hhUhijRubahohubeubh)rZ}r[(hhXThis transformation compresses images on the fly resulting in a smaller payload. It is advisable to only use this transformation in combination with an image type in the URL (for instance ``.jpg`` or ``.png``). This transformation is not applied to images of type ``image/gif``.r\hijAhjhmhohhq}r](hu]hv]ht]hs]hw]uhyKZhzhhc]r^(hXThis transformation compresses images on the fly resulting in a smaller payload. It is advisable to only use this transformation in combination with an image type in the URL (for instance r_r`}ra(hhXThis transformation compresses images on the fly resulting in a smaller payload. It is advisable to only use this transformation in combination with an image type in the URL (for instance hijZubh)rb}rc(hhX``.jpg``hq}rd(hu]hv]ht]hs]hw]uhijZhc]rehX.jpgrfrg}rh(hhUhijbubahohubhX or rirj}rk(hhX or hijZubh)rl}rm(hhX``.png``hq}rn(hu]hv]ht]hs]hw]uhijZhc]rohX.pngrprq}rr(hhUhijlubahohubhX8). This transformation is not applied to images of type rsrt}ru(hhX8). This transformation is not applied to images of type hijZubh)rv}rw(hhX ``image/gif``hq}rx(hu]hv]ht]hs]hw]uhijZhc]ryhX image/gifrzr{}r|(hhUhijvubahohubhX.r}}r~(hhX.hijZubeubh)r}r(hhX**Parameters:**rhijAhjhmhohhq}r(hu]hv]ht]hs]hw]uhyK\hzhhc]rj!)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhX Parameters:rr}r(hhUhijubahoj)ubaubjs)r}r(hhUhijAhjhmhojvhq}r(hu]hv]ht]hs]hw]uhyNhzhhc]rjy)r}r(hhXk``level`` The level of the compression applied to the image. The effect this parameter has on the image depends on the type of the image. If the image in the response is an ``image/jpeg`` a high ``level`` means high quality, usually resulting in larger files. If the image in the response is an ``image/png`` a high ``level`` means high compression, usually resulting in smaller files. If you do not specify an image type in the URL the result of this transformation is not deterministic as clients have different preferences with regards to the type of images they want to receive (via the ``Accept`` request header). hijhjhmhoj|hq}r(hu]hv]ht]hs]hw]uhyK_hc]r(j)r}r(hhX ``level``rhijhjhmhojhq}r(hu]hv]ht]hs]hw]uhyK_hc]rh)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhXlevelrr}r(hhUhijubahohubaubj)r}r(hhUhq}r(hu]hv]ht]hs]hw]uhijhc]rh)r}r(hhX`The level of the compression applied to the image. The effect this parameter has on the image depends on the type of the image. If the image in the response is an ``image/jpeg`` a high ``level`` means high quality, usually resulting in larger files. If the image in the response is an ``image/png`` a high ``level`` means high compression, usually resulting in smaller files. If you do not specify an image type in the URL the result of this transformation is not deterministic as clients have different preferences with regards to the type of images they want to receive (via the ``Accept`` request header).hijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyK_hc]r(hXThe level of the compression applied to the image. The effect this parameter has on the image depends on the type of the image. If the image in the response is an rr}r(hhXThe level of the compression applied to the image. The effect this parameter has on the image depends on the type of the image. If the image in the response is an hijubh)r}r(hhX``image/jpeg``hq}r(hu]hv]ht]hs]hw]uhijhc]rhX image/jpegrr}r(hhUhijubahohubhX a high rr}r(hhX a high hijubh)r}r(hhX ``level``hq}r(hu]hv]ht]hs]hw]uhijhc]rhXlevelrr}r(hhUhijubahohubhX[ means high quality, usually resulting in larger files. If the image in the response is an rr}r(hhX[ means high quality, usually resulting in larger files. If the image in the response is an hijubh)r}r(hhX ``image/png``hq}r(hu]hv]ht]hs]hw]uhijhc]rhX image/pngrr}r(hhUhijubahohubhX a high rr}r(hhX a high hijubh)r}r(hhX ``level``hq}r(hu]hv]ht]hs]hw]uhijhc]rhXlevelrr}r(hhUhijubahohubhX  means high compression, usually resulting in smaller files. If you do not specify an image type in the URL the result of this transformation is not deterministic as clients have different preferences with regards to the type of images they want to receive (via the rr}r(hhX  means high compression, usually resulting in smaller files. If you do not specify an image type in the URL the result of this transformation is not deterministic as clients have different preferences with regards to the type of images they want to receive (via the hijubh)r}r(hhX ``Accept``hq}r(hu]hv]ht]hs]hw]uhijhc]rhXAcceptrr}r(hhUhijubahohubhX request header).rr}r(hhX request header).hijubeubahojubeubaubh)r}r(hhX **Examples:**rhijAhjhmhohhq}r(hu]hv]ht]hs]hw]uhyKahzhhc]rj!)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhX Examples:rr}r(hhUhijubahoj)ubaubj*)r}r(hhUhijAhjhmhoj-hq}r(j/X*hs]ht]hu]hv]hw]uhyKchzhhc]rj1)r}r(hhX``t[]=compress:level=40`` hijhjhmhoj4hq}r(hu]hv]ht]hs]hw]uhyNhzhhc]rh)r}r(hhX``t[]=compress:level=40``rhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyKchc]rh)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhXt[]=compress:level=40rr}r(hhUhijubahohubaubaubaubhe)r}r(hhX.. _convert-transformation:hijAhjhmhohphq}r(hs]ht]hu]hv]hw]hxh]uhyKehzhhc]ubeubh{)r}r(hhUhih|hjhmh~}rh*jshohhq}r(hu]hv]ht]hs]r(hah]ehw]r(h.h*euhyKhhzhh}rh]jshc]r(h)r}r(hhX+Convert the image type - ``.jpg/.gif/.png``r hijhjhmhohhq}r (hu]hv]ht]hs]hw]uhyKhhzhhc]r (hXConvert the image type - r r }r(hhXConvert the image type - rhijubh)r}r(hhX``.jpg/.gif/.png``rhq}r(hu]hv]ht]hs]hw]uhijhc]rhX.jpg/.gif/.pngrr}r(hhUhijubahohubeubh)r}r(hhXThis transformation can be used to change the image type. It is not applied like the other transformations, but is triggered when specifying a custom extension to the ````. Currently Imbo can convert to:rhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyKjhzhhc]r(hXThis transformation can be used to change the image type. It is not applied like the other transformations, but is triggered when specifying a custom extension to the rr}r(hhXThis transformation can be used to change the image type. It is not applied like the other transformations, but is triggered when specifying a custom extension to the hijubh)r }r!(hhX ````hq}r"(hu]hv]ht]hs]hw]uhijhc]r#hXr$r%}r&(hhUhij ubahohubhX . Currently Imbo can convert to:r'r(}r)(hhX . Currently Imbo can convert to:hijubeubj*)r*}r+(hhUhijhjhmhoj-hq}r,(j/X*hs]ht]hu]hv]hw]uhyKlhzhhc]r-(j1)r.}r/(hhX``image/jpeg``r0hij*hjhmhoj4hq}r1(hu]hv]ht]hs]hw]uhyNhzhhc]r2h)r3}r4(hhj0hij.hjhmhohhq}r5(hu]hv]ht]hs]hw]uhyKlhc]r6h)r7}r8(hhj0hq}r9(hu]hv]ht]hs]hw]uhij3hc]r:hX image/jpegr;r<}r=(hhUhij7ubahohubaubaubj1)r>}r?(hhX ``image/png``r@hij*hjhmhoj4hq}rA(hu]hv]ht]hs]hw]uhyNhzhhc]rBh)rC}rD(hhj@hij>hjhmhohhq}rE(hu]hv]ht]hs]hw]uhyKmhc]rFh)rG}rH(hhj@hq}rI(hu]hv]ht]hs]hw]uhijChc]rJhX image/pngrKrL}rM(hhUhijGubahohubaubaubj1)rN}rO(hhX``image/gif`` hij*hjhmhoj4hq}rP(hu]hv]ht]hs]hw]uhyNhzhhc]rQh)rR}rS(hhX ``image/gif``rThijNhjhmhohhq}rU(hu]hv]ht]hs]hw]uhyKnhc]rVh)rW}rX(hhjThq}rY(hu]hv]ht]hs]hw]uhijRhc]rZhX image/gifr[r\}r](hhUhijWubahohubaubaubeubh)r^}r_(hhX **Examples:**r`hijhjhmhohhq}ra(hu]hv]ht]hs]hw]uhyKphzhhc]rbj!)rc}rd(hhj`hq}re(hu]hv]ht]hs]hw]uhij^hc]rfhX Examples:rgrh}ri(hhUhijcubahoj)ubaubj*)rj}rk(hhUhijhjhmhoj-hq}rl(j/X*hs]ht]hu]hv]hw]uhyKrhzhhc]rm(j1)rn}ro(hhX4``curl http://imbo/users//images/.gif``rphijjhjhmhoj4hq}rq(hu]hv]ht]hs]hw]uhyNhzhhc]rrh)rs}rt(hhjphijnhjhmhohhq}ru(hu]hv]ht]hs]hw]uhyKrhc]rvh)rw}rx(hhjphq}ry(hu]hv]ht]hs]hw]uhijshc]rzhX0curl http://imbo/users//images/.gifr{r|}r}(hhUhijwubahohubaubaubj1)r~}r(hhX4``curl http://imbo/users//images/.jpg``rhijjhjhmhoj4hq}r(hu]hv]ht]hs]hw]uhyNhzhhc]rh)r}r(hhjhij~hjhmhohhq}r(hu]hv]ht]hs]hw]uhyKshc]rh)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhX0curl http://imbo/users//images/.jpgrr}r(hhUhijubahohubaubaubj1)r}r(hhX5``curl http://imbo/users//images/.png`` hijjhjhmhoj4hq}r(hu]hv]ht]hs]hw]uhyNhzhhc]rh)r}r(hhX4``curl http://imbo/users//images/.png``rhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyKthc]rh)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhX0curl http://imbo/users//images/.pngrr}r(hhUhijubahohubaubaubeubhe)r}r(hhX.. _crop-transformation:hijhjhmhohphq}r(hs]ht]hu]hv]hw]hxh?uhyKvhzhhc]ubeubh{)r}r(hhUhih|hjhmh~}rh jshohhq}r(hu]hv]ht]hs]r(h9h?ehw]r(hh euhyKyhzhh}rh?jshc]r(h)r}r(hhXCrop the image - ``t[]=crop``rhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyKyhzhhc]r(hXCrop the image - rr}r(hhXCrop the image - rhijubh)r}r(hhX ``t[]=crop``rhq}r(hu]hv]ht]hs]hw]uhijhc]rhXt[]=croprr}r(hhUhijubahohubeubh)r}r(hhX.This transformation is used to crop the image.rhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyK{hzhhc]rhX.This transformation is used to crop the image.rr}r(hhjhijubaubh)r}r(hhX**Parameters:**rhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyK}hzhhc]rj!)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhX Parameters:rr}r(hhUhijubahoj)ubaubjs)r}r(hhUhijhjhmhojvhq}r(hu]hv]ht]hs]hw]uhyNhzhhc]r(jy)r}r(hhX@``x`` The X coordinate of the cropped region's top left corner. hijhjhmhoj|hq}r(hu]hv]ht]hs]hw]uhyKhc]r(j)r}r(hhX``x``rhijhjhmhojhq}r(hu]hv]ht]hs]hw]uhyKhc]rh)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhXxr}r(hhUhijubahohubaubj)r}r(hhUhq}r(hu]hv]ht]hs]hw]uhijhc]rh)r}r(hhX9The X coordinate of the cropped region's top left corner.rhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyKhc]rhX9The X coordinate of the cropped region's top left corner.rr}r(hhjhijubaubahojubeubjy)r}r(hhX@``y`` The Y coordinate of the cropped region's top left corner. hijhjhmhoj|hq}r(hu]hv]ht]hs]hw]uhyKhzhhc]r(j)r}r(hhX``y``rhijhjhmhojhq}r(hu]hv]ht]hs]hw]uhyKhc]rh)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhXyr}r(hhUhijubahohubaubj)r}r(hhUhq}r(hu]hv]ht]hs]hw]uhijhc]rh)r}r(hhX9The Y coordinate of the cropped region's top left corner.rhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyKhc]rhX9The Y coordinate of the cropped region's top left corner.rr}r(hhjhijubaubahojubeubjy)r}r (hhX+``width`` The width of the crop in pixels. hijhjhmhoj|hq}r (hu]hv]ht]hs]hw]uhyKhzhhc]r (j)r }r (hhX ``width``rhijhjhmhojhq}r(hu]hv]ht]hs]hw]uhyKhc]rh)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhij hc]rhXwidthrr}r(hhUhijubahohubaubj)r}r(hhUhq}r(hu]hv]ht]hs]hw]uhijhc]rh)r}r(hhX The width of the crop in pixels.rhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyKhc]r hX The width of the crop in pixels.r!r"}r#(hhjhijubaubahojubeubjy)r$}r%(hhX-``height`` The height of the crop in pixels. hijhjhmhoj|hq}r&(hu]hv]ht]hs]hw]uhyKhzhhc]r'(j)r(}r)(hhX ``height``r*hij$hjhmhojhq}r+(hu]hv]ht]hs]hw]uhyKhc]r,h)r-}r.(hhj*hq}r/(hu]hv]ht]hs]hw]uhij(hc]r0hXheightr1r2}r3(hhUhij-ubahohubaubj)r4}r5(hhUhq}r6(hu]hv]ht]hs]hw]uhij$hc]r7h)r8}r9(hhX!The height of the crop in pixels.r:hij4hjhmhohhq}r;(hu]hv]ht]hs]hw]uhyKhc]r<hX!The height of the crop in pixels.r=r>}r?(hhj:hij8ubaubahojubeubjy)r@}rA(hhX``mode`` The crop mode (optional). Possible values are: ``center`` When using the center mode the ``x`` and ``y`` parameters are ignored, and the center of the cropped area is placed in the center of the original image. ``center-x`` Center the crop on the x-axis. Use the ``y`` parameter to control the upper edge of the crop. ``center-y`` Center the crop on the y-axis. Use the ``x`` parameter to control the left edge of the crop. hijhjhmhoj|hq}rB(hu]hv]ht]hs]hw]uhyKhzhhc]rC(j)rD}rE(hhX``mode``rFhij@hjhmhojhq}rG(hu]hv]ht]hs]hw]uhyKhc]rHh)rI}rJ(hhjFhq}rK(hu]hv]ht]hs]hw]uhijDhc]rLhXmoderMrN}rO(hhUhijIubahohubaubj)rP}rQ(hhUhq}rR(hu]hv]ht]hs]hw]uhij@hc]rS(h)rT}rU(hhX.The crop mode (optional). Possible values are:rVhijPhjhmhohhq}rW(hu]hv]ht]hs]hw]uhyKhc]rXhX.The crop mode (optional). Possible values are:rYrZ}r[(hhjVhijTubaubjs)r\}r](hhUhq}r^(hu]hv]ht]hs]hw]uhijPhc]r_(jy)r`}ra(hhX``center`` When using the center mode the ``x`` and ``y`` parameters are ignored, and the center of the cropped area is placed in the center of the original image. hij\hjhmhoj|hq}rb(hu]hv]ht]hs]hw]uhyKhc]rc(j)rd}re(hhX ``center``rfhij`hjhmhojhq}rg(hu]hv]ht]hs]hw]uhyKhc]rhh)ri}rj(hhjfhq}rk(hu]hv]ht]hs]hw]uhijdhc]rlhXcenterrmrn}ro(hhUhijiubahohubaubj)rp}rq(hhUhq}rr(hu]hv]ht]hs]hw]uhij`hc]rsh)rt}ru(hhXWhen using the center mode the ``x`` and ``y`` parameters are ignored, and the center of the cropped area is placed in the center of the original image.hijphjhmhohhq}rv(hu]hv]ht]hs]hw]uhyKhc]rw(hXWhen using the center mode the rxry}rz(hhXWhen using the center mode the hijtubh)r{}r|(hhX``x``hq}r}(hu]hv]ht]hs]hw]uhijthc]r~hXxr}r(hhUhij{ubahohubhX and rr}r(hhX and hijtubh)r}r(hhX``y``hq}r(hu]hv]ht]hs]hw]uhijthc]rhXyr}r(hhUhijubahohubhXj parameters are ignored, and the center of the cropped area is placed in the center of the original image.rr}r(hhXj parameters are ignored, and the center of the cropped area is placed in the center of the original image.hijtubeubahojubeubjy)r}r(hhXk``center-x`` Center the crop on the x-axis. Use the ``y`` parameter to control the upper edge of the crop. hij\hjhmhoj|hq}r(hu]hv]ht]hs]hw]uhyKhc]r(j)r}r(hhX ``center-x``rhijhjhmhojhq}r(hu]hv]ht]hs]hw]uhyKhc]rh)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhXcenter-xrr}r(hhUhijubahohubaubj)r}r(hhUhq}r(hu]hv]ht]hs]hw]uhijhc]rh)r}r(hhX]Center the crop on the x-axis. Use the ``y`` parameter to control the upper edge of the crop.hijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyKhc]r(hX'Center the crop on the x-axis. Use the rr}r(hhX'Center the crop on the x-axis. Use the hijubh)r}r(hhX``y``hq}r(hu]hv]ht]hs]hw]uhijhc]rhXyr}r(hhUhijubahohubhX1 parameter to control the upper edge of the crop.rr}r(hhX1 parameter to control the upper edge of the crop.hijubeubahojubeubjy)r}r(hhXj``center-y`` Center the crop on the y-axis. Use the ``x`` parameter to control the left edge of the crop. hij\hjhmhoj|hq}r(hu]hv]ht]hs]hw]uhyKhc]r(j)r}r(hhX ``center-y``rhijhjhmhojhq}r(hu]hv]ht]hs]hw]uhyKhc]rh)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhXcenter-yrr}r(hhUhijubahohubaubj)r}r(hhUhq}r(hu]hv]ht]hs]hw]uhijhc]rh)r}r(hhX\Center the crop on the y-axis. Use the ``x`` parameter to control the left edge of the crop.rhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyKhc]r(hX'Center the crop on the y-axis. Use the rr}r(hhX'Center the crop on the y-axis. Use the hijubh)r}r(hhX``x``hq}r(hu]hv]ht]hs]hw]uhijhc]rhXxr}r(hhUhijubahohubhX0 parameter to control the left edge of the crop.rr}r(hhX0 parameter to control the left edge of the crop.hijubeubahojubeubehojvubehojubeubeubh)r}r(hhX **Examples:**rhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyKhzhhc]rj!)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhX Examples:rr}r(hhUhijubahoj)ubaubj*)r}r(hhUhijhjhmhoj-hq}r(j/X*hs]ht]hu]hv]hw]uhyKhzhhc]r(j1)r}r(hhX+``t[]=crop:x=10,y=25,width=250,height=150``rhijhjhmhoj4hq}r(hu]hv]ht]hs]hw]uhyNhzhhc]rh)r}r(hhjhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyKhc]rh)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhX't[]=crop:x=10,y=25,width=250,height=150rr}r(hhUhijubahohubaubaubj1)r}r(hhX-``t[]=crop:width=100,height=100,mode=center``rhijhjhmhoj4hq}r(hu]hv]ht]hs]hw]uhyNhzhhc]rh)r}r(hhjhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyKhc]rh)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhX)t[]=crop:width=100,height=100,mode=centerrr}r(hhUhijubahohubaubaubj1)r}r(hhX2``t[]=crop:width=50,height=50,mode=center-x,y=15``rhijhjhmhoj4hq}r (hu]hv]ht]hs]hw]uhyNhzhhc]r h)r }r (hhjhijhjhmhohhq}r (hu]hv]ht]hs]hw]uhyKhc]rh)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhij hc]rhX.t[]=crop:width=50,height=50,mode=center-x,y=15rr}r(hhUhijubahohubaubaubj1)r}r(hhX3``t[]=crop:width=50,height=50,mode=center-y,x=15`` hijhjhmhoj4hq}r(hu]hv]ht]hs]hw]uhyNhzhhc]rh)r}r(hhX2``t[]=crop:width=50,height=50,mode=center-y,x=15``rhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyKhc]rh)r}r (hhjhq}r!(hu]hv]ht]hs]hw]uhijhc]r"hX.t[]=crop:width=50,height=50,mode=center-y,x=15r#r$}r%(hhUhijubahohubaubaubeubhe)r&}r'(hhX.. _desaturate-transformation:hijhjhmhohphq}r((hs]ht]hu]hv]hw]hxhAuhyKhzhhc]ubeubh{)r)}r*(hhUhih|hjhmh~}r+hj&shohhq}r,(hu]hv]ht]hs]r-(h_hAehw]r.(h,heuhyKhzhh}r/hAj&shc]r0(h)r1}r2(hhX-Make a gray scaled image - ``t[]=desaturate``r3hij)hjhmhohhq}r4(hu]hv]ht]hs]hw]uhyKhzhhc]r5(hXMake a gray scaled image - r6r7}r8(hhXMake a gray scaled image - r9hij1ubh)r:}r;(hhX``t[]=desaturate``r<hq}r=(hu]hv]ht]hs]hw]uhij1hc]r>hXt[]=desaturater?r@}rA(hhUhij:ubahohubeubh)rB}rC(hhXHThis transformation desaturates the image (in practice, gray scales it).rDhij)hjhmhohhq}rE(hu]hv]ht]hs]hw]uhyKhzhhc]rFhXHThis transformation desaturates the image (in practice, gray scales it).rGrH}rI(hhjDhijBubaubh)rJ}rK(hhX **Examples:**rLhij)hjhmhohhq}rM(hu]hv]ht]hs]hw]uhyKhzhhc]rNj!)rO}rP(hhjLhq}rQ(hu]hv]ht]hs]hw]uhijJhc]rRhX Examples:rSrT}rU(hhUhijOubahoj)ubaubj*)rV}rW(hhUhij)hjhmhoj-hq}rX(j/X*hs]ht]hu]hv]hw]uhyKhzhhc]rYj1)rZ}r[(hhX``t[]=desaturate`` hijVhjhmhoj4hq}r\(hu]hv]ht]hs]hw]uhyNhzhhc]r]h)r^}r_(hhX``t[]=desaturate``r`hijZhjhmhohhq}ra(hu]hv]ht]hs]hw]uhyKhc]rbh)rc}rd(hhj`hq}re(hu]hv]ht]hs]hw]uhij^hc]rfhXt[]=desaturatergrh}ri(hhUhijcubahohubaubaubaubhe)rj}rk(hhX%.. _flip-horizontally-transformation:hij)hjhmhohphq}rl(hs]ht]hu]hv]hw]hxhQuhyKhzhhc]ubeubh{)rm}rn(hhUhih|hjhmh~}rohjjshohhq}rp(hu]hv]ht]hs]rq(hZhQehw]rr(h'heuhyKhzhh}rshQjjshc]rt(h)ru}rv(hhX.Make a mirror image - ``t[]=flipHorizontally``rwhijmhjhmhohhq}rx(hu]hv]ht]hs]hw]uhyKhzhhc]ry(hXMake a mirror image - rzr{}r|(hhXMake a mirror image - r}hijuubh)r~}r(hhX``t[]=flipHorizontally``rhq}r(hu]hv]ht]hs]hw]uhijuhc]rhXt[]=flipHorizontallyrr}r(hhUhij~ubahohubeubh)r}r(hhX1This transformation flips the image horizontally.rhijmhjhmhohhq}r(hu]hv]ht]hs]hw]uhyKhzhhc]rhX1This transformation flips the image horizontally.rr}r(hhjhijubaubh)r}r(hhX **Examples:**rhijmhjhmhohhq}r(hu]hv]ht]hs]hw]uhyKhzhhc]rj!)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhX Examples:rr}r(hhUhijubahoj)ubaubj*)r}r(hhUhijmhjhmhoj-hq}r(j/X*hs]ht]hu]hv]hw]uhyKhzhhc]rj1)r}r(hhX``t[]=flipHorizontally`` hijhjhmhoj4hq}r(hu]hv]ht]hs]hw]uhyNhzhhc]rh)r}r(hhX``t[]=flipHorizontally``rhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyKhc]rh)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhXt[]=flipHorizontallyrr}r(hhUhijubahohubaubaubaubhe)r}r(hhX#.. _flip-vertically-transformation:hijmhjhmhohphq}r(hs]ht]hu]hv]hw]hxhNuhyKhzhhc]ubeubh{)r}r(hhUhih|hjhmh~}rhjshohhq}r(hu]hv]ht]hs]r(hLhNehw]r(hheuhyKhzhh}rhNjshc]r(h)r}r(hhX3Flip the image upside down - ``t[]=flipVertically``rhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyKhzhhc]r(hXFlip the image upside down - rr}r(hhXFlip the image upside down - rhijubh)r}r(hhX``t[]=flipVertically``rhq}r(hu]hv]ht]hs]hw]uhijhc]rhXt[]=flipVerticallyrr}r(hhUhijubahohubeubh)r}r(hhX/This transformation flips the image vertically.rhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyKhzhhc]rhX/This transformation flips the image vertically.rr}r(hhjhijubaubh)r}r(hhX **Examples:**rhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyKhzhhc]rj!)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhX Examples:rr}r(hhUhijubahoj)ubaubj*)r}r(hhUhijhjhmhoj-hq}r(j/X*hs]ht]hu]hv]hw]uhyKhzhhc]rj1)r}r(hhX``t[]=flipVertically`` hijhjhmhoj4hq}r(hu]hv]ht]hs]hw]uhyNhzhhc]rh)r}r(hhX``t[]=flipVertically``rhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyKhc]rh)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhXt[]=flipVerticallyrr}r(hhUhijubahohubaubaubaubhe)r}r(hhX.. _max-size-transformation:hijhjhmhohphq}r(hs]ht]hu]hv]hw]hxhh` transformation: given both ``width`` and ``height``, the resulting image will not be the same width and height as specified unless the aspect ratio is the same.rhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyKhzhhc]r(hXNote the difference from the rr}r(hhXNote the difference from the hijubj)r}r(hhX%:ref:`resize `r hijhjhmhojhq}r!(UreftypeXrefjjXresize-transformationU refdomainXstdr"hs]ht]U refexplicithu]hv]hw]j j uhyKhc]r#j )r$}r%(hhj hq}r&(hu]hv]r'(jj"Xstd-refr(eht]hs]hw]uhijhc]r)hXresizer*r+}r,(hhUhij$ubahojubaubhX transformation: given both r-r.}r/(hhX transformation: given both hijubh)r0}r1(hhX ``width``hq}r2(hu]hv]ht]hs]hw]uhijhc]r3hXwidthr4r5}r6(hhUhij0ubahohubhX and r7r8}r9(hhX and hijubh)r:}r;(hhX ``height``hq}r<(hu]hv]ht]hs]hw]uhijhc]r=hXheightr>r?}r@(hhUhij:ubahohubhXm, the resulting image will not be the same width and height as specified unless the aspect ratio is the same.rArB}rC(hhXm, the resulting image will not be the same width and height as specified unless the aspect ratio is the same.hijubeubh)rD}rE(hhX**Parameters:**rFhijhjhmhohhq}rG(hu]hv]ht]hs]hw]uhyKhzhhc]rHj!)rI}rJ(hhjFhq}rK(hu]hv]ht]hs]hw]uhijDhc]rLhX Parameters:rMrN}rO(hhUhijIubahoj)ubaubjs)rP}rQ(hhUhijhjhmhojvhq}rR(hu]hv]ht]hs]hw]uhyNhzhhc]rS(jy)rT}rU(hhX``width`` The max width of the resulting image in pixels. If not specified the width will be calculated using the same aspect ratio as the original image. hijPhjhmhoj|hq}rV(hu]hv]ht]hs]hw]uhyKhc]rW(j)rX}rY(hhX ``width``rZhijThjhmhojhq}r[(hu]hv]ht]hs]hw]uhyKhc]r\h)r]}r^(hhjZhq}r_(hu]hv]ht]hs]hw]uhijXhc]r`hXwidthrarb}rc(hhUhij]ubahohubaubj)rd}re(hhUhq}rf(hu]hv]ht]hs]hw]uhijThc]rgh)rh}ri(hhXThe max width of the resulting image in pixels. If not specified the width will be calculated using the same aspect ratio as the original image.rjhijdhjhmhohhq}rk(hu]hv]ht]hs]hw]uhyKhc]rlhXThe max width of the resulting image in pixels. If not specified the width will be calculated using the same aspect ratio as the original image.rmrn}ro(hhjjhijhubaubahojubeubjy)rp}rq(hhX``height`` The max height of the resulting image in pixels. If not specified the height will be calculated using the same aspect ratio as the original image. hijPhjhmhoj|hq}rr(hu]hv]ht]hs]hw]uhyKhzhhc]rs(j)rt}ru(hhX ``height``rvhijphjhmhojhq}rw(hu]hv]ht]hs]hw]uhyKhc]rxh)ry}rz(hhjvhq}r{(hu]hv]ht]hs]hw]uhijthc]r|hXheightr}r~}r(hhUhijyubahohubaubj)r}r(hhUhq}r(hu]hv]ht]hs]hw]uhijphc]rh)r}r(hhXThe max height of the resulting image in pixels. If not specified the height will be calculated using the same aspect ratio as the original image.rhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyKhc]rhXThe max height of the resulting image in pixels. If not specified the height will be calculated using the same aspect ratio as the original image.rr}r(hhjhijubaubahojubeubeubh)r}r(hhX **Examples:**rhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyKhzhhc]rj!)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhX Examples:rr}r(hhUhijubahoj)ubaubj*)r}r(hhUhijhjhmhoj-hq}r(j/X*hs]ht]hu]hv]hw]uhyKhzhhc]r(j1)r}r(hhX``t[]=maxSize:width=100``rhijhjhmhoj4hq}r(hu]hv]ht]hs]hw]uhyNhzhhc]rh)r}r(hhjhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyKhc]rh)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhXt[]=maxSize:width=100rr}r(hhUhijubahohubaubaubj1)r}r(hhX``t[]=maxSize:height=100``rhijhjhmhoj4hq}r(hu]hv]ht]hs]hw]uhyNhzhhc]rh)r}r(hhjhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyKhc]rh)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhXt[]=maxSize:height=100rr}r(hhUhijubahohubaubaubj1)r}r(hhX$``t[]=maxSize:width=100,height=50`` hijhjhmhoj4hq}r(hu]hv]ht]hs]hw]uhyNhzhhc]rh)r}r(hhX#``t[]=maxSize:width=100,height=50``rhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyKhc]rh)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhXt[]=maxSize:width=100,height=50rr}r(hhUhijubahohubaubaubeubhe)r}r(hhX.. _modulate-transformation:hijhjhmhohphq}r(hs]ht]hu]hv]hw]hxhIuhyKhzhhc]ubeubh{)r}r(hhUhih|hjhmh~}rhjshohhq}r(hu]hv]ht]hs]r(hVhIehw]r(h#heuhyKhzhh}rhIjshc]r(h)r}r(hhX%Modulate the image - ``t[]=modulate``rhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyKhzhhc]r(hXModulate the image - rr}r(hhXModulate the image - rhijubh)r}r(hhX``t[]=modulate``rhq}r(hu]hv]ht]hs]hw]uhijhc]rhX t[]=modulaterr}r(hhUhijubahohubeubh)r}r(hhX[This transformation can be used to control the brightness, saturation and hue of the image.rhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyKhzhhc]rhX[This transformation can be used to control the brightness, saturation and hue of the image.rr}r(hhjhijubaubh)r}r(hhX**Parameters:**rhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyKhzhhc]rj!)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhX Parameters:rr}r(hhUhijubahoj)ubaubjs)r}r(hhUhijhjhmhojvhq}r(hu]hv]ht]hs]hw]uhyNhzhhc]r(jy)r }r (hhX;``b`` Brightness of the image in percent. Defaults to 100. hijhjhmhoj|hq}r (hu]hv]ht]hs]hw]uhyKhc]r (j)r }r (hhX``b``r hij hjhmhojhq}r (hu]hv]ht]hs]hw]uhyKhc]r h)r }r (hhj hq}r (hu]hv]ht]hs]hw]uhij hc]r hXbr }r (hhUhij ubahohubaubj)r }r (hhUhq}r (hu]hv]ht]hs]hw]uhij hc]r h)r }r (hhX4Brightness of the image in percent. Defaults to 100.r hij hjhmhohhq}r (hu]hv]ht]hs]hw]uhyKhc]r hX4Brightness of the image in percent. Defaults to 100.r r }r (hhj hij ubaubahojubeubjy)r }r (hhX;``s`` Saturation of the image in percent. Defaults to 100. hijhjhmhoj|hq}r (hu]hv]ht]hs]hw]uhyKhzhhc]r (j)r }r (hhX``s``r! hij hjhmhojhq}r" (hu]hv]ht]hs]hw]uhyKhc]r# h)r$ }r% (hhj! hq}r& (hu]hv]ht]hs]hw]uhij hc]r' hXsr( }r) (hhUhij$ ubahohubaubj)r* }r+ (hhUhq}r, (hu]hv]ht]hs]hw]uhij hc]r- h)r. }r/ (hhX4Saturation of the image in percent. Defaults to 100.r0 hij* hjhmhohhq}r1 (hu]hv]ht]hs]hw]uhyKhc]r2 hX4Saturation of the image in percent. Defaults to 100.r3 r4 }r5 (hhj0 hij. ubaubahojubeubjy)r6 }r7 (hhX'``h`` Hue percentage. Defaults to 100. hijhjhmhoj|hq}r8 (hu]hv]ht]hs]hw]uhyKhzhhc]r9 (j)r: }r; (hhX``h``r< hij6 hjhmhojhq}r= (hu]hv]ht]hs]hw]uhyKhc]r> h)r? }r@ (hhj< hq}rA (hu]hv]ht]hs]hw]uhij: hc]rB hXhrC }rD (hhUhij? ubahohubaubj)rE }rF (hhUhq}rG (hu]hv]ht]hs]hw]uhij6 hc]rH h)rI }rJ (hhX Hue percentage. Defaults to 100.rK hijE hjhmhohhq}rL (hu]hv]ht]hs]hw]uhyKhc]rM hX Hue percentage. Defaults to 100.rN rO }rP (hhjK hijI ubaubahojubeubeubh)rQ }rR (hhX **Examples:**rS hijhjhmhohhq}rT (hu]hv]ht]hs]hw]uhyKhzhhc]rU j!)rV }rW (hhjS hq}rX (hu]hv]ht]hs]hw]uhijQ hc]rY hX Examples:rZ r[ }r\ (hhUhijV ubahoj)ubaubj*)r] }r^ (hhUhijhjhmhoj-hq}r_ (j/X*hs]ht]hu]hv]hw]uhyKhzhhc]r` (j1)ra }rb (hhX``t[]=modulate:b=150``rc hij] hjhmhoj4hq}rd (hu]hv]ht]hs]hw]uhyNhzhhc]re h)rf }rg (hhjc hija hjhmhohhq}rh (hu]hv]ht]hs]hw]uhyKhc]ri h)rj }rk (hhjc hq}rl (hu]hv]ht]hs]hw]uhijf hc]rm hXt[]=modulate:b=150rn ro }rp (hhUhijj ubahohubaubaubj1)rq }rr (hhX"``t[]=modulate:b=120,s=130,h=90`` hij] hjhmhoj4hq}rs (hu]hv]ht]hs]hw]uhyNhzhhc]rt h)ru }rv (hhX!``t[]=modulate:b=120,s=130,h=90``rw hijq hjhmhohhq}rx (hu]hv]ht]hs]hw]uhyKhc]ry h)rz }r{ (hhjw hq}r| (hu]hv]ht]hs]hw]uhiju hc]r} hXt[]=modulate:b=120,s=130,h=90r~ r }r (hhUhijz ubahohubaubaubeubhe)r }r (hhX.. _progressive-transformation:hijhjhmhohphq}r (hs]ht]hu]hv]hw]hxhPuhyKhzhhc]ubeubh{)r }r (hhUhih|hjhmh~}r hj shohhq}r (hu]hv]ht]hs]r (h`hPehw]r (h-heuhyKhzhh}r hPj shc]r (h)r }r (hhX.Make a progressive image - ``t[]=progressive``r hij hjhmhohhq}r (hu]hv]ht]hs]hw]uhyKhzhhc]r (hXMake a progressive image - r r }r (hhXMake a progressive image - r hij ubh)r }r (hhX``t[]=progressive``r hq}r (hu]hv]ht]hs]hw]uhij hc]r hXt[]=progressiver r }r (hhUhij ubahohubeubh)r }r (hhX0This transformation makes the image progressive.r hij hjhmhohhq}r (hu]hv]ht]hs]hw]uhyKhzhhc]r hX0This transformation makes the image progressive.r r }r (hhj hij ubaubh)r }r (hhX **Examples:**r hij hjhmhohhq}r (hu]hv]ht]hs]hw]uhyKhzhhc]r j!)r }r (hhj hq}r (hu]hv]ht]hs]hw]uhij hc]r hX Examples:r r }r (hhUhij ubahoj)ubaubj*)r }r (hhUhij hjhmhoj-hq}r (j/X*hs]ht]hu]hv]hw]uhyKhzhhc]r j1)r }r (hhX``t[]=progressive`` hij hjhmhoj4hq}r (hu]hv]ht]hs]hw]uhyNhzhhc]r h)r }r (hhX``t[]=progressive``r hij hjhmhohhq}r (hu]hv]ht]hs]hw]uhyKhc]r h)r }r (hhj hq}r (hu]hv]ht]hs]hw]uhij hc]r hXt[]=progressiver r }r (hhUhij ubahohubaubaubaubhe)r }r (hhX.. _resize-transformation:hij hjhmhohphq}r (hs]ht]hu]hv]hw]hxhJuhyKhzhhc]ubeubh{)r }r (hhUhih|hjhmh~}r hj shohhq}r (hu]hv]ht]hs]r (hWhJehw]r (h$heuhyKhzhh}r hJj shc]r (h)r }r (hhX!Resize the image - ``t[]=resize``r hij hjhmhohhq}r (hu]hv]ht]hs]hw]uhyKhzhhc]r (hXResize the image - r r }r (hhXResize the image - r hij ubh)r }r (hhX``t[]=resize``r hq}r (hu]hv]ht]hs]hw]uhij hc]r hX t[]=resizer r }r (hhUhij ubahohubeubh)r }r (hhXThis transformation will resize the image. Two parameters are supported and at least one of them must be supplied to apply the transformation.r hij hjhmhohhq}r (hu]hv]ht]hs]hw]uhyKhzhhc]r hXThis transformation will resize the image. Two parameters are supported and at least one of them must be supplied to apply the transformation.r r }r (hhj hij ubaubh)r }r (hhX**Parameters:**r hij hjhmhohhq}r (hu]hv]ht]hs]hw]uhyKhzhhc]r j!)r }r (hhj hq}r (hu]hv]ht]hs]hw]uhij hc]r hX Parameters:r r }r (hhUhij ubahoj)ubaubjs)r }r (hhUhij hjhmhojvhq}r (hu]hv]ht]hs]hw]uhyNhzhhc]r (jy)r }r (hhX``width`` The width of the resulting image in pixels. If not specified the width will be calculated using the same aspect ratio as the original image. hij hjhmhoj|hq}r (hu]hv]ht]hs]hw]uhyMhc]r (j)r }r (hhX ``width``r hij hjhmhojhq}r (hu]hv]ht]hs]hw]uhyMhc]r h)r }r (hhj hq}r (hu]hv]ht]hs]hw]uhij hc]r hXwidthr r }r (hhUhij ubahohubaubj)r }r (hhUhq}r (hu]hv]ht]hs]hw]uhij hc]r h)r }r (hhXThe width of the resulting image in pixels. If not specified the width will be calculated using the same aspect ratio as the original image.r hij hjhmhohhq}r (hu]hv]ht]hs]hw]uhyMhc]r hXThe width of the resulting image in pixels. If not specified the width will be calculated using the same aspect ratio as the original image.r r }r (hhj hij ubaubahojubeubjy)r }r (hhX``height`` The height of the resulting image in pixels. If not specified the height will be calculated using the same aspect ratio as the original image. hij hjhmhoj|hq}r (hu]hv]ht]hs]hw]uhyMhzhhc]r (j)r }r (hhX ``height``r hij hjhmhojhq}r (hu]hv]ht]hs]hw]uhyMhc]r h)r }r (hhj hq}r (hu]hv]ht]hs]hw]uhij hc]r! hXheightr" r# }r$ (hhUhij ubahohubaubj)r% }r& (hhUhq}r' (hu]hv]ht]hs]hw]uhij hc]r( h)r) }r* (hhXThe height of the resulting image in pixels. If not specified the height will be calculated using the same aspect ratio as the original image.r+ hij% hjhmhohhq}r, (hu]hv]ht]hs]hw]uhyMhc]r- hXThe height of the resulting image in pixels. If not specified the height will be calculated using the same aspect ratio as the original image.r. r/ }r0 (hhj+ hij) ubaubahojubeubeubh)r1 }r2 (hhX **Examples:**r3 hij hjhmhohhq}r4 (hu]hv]ht]hs]hw]uhyMhzhhc]r5 j!)r6 }r7 (hhj3 hq}r8 (hu]hv]ht]hs]hw]uhij1 hc]r9 hX Examples:r: r; }r< (hhUhij6 ubahoj)ubaubj*)r= }r> (hhUhij hjhmhoj-hq}r? (j/X*hs]ht]hu]hv]hw]uhyM hzhhc]r@ (j1)rA }rB (hhX``t[]=resize:width=100``rC hij= hjhmhoj4hq}rD (hu]hv]ht]hs]hw]uhyNhzhhc]rE h)rF }rG (hhjC hijA hjhmhohhq}rH (hu]hv]ht]hs]hw]uhyM hc]rI h)rJ }rK (hhjC hq}rL (hu]hv]ht]hs]hw]uhijF hc]rM hXt[]=resize:width=100rN rO }rP (hhUhijJ ubahohubaubaubj1)rQ }rR (hhX``t[]=resize:height=100``rS hij= hjhmhoj4hq}rT (hu]hv]ht]hs]hw]uhyNhzhhc]rU h)rV }rW (hhjS hijQ hjhmhohhq}rX (hu]hv]ht]hs]hw]uhyM hc]rY h)rZ }r[ (hhjS hq}r\ (hu]hv]ht]hs]hw]uhijV hc]r] hXt[]=resize:height=100r^ r_ }r` (hhUhijZ ubahohubaubaubj1)ra }rb (hhX#``t[]=resize:width=100,height=50`` hij= hjhmhoj4hq}rc (hu]hv]ht]hs]hw]uhyNhzhhc]rd h)re }rf (hhX"``t[]=resize:width=100,height=50``rg hija hjhmhohhq}rh (hu]hv]ht]hs]hw]uhyM hc]ri h)rj }rk (hhjg hq}rl (hu]hv]ht]hs]hw]uhije hc]rm hXt[]=resize:width=100,height=50rn ro }rp (hhUhijj ubahohubaubaubeubhe)rq }rr (hhX.. _rotate-transformation:hij hjhmhohphq}rs (hs]ht]hu]hv]hw]hxh\uhyM hzhhc]ubeubh{)rt }ru (hhUhih|hjhmh~}rv h)jq shohhq}rw (hu]hv]ht]hs]rx (hKh\ehw]ry (hh)euhyMhzhh}rz h\jq shc]r{ (h)r| }r} (hhX!Rotate the image - ``t[]=rotate``r~ hijt hjhmhohhq}r (hu]hv]ht]hs]hw]uhyMhzhhc]r (hXRotate the image - r r }r (hhXRotate the image - r hij| ubh)r }r (hhX``t[]=rotate``r hq}r (hu]hv]ht]hs]hw]uhij| hc]r hX t[]=rotater r }r (hhUhij ubahohubeubh)r }r (hhX5This transformation will rotate the image clock-wise.r hijt hjhmhohhq}r (hu]hv]ht]hs]hw]uhyMhzhhc]r hX5This transformation will rotate the image clock-wise.r r }r (hhj hij ubaubh)r }r (hhX**Parameters:**r hijt hjhmhohhq}r (hu]hv]ht]hs]hw]uhyMhzhhc]r j!)r }r (hhj hq}r (hu]hv]ht]hs]hw]uhij hc]r hX Parameters:r r }r (hhUhij ubahoj)ubaubjs)r }r (hhUhijt hjhmhojvhq}r (hu]hv]ht]hs]hw]uhyNhzhhc]r (jy)r }r (hhXB``angle`` The number of degrees to rotate the image (clock-wise). hij hjhmhoj|hq}r (hu]hv]ht]hs]hw]uhyMhc]r (j)r }r (hhX ``angle``r hij hjhmhojhq}r (hu]hv]ht]hs]hw]uhyMhc]r h)r }r (hhj hq}r (hu]hv]ht]hs]hw]uhij hc]r hXangler r }r (hhUhij ubahohubaubj)r }r (hhUhq}r (hu]hv]ht]hs]hw]uhij hc]r h)r }r (hhX7The number of degrees to rotate the image (clock-wise).r hij hjhmhohhq}r (hu]hv]ht]hs]hw]uhyMhc]r hX7The number of degrees to rotate the image (clock-wise).r r }r (hhj hij ubaubahojubeubjy)r }r (hhXw``bg`` Background color in hexadecimal. Defaults to ``000000`` (also supports short values like ``f00`` (``ff0000``)). hij hjhmhoj|hq}r (hu]hv]ht]hs]hw]uhyMhzhhc]r (j)r }r (hhX``bg``r hij hjhmhojhq}r (hu]hv]ht]hs]hw]uhyMhc]r h)r }r (hhj hq}r (hu]hv]ht]hs]hw]uhij hc]r hXbgr r }r (hhUhij ubahohubaubj)r }r (hhUhq}r (hu]hv]ht]hs]hw]uhij hc]r h)r }r (hhXoBackground color in hexadecimal. Defaults to ``000000`` (also supports short values like ``f00`` (``ff0000``)).hij hjhmhohhq}r (hu]hv]ht]hs]hw]uhyMhc]r (hX-Background color in hexadecimal. Defaults to r r }r (hhX-Background color in hexadecimal. Defaults to hij ubh)r }r (hhX ``000000``hq}r (hu]hv]ht]hs]hw]uhij hc]r hX000000r r }r (hhUhij ubahohubhX" (also supports short values like r r }r (hhX" (also supports short values like hij ubh)r }r (hhX``f00``hq}r (hu]hv]ht]hs]hw]uhij hc]r hXf00r r }r (hhUhij ubahohubhX (r r }r (hhX (hij ubh)r }r (hhX ``ff0000``hq}r (hu]hv]ht]hs]hw]uhij hc]r hXff0000r r }r (hhUhij ubahohubhX)).r r }r (hhX)).hij ubeubahojubeubeubh)r }r (hhX **Examples:**r hijt hjhmhohhq}r (hu]hv]ht]hs]hw]uhyMhzhhc]r j!)r }r (hhj hq}r (hu]hv]ht]hs]hw]uhij hc]r hX Examples:r r }r (hhUhij ubahoj)ubaubj*)r }r (hhUhijt hjhmhoj-hq}r (j/X*hs]ht]hu]hv]hw]uhyMhzhhc]r (j1)r }r (hhX``t[]=rotate:angle=90``r hij hjhmhoj4hq}r (hu]hv]ht]hs]hw]uhyNhzhhc]r h)r }r (hhj hij hjhmhohhq}r (hu]hv]ht]hs]hw]uhyMhc]r h)r }r (hhj hq}r (hu]hv]ht]hs]hw]uhij hc]r hXt[]=rotate:angle=90r r }r (hhUhij ubahohubaubaubj1)r }r (hhX``t[]=rotate:angle=45,bg=fff`` hij hjhmhoj4hq}r (hu]hv]ht]hs]hw]uhyNhzhhc]r h)r }r (hhX``t[]=rotate:angle=45,bg=fff``r hij hjhmhohhq}r! (hu]hv]ht]hs]hw]uhyMhc]r" h)r# }r$ (hhj hq}r% (hu]hv]ht]hs]hw]uhij hc]r& hXt[]=rotate:angle=45,bg=fffr' r( }r) (hhUhij# ubahohubaubaubeubhe)r* }r+ (hhX.. _sepia-transformation:hijt hjhmhohphq}r, (hs]ht]hu]hv]hw]hxhCuhyM!hzhhc]ubeubh{)r- }r. (hhUhih|hjhmh~}r/ hj* shohhq}r0 (hu]hv]ht]hs]r1 (h[hCehw]r2 (h(heuhyM$hzhh}r3 hCj* shc]r4 (h)r5 }r6 (hhX(Apply a sepia color tone - ``t[]=sepia``r7 hij- hjhmhohhq}r8 (hu]hv]ht]hs]hw]uhyM$hzhhc]r9 (hXApply a sepia color tone - r: r; }r< (hhXApply a sepia color tone - r= hij5 ubh)r> }r? (hhX ``t[]=sepia``r@ hq}rA (hu]hv]ht]hs]hw]uhij5 hc]rB hX t[]=sepiarC rD }rE (hhUhij> ubahohubeubh)rF }rG (hhXNThis transformation will apply a sepia color tone transformation to the image.rH hij- hjhmhohhq}rI (hu]hv]ht]hs]hw]uhyM&hzhhc]rJ hXNThis transformation will apply a sepia color tone transformation to the image.rK rL }rM (hhjH hijF ubaubh)rN }rO (hhX**Parameters:**rP hij- hjhmhohhq}rQ (hu]hv]ht]hs]hw]uhyM(hzhhc]rR j!)rS }rT (hhjP hq}rU (hu]hv]ht]hs]hw]uhijN hc]rV hX Parameters:rW rX }rY (hhUhijS ubahoj)ubaubjs)rZ }r[ (hhUhij- hjhmhojvhq}r\ (hu]hv]ht]hs]hw]uhyNhzhhc]r] jy)r^ }r_ (hhX}``threshold`` Threshold ranges from 0 to QuantumRange and is a measure of the extent of the sepia toning. Defaults to ``80`` hijZ hjhmhoj|hq}r` (hu]hv]ht]hs]hw]uhyM+hc]ra (j)rb }rc (hhX ``threshold``rd hij^ hjhmhojhq}re (hu]hv]ht]hs]hw]uhyM+hc]rf h)rg }rh (hhjd hq}ri (hu]hv]ht]hs]hw]uhijb hc]rj hX thresholdrk rl }rm (hhUhijg ubahohubaubj)rn }ro (hhUhq}rp (hu]hv]ht]hs]hw]uhij^ hc]rq h)rr }rs (hhXnThreshold ranges from 0 to QuantumRange and is a measure of the extent of the sepia toning. Defaults to ``80``hijn hjhmhohhq}rt (hu]hv]ht]hs]hw]uhyM+hc]ru (hXhThreshold ranges from 0 to QuantumRange and is a measure of the extent of the sepia toning. Defaults to rv rw }rx (hhXhThreshold ranges from 0 to QuantumRange and is a measure of the extent of the sepia toning. Defaults to hijr ubh)ry }rz (hhX``80``hq}r{ (hu]hv]ht]hs]hw]uhijr hc]r| hX80r} r~ }r (hhUhijy ubahohubeubahojubeubaubh)r }r (hhX **Examples:**r hij- hjhmhohhq}r (hu]hv]ht]hs]hw]uhyM-hzhhc]r j!)r }r (hhj hq}r (hu]hv]ht]hs]hw]uhij hc]r hX Examples:r r }r (hhUhij ubahoj)ubaubj*)r }r (hhUhij- hjhmhoj-hq}r (j/X*hs]ht]hu]hv]hw]uhyM/hzhhc]r (j1)r }r (hhX ``t[]=sepia``r hij hjhmhoj4hq}r (hu]hv]ht]hs]hw]uhyNhzhhc]r h)r }r (hhj hij hjhmhohhq}r (hu]hv]ht]hs]hw]uhyM/hc]r h)r }r (hhj hq}r (hu]hv]ht]hs]hw]uhij hc]r hX t[]=sepiar r }r (hhUhij ubahohubaubaubj1)r }r (hhX``t[]=sepia:threshold=70`` hij hjhmhoj4hq}r (hu]hv]ht]hs]hw]uhyNhzhhc]r h)r }r (hhX``t[]=sepia:threshold=70``r hij hjhmhohhq}r (hu]hv]ht]hs]hw]uhyM0hc]r h)r }r (hhj hq}r (hu]hv]ht]hs]hw]uhij hc]r hXt[]=sepia:threshold=70r r }r (hhUhij ubahohubaubaubeubhe)r }r (hhX.. _strip-transformation:hij- hjhmhohphq}r (hs]ht]hu]hv]hw]hxhHuhyM2hzhhc]ubeubh{)r }r (hhUhih|hjhmh~}r hj shohhq}r (hu]hv]ht]hs]r (h@hHehw]r (h heuhyM5hzhh}r hHj shc]r (h)r }r (hhX3Strip image properties and comments - ``t[]=strip``r hij hjhmhohhq}r (hu]hv]ht]hs]hw]uhyM5hzhhc]r (hX&Strip image properties and comments - r r }r (hhX&Strip image properties and comments - r hij ubh)r }r (hhX ``t[]=strip``r hq}r (hu]hv]ht]hs]hw]uhij hc]r hX t[]=stripr r }r (hhUhij ubahohubeubh)r }r (hhXThis transformation removes all properties and comments from the image. If you want to strip EXIF tags from the image for instance, this transformation will do that for you.r hij hjhmhohhq}r (hu]hv]ht]hs]hw]uhyM7hzhhc]r hXThis transformation removes all properties and comments from the image. If you want to strip EXIF tags from the image for instance, this transformation will do that for you.r r }r (hhj hij ubaubh)r }r (hhX **Examples:**r hij hjhmhohhq}r (hu]hv]ht]hs]hw]uhyM9hzhhc]r j!)r }r (hhj hq}r (hu]hv]ht]hs]hw]uhij hc]r hX Examples:r r }r (hhUhij ubahoj)ubaubj*)r }r (hhUhij hjhmhoj-hq}r (j/X*hs]ht]hu]hv]hw]uhyM;hzhhc]r j1)r }r (hhX``t[]=strip`` hij hjhmhoj4hq}r (hu]hv]ht]hs]hw]uhyNhzhhc]r h)r }r (hhX ``t[]=strip``r hij hjhmhohhq}r (hu]hv]ht]hs]hw]uhyM;hc]r h)r }r (hhj hq}r (hu]hv]ht]hs]hw]uhij hc]r hX t[]=stripr r }r (hhUhij ubahohubaubaubaubhe)r }r (hhX.. _thumbnail-transformation:hij hjhmhohphq}r (hs]ht]hu]hv]hw]hxh:uhyM=hzhhc]ubeubh{)r }r (hhUhih|hjhmh~}r hj shohhq}r (hu]hv]ht]hs]r (hSh:ehw]r (h heuhyM@hzhh}r h:j shc]r (h)r }r (hhX3Create a thumbnail of the image - ``t[]=thumbnail``r hij hjhmhohhq}r (hu]hv]ht]hs]hw]uhyM@hzhhc]r (hX"Create a thumbnail of the image - r r }r (hhX"Create a thumbnail of the image - r hij ubh)r }r (hhX``t[]=thumbnail``r hq}r (hu]hv]ht]hs]hw]uhij hc]r hX t[]=thumbnailr r }r (hhUhij ubahohubeubh)r }r (hhX7This transformation creates a thumbnail of ````.r hij hjhmhohhq}r (hu]hv]ht]hs]hw]uhyMBhzhhc]r (hX+This transformation creates a thumbnail of r r }r (hhX+This transformation creates a thumbnail of hij ubh)r }r (hhX ````hq}r (hu]hv]ht]hs]hw]uhij hc]r hXr r }r (hhUhij ubahohubhX.r }r (hhX.hij ubeubh)r! }r" (hhX**Parameters:**r# hij hjhmhohhq}r$ (hu]hv]ht]hs]hw]uhyMDhzhhc]r% j!)r& }r' (hhj# hq}r( (hu]hv]ht]hs]hw]uhij! hc]r) hX Parameters:r* r+ }r, (hhUhij& ubahoj)ubaubjs)r- }r. (hhUhij hjhmhojvhq}r/ (hu]hv]ht]hs]hw]uhyNhzhhc]r0 (jy)r1 }r2 (hhX@``width`` Width of the thumbnail in pixels. Defaults to ``50``. hij- hjhmhoj|hq}r3 (hu]hv]ht]hs]hw]uhyMGhc]r4 (j)r5 }r6 (hhX ``width``r7 hij1 hjhmhojhq}r8 (hu]hv]ht]hs]hw]uhyMGhc]r9 h)r: }r; (hhj7 hq}r< (hu]hv]ht]hs]hw]uhij5 hc]r= hXwidthr> r? }r@ (hhUhij: ubahohubaubj)rA }rB (hhUhq}rC (hu]hv]ht]hs]hw]uhij1 hc]rD h)rE }rF (hhX5Width of the thumbnail in pixels. Defaults to ``50``.hijA hjhmhohhq}rG (hu]hv]ht]hs]hw]uhyMGhc]rH (hX.Width of the thumbnail in pixels. Defaults to rI rJ }rK (hhX.Width of the thumbnail in pixels. Defaults to hijE ubh)rL }rM (hhX``50``hq}rN (hu]hv]ht]hs]hw]uhijE hc]rO hX50rP rQ }rR (hhUhijL ubahohubhX.rS }rT (hhX.hijE ubeubahojubeubjy)rU }rV (hhXB``height`` Height of the thumbnail in pixels. Defaults to ``50``. hij- hjhmhoj|hq}rW (hu]hv]ht]hs]hw]uhyMJhzhhc]rX (j)rY }rZ (hhX ``height``r[ hijU hjhmhojhq}r\ (hu]hv]ht]hs]hw]uhyMJhc]r] h)r^ }r_ (hhj[ hq}r` (hu]hv]ht]hs]hw]uhijY hc]ra hXheightrb rc }rd (hhUhij^ ubahohubaubj)re }rf (hhUhq}rg (hu]hv]ht]hs]hw]uhijU hc]rh h)ri }rj (hhX6Height of the thumbnail in pixels. Defaults to ``50``.hije hjhmhohhq}rk (hu]hv]ht]hs]hw]uhyMJhc]rl (hX/Height of the thumbnail in pixels. Defaults to rm rn }ro (hhX/Height of the thumbnail in pixels. Defaults to hiji ubh)rp }rq (hhX``50``hq}rr (hu]hv]ht]hs]hw]uhiji hc]rs hX50rt ru }rv (hhUhijp ubahohubhX.rw }rx (hhX.hiji ubeubahojubeubjy)ry }rz (hhX\``fit`` Fit style. Possible values are: ``inset`` or ``outbound``. Default to ``outbound``. hij- hjhmhoj|hq}r{ (hu]hv]ht]hs]hw]uhyMMhzhhc]r| (j)r} }r~ (hhX``fit``r hijy hjhmhojhq}r (hu]hv]ht]hs]hw]uhyMMhc]r h)r }r (hhj hq}r (hu]hv]ht]hs]hw]uhij} hc]r hXfitr r }r (hhUhij ubahohubaubj)r }r (hhUhq}r (hu]hv]ht]hs]hw]uhijy hc]r h)r }r (hhXSFit style. Possible values are: ``inset`` or ``outbound``. Default to ``outbound``.hij hjhmhohhq}r (hu]hv]ht]hs]hw]uhyMMhc]r (hX Fit style. Possible values are: r r }r (hhX Fit style. Possible values are: hij ubh)r }r (hhX ``inset``hq}r (hu]hv]ht]hs]hw]uhij hc]r hXinsetr r }r (hhUhij ubahohubhX or r r }r (hhX or hij ubh)r }r (hhX ``outbound``hq}r (hu]hv]ht]hs]hw]uhij hc]r hXoutboundr r }r (hhUhij ubahohubhX . Default to r r }r (hhX . Default to hij ubh)r }r (hhX ``outbound``hq}r (hu]hv]ht]hs]hw]uhij hc]r hXoutboundr r }r (hhUhij ubahohubhX.r }r (hhX.hij ubeubahojubeubeubh)r }r (hhX **Examples:**r hij hjhmhohhq}r (hu]hv]ht]hs]hw]uhyMOhzhhc]r j!)r }r (hhj hq}r (hu]hv]ht]hs]hw]uhij hc]r hX Examples:r r }r (hhUhij ubahoj)ubaubj*)r }r (hhUhij hjhmhoj-hq}r (j/X*hs]ht]hu]hv]hw]uhyMQhzhhc]r (j1)r }r (hhX``t[]=thumbnail``r hij hjhmhoj4hq}r (hu]hv]ht]hs]hw]uhyNhzhhc]r h)r }r (hhj hij hjhmhohhq}r (hu]hv]ht]hs]hw]uhyMQhc]r h)r }r (hhj hq}r (hu]hv]ht]hs]hw]uhij hc]r hX t[]=thumbnailr r }r (hhUhij ubahohubaubaubj1)r }r (hhX/``t[]=thumbnail:width=20,height=20,fit=inset`` hij hjhmhoj4hq}r (hu]hv]ht]hs]hw]uhyNhzhhc]r h)r }r (hhX.``t[]=thumbnail:width=20,height=20,fit=inset``r hij hjhmhohhq}r (hu]hv]ht]hs]hw]uhyMRhc]r h)r }r (hhj hq}r (hu]hv]ht]hs]hw]uhij hc]r hX*t[]=thumbnail:width=20,height=20,fit=insetr r }r (hhUhij ubahohubaubaubeubhe)r }r (hhX.. _transpose-transformation:hij hjhmhohphq}r (hs]ht]hu]hv]hw]hxhUuhyMThzhhc]ubeubh{)r }r (hhUhih|hjhmh~}r h"j shohhq}r (hu]hv]ht]hs]r (h=hUehw]r (h h"euhyMWhzhh}r hUj shc]r (h)r }r (hhX2Create a vertical mirror image - ``t[]=transpose``r hij hjhmhohhq}r (hu]hv]ht]hs]hw]uhyMWhzhhc]r (hX!Create a vertical mirror image - r r }r (hhX!Create a vertical mirror image - r hij ubh)r }r (hhX``t[]=transpose``r hq}r (hu]hv]ht]hs]hw]uhij hc]r hX t[]=transposer r }r (hhUhij ubahohubeubh)r }r (hhX)This transformation transposes the image.r hij hjhmhohhq}r (hu]hv]ht]hs]hw]uhyMYhzhhc]r hX)This transformation transposes the image.r r }r (hhj hij ubaubh)r }r (hhX **Examples:**r hij hjhmhohhq}r (hu]hv]ht]hs]hw]uhyM[hzhhc]r j!)r }r (hhj hq}r (hu]hv]ht]hs]hw]uhij hc]r hX Examples:r r }r (hhUhij ubahoj)ubaubj*)r }r (hhUhij hjhmhoj-hq}r (j/X*hs]ht]hu]hv]hw]uhyM]hzhhc]r j1)r }r (hhX``t[]=transpose`` hij hjhmhoj4hq}r (hu]hv]ht]hs]hw]uhyNhzhhc]r h)r }r (hhX``t[]=transpose``r hij hjhmhohhq}r (hu]hv]ht]hs]hw]uhyM]hc]r h)r }r (hhj hq}r (hu]hv]ht]hs]hw]uhij hc]r! hX t[]=transposer" r# }r$ (hhUhij ubahohubaubaubaubhe)r% }r& (hhX.. _transverse-transformation:hij hjhmhohphq}r' (hs]ht]hu]hv]hw]hxh^uhyM_hzhhc]ubeubh{)r( }r) (hhUhih|hjhmh~}r* h+j% shohhq}r+ (hu]hv]ht]hs]r, (hBh^ehw]r- (hh+euhyMbhzhh}r. h^j% shc]r/ (h)r0 }r1 (hhX5Create a horizontal mirror image - ``t[]=transverse``r2 hij( hjhmhohhq}r3 (hu]hv]ht]hs]hw]uhyMbhzhhc]r4 (hX#Create a horizontal mirror image - r5 r6 }r7 (hhX#Create a horizontal mirror image - r8 hij0 ubh)r9 }r: (hhX``t[]=transverse``r; hq}r< (hu]hv]ht]hs]hw]uhij0 hc]r= hXt[]=transverser> r? }r@ (hhUhij9 ubahohubeubh)rA }rB (hhX*This transformation transverses the image.rC hij( hjhmhohhq}rD (hu]hv]ht]hs]hw]uhyMdhzhhc]rE hX*This transformation transverses the image.rF rG }rH (hhjC hijA ubaubh)rI }rJ (hhX **Examples:**rK hij( hjhmhohhq}rL (hu]hv]ht]hs]hw]uhyMfhzhhc]rM j!)rN }rO (hhjK hq}rP (hu]hv]ht]hs]hw]uhijI hc]rQ hX Examples:rR rS }rT (hhUhijN ubahoj)ubaubj*)rU }rV (hhUhij( hjhmhoj-hq}rW (j/X*hs]ht]hu]hv]hw]uhyMhhzhhc]rX j1)rY }rZ (hhX``t[]=transverse`` hijU hjhmhoj4hq}r[ (hu]hv]ht]hs]hw]uhyNhzhhc]r\ h)r] }r^ (hhX``t[]=transverse``r_ hijY hjhmhohhq}r` (hu]hv]ht]hs]hw]uhyMhhc]ra h)rb }rc (hhj_ hq}rd (hu]hv]ht]hs]hw]uhij] hc]re hXt[]=transverserf rg }rh (hhUhijb ubahohubaubaubaubhe)ri }rj (hhX.. _watermark-transformation:hij( hjhmhohphq}rk (hs]ht]hu]hv]hw]hxhEuhyMjhzhhc]ubeubh{)rl }rm (hhUhih|hjhmh~}rn hji shohhq}ro (hu]hv]ht]hs]rp (hXhEehw]rq (h%heuhyMmhzhh}rr hEji shc]rs (h)rt }ru (hhX0Add a watermark to the image - ``t[]=watermark``rv hijl hjhmhohhq}rw (hu]hv]ht]hs]hw]uhyMmhzhhc]rx (hXAdd a watermark to the image - ry rz }r{ (hhXAdd a watermark to the image - r| hijt ubh)r} }r~ (hhX``t[]=watermark``r hq}r (hu]hv]ht]hs]hw]uhijt hc]r hX t[]=watermarkr r }r (hhUhij} ubahohubeubh)r }r (hhXRThis transformation can be used to apply a watermark on top of the original image.r hijl hjhmhohhq}r (hu]hv]ht]hs]hw]uhyMohzhhc]r hXRThis transformation can be used to apply a watermark on top of the original image.r r }r (hhj hij ubaubh)r }r (hhX**Parameters:**r hijl hjhmhohhq}r (hu]hv]ht]hs]hw]uhyMqhzhhc]r j!)r }r (hhj hq}r (hu]hv]ht]hs]hw]uhij hc]r hX Parameters:r r }r (hhUhij ubahoj)ubaubjs)r }r (hhUhijl hjhmhojvhq}r (hu]hv]ht]hs]hw]uhyNhzhhc]r (jy)r }r (hhX``img`` Image identifier of the image to apply as watermark. Can be set to a default value in configuration by using ````. hij hjhmhoj|hq}r (hu]hv]ht]hs]hw]uhyMthc]r (j)r }r (hhX``img``r hij hjhmhojhq}r (hu]hv]ht]hs]hw]uhyMthc]r h)r }r (hhj hq}r (hu]hv]ht]hs]hw]uhij hc]r hXimgr r }r (hhUhij ubahohubaubj)r }r (hhUhq}r (hu]hv]ht]hs]hw]uhij hc]r h)r }r (hhXImage identifier of the image to apply as watermark. Can be set to a default value in configuration by using ````.hij hjhmhohhq}r (hu]hv]ht]hs]hw]uhyMthc]r (hXmImage identifier of the image to apply as watermark. Can be set to a default value in configuration by using r r }r (hhXmImage identifier of the image to apply as watermark. Can be set to a default value in configuration by using hij ubh)r }r (hhX````hq}r (hu]hv]ht]hs]hw]uhij hc]r hXr r }r (hhUhij ubahohubhX.r }r (hhX.hij ubeubahojubeubjy)r }r (hhXb``width`` Width of the watermark image in pixels. If omitted the width of ```` will be used. hij hjhmhoj|hq}r (hu]hv]ht]hs]hw]uhyMwhzhhc]r (j)r }r (hhX ``width``r hij hjhmhojhq}r (hu]hv]ht]hs]hw]uhyMwhc]r h)r }r (hhj hq}r (hu]hv]ht]hs]hw]uhij hc]r hXwidthr r }r (hhUhij ubahohubaubj)r }r (hhUhq}r (hu]hv]ht]hs]hw]uhij hc]r h)r }r (hhXWWidth of the watermark image in pixels. If omitted the width of ```` will be used.hij hjhmhohhq}r (hu]hv]ht]hs]hw]uhyMwhc]r (hX@Width of the watermark image in pixels. If omitted the width of r r }r (hhX@Width of the watermark image in pixels. If omitted the width of hij ubh)r }r (hhX ````hq}r (hu]hv]ht]hs]hw]uhij hc]r hXr r }r (hhUhij ubahohubhX will be used.r r }r (hhX will be used.hij ubeubahojubeubjy)r }r (hhXe``height`` Height of the watermark image in pixels. If omitted the height of ```` will be used. hij hjhmhoj|hq}r (hu]hv]ht]hs]hw]uhyMzhzhhc]r (j)r }r (hhX ``height``r hij hjhmhojhq}r (hu]hv]ht]hs]hw]uhyMzhc]r h)r }r (hhj hq}r (hu]hv]ht]hs]hw]uhij hc]r hXheightr r }r (hhUhij ubahohubaubj)r }r (hhUhq}r (hu]hv]ht]hs]hw]uhij hc]r h)r }r (hhXYHeight of the watermark image in pixels. If omitted the height of ```` will be used.hij hjhmhohhq}r (hu]hv]ht]hs]hw]uhyMzhc]r (hXBHeight of the watermark image in pixels. If omitted the height of r r }r(hhXBHeight of the watermark image in pixels. If omitted the height of hij ubh)r}r(hhX ````hq}r(hu]hv]ht]hs]hw]uhij hc]rhXrr}r(hhUhijubahohubhX will be used.rr }r (hhX will be used.hij ubeubahojubeubjy)r }r (hhX``position`` The placement of the watermark image. ``top-left``, ``top-right``, ``bottom-left``, ``bottom-right`` and ``center`` are available values. Defaults to ``top-left``. hij hjhmhoj|hq}r (hu]hv]ht]hs]hw]uhyM}hzhhc]r(j)r}r(hhX ``position``rhij hjhmhojhq}r(hu]hv]ht]hs]hw]uhyM}hc]rh)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhXpositionrr}r(hhUhijubahohubaubj)r}r(hhUhq}r(hu]hv]ht]hs]hw]uhij hc]rh)r}r (hhXThe placement of the watermark image. ``top-left``, ``top-right``, ``bottom-left``, ``bottom-right`` and ``center`` are available values. Defaults to ``top-left``.hijhjhmhohhq}r!(hu]hv]ht]hs]hw]uhyM}hc]r"(hX&The placement of the watermark image. r#r$}r%(hhX&The placement of the watermark image. hijubh)r&}r'(hhX ``top-left``hq}r((hu]hv]ht]hs]hw]uhijhc]r)hXtop-leftr*r+}r,(hhUhij&ubahohubhX, r-r.}r/(hhX, hijubh)r0}r1(hhX ``top-right``hq}r2(hu]hv]ht]hs]hw]uhijhc]r3hX top-rightr4r5}r6(hhUhij0ubahohubhX, r7r8}r9(hhX, hijubh)r:}r;(hhX``bottom-left``hq}r<(hu]hv]ht]hs]hw]uhijhc]r=hX bottom-leftr>r?}r@(hhUhij:ubahohubhX, rArB}rC(hhX, hijubh)rD}rE(hhX``bottom-right``hq}rF(hu]hv]ht]hs]hw]uhijhc]rGhX bottom-rightrHrI}rJ(hhUhijDubahohubhX and rKrL}rM(hhX and hijubh)rN}rO(hhX ``center``hq}rP(hu]hv]ht]hs]hw]uhijhc]rQhXcenterrRrS}rT(hhUhijNubahohubhX# are available values. Defaults to rUrV}rW(hhX# are available values. Defaults to hijubh)rX}rY(hhX ``top-left``hq}rZ(hu]hv]ht]hs]hw]uhijhc]r[hXtop-leftr\r]}r^(hhUhijXubahohubhX.r_}r`(hhX.hijubeubahojubeubjy)ra}rb(hhX``x`` Number of pixels in the X-axis the watermark image should be offset from the original position (defined by the ``position`` parameter). Supports negative numbers. Defaults to ``0`` hij hjhmhoj|hq}rc(hu]hv]ht]hs]hw]uhyMhzhhc]rd(j)re}rf(hhX``x``rghijahjhmhojhq}rh(hu]hv]ht]hs]hw]uhyMhc]rih)rj}rk(hhjghq}rl(hu]hv]ht]hs]hw]uhijehc]rmhXxrn}ro(hhUhijjubahohubaubj)rp}rq(hhUhq}rr(hu]hv]ht]hs]hw]uhijahc]rsh)rt}ru(hhXNumber of pixels in the X-axis the watermark image should be offset from the original position (defined by the ``position`` parameter). Supports negative numbers. Defaults to ``0``hijphjhmhohhq}rv(hu]hv]ht]hs]hw]uhyMhc]rw(hXoNumber of pixels in the X-axis the watermark image should be offset from the original position (defined by the rxry}rz(hhXoNumber of pixels in the X-axis the watermark image should be offset from the original position (defined by the hijtubh)r{}r|(hhX ``position``hq}r}(hu]hv]ht]hs]hw]uhijthc]r~hXpositionrr}r(hhUhij{ubahohubhX4 parameter). Supports negative numbers. Defaults to rr}r(hhX4 parameter). Supports negative numbers. Defaults to hijtubh)r}r(hhX``0``hq}r(hu]hv]ht]hs]hw]uhijthc]rhX0r}r(hhUhijubahohubeubahojubeubjy)r}r(hhX``y`` Number of pixels in the Y-axis the watermark image should be offset from the original position (defined by the ``position`` parameter). Supports negative numbers. Defaults to ``0`` hij hjhmhoj|hq}r(hu]hv]ht]hs]hw]uhyMhzhhc]r(j)r}r(hhX``y``rhijhjhmhojhq}r(hu]hv]ht]hs]hw]uhyMhc]rh)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhXyr}r(hhUhijubahohubaubj)r}r(hhUhq}r(hu]hv]ht]hs]hw]uhijhc]rh)r}r(hhXNumber of pixels in the Y-axis the watermark image should be offset from the original position (defined by the ``position`` parameter). Supports negative numbers. Defaults to ``0``hijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyMhc]r(hXoNumber of pixels in the Y-axis the watermark image should be offset from the original position (defined by the rr}r(hhXoNumber of pixels in the Y-axis the watermark image should be offset from the original position (defined by the hijubh)r}r(hhX ``position``hq}r(hu]hv]ht]hs]hw]uhijhc]rhXpositionrr}r(hhUhijubahohubhX4 parameter). Supports negative numbers. Defaults to rr}r(hhX4 parameter). Supports negative numbers. Defaults to hijubh)r}r(hhX``0``hq}r(hu]hv]ht]hs]hw]uhijhc]rhX0r}r(hhUhijubahohubeubahojubeubeubh)r}r(hhX **Examples:**rhijl hjhmhohhq}r(hu]hv]ht]hs]hw]uhyMhzhhc]rj!)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhX Examples:rr}r(hhUhijubahoj)ubaubj*)r}r(hhUhijl hjhmhoj-hq}r(j/X*hs]ht]hu]hv]hw]uhyMhzhhc]r(j1)r}r(hhX6``t[]=watermark:img=f5f7851c40e2b76a01af9482f67bbf3f``rhijhjhmhoj4hq}r(hu]hv]ht]hs]hw]uhyNhzhhc]rh)r}r(hhjhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyMhc]rh)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhX2t[]=watermark:img=f5f7851c40e2b76a01af9482f67bbf3frr}r(hhUhijubahohubaubaubj1)r}r(hhXD``t[]=watermark:img=f5f7851c40e2b76a01af9482f67bbf3f,width=200,x=5``rhijhjhmhoj4hq}r(hu]hv]ht]hs]hw]uhyNhzhhc]rh)r}r(hhjhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyMhc]rh)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhX@t[]=watermark:img=f5f7851c40e2b76a01af9482f67bbf3f,width=200,x=5rr}r(hhUhijubahohubaubaubj1)r}r(hhXa``t[]=watermark:img=f5f7851c40e2b76a01af9482f67bbf3f,height=50,x=-5,y=-5,position=bottom-right`` hijhjhmhoj4hq}r(hu]hv]ht]hs]hw]uhyNhzhhc]rh)r}r(hhX```t[]=watermark:img=f5f7851c40e2b76a01af9482f67bbf3f,height=50,x=-5,y=-5,position=bottom-right``rhijhjhmhohhq}r(hu]hv]ht]hs]hw]uhyMhc]rh)r}r(hhjhq}r(hu]hv]ht]hs]hw]uhijhc]rhX\t[]=watermark:img=f5f7851c40e2b76a01af9482f67bbf3f,height=50,x=-5,y=-5,position=bottom-rightrr}r(hhUhijubahohubaubaubeubh)r}r(hhX[If you want to set the default watermark image you will have to do so in the configuration:rhijl hjhmhohhq}r(hu]hv]ht]hs]hw]uhyMhzhhc]rhX[If you want to set the default watermark image you will have to do so in the configuration:rr}r(hhjhijubaubcdocutils.nodes literal_block r)r}r(hhX8 array( 'watermark' => function() { $transformation = new Imbo\Image\Transformation\Watermark(); $transformation->setDefaultImage('some image identifier'); return $transformation; }, ), // ... );hijl hjhmhoU literal_blockrhq}r(UlinenosrUlanguagerXphpU xml:spacerUpreserverhs]ht]hu]hv]hw]uhyMhzhhc]rhX8 array( 'watermark' => function() { $transformation = new Imbo\Image\Transformation\Watermark(); $transformation->setDefaultImage('some image identifier'); return $transformation; }, ), // ... );rr}r (hhUhijubaubh)r }r (hhXWhen you have specified a default watermark image you are not required to use the ``img`` option for the transformation, but if you do so it will override the default one.r hijl hjhmhohhq}r (hu]hv]ht]hs]hw]uhyMhzhhc]r(hXRWhen you have specified a default watermark image you are not required to use the rr}r(hhXRWhen you have specified a default watermark image you are not required to use the hij ubh)r}r(hhX``img``hq}r(hu]hv]ht]hs]hw]uhij hc]rhXimgrr}r(hhUhijubahohubhXR option for the transformation, but if you do so it will override the default one.rr}r(hhXR option for the transformation, but if you do so it will override the default one.hij ubeubeubeubehhUU transformerrNU footnote_refsr}rUrefnamesr}r Usymbol_footnotesr!]r"Uautofootnote_refsr#]r$Usymbol_footnote_refsr%]r&U citationsr']r(hzhU current_liner)NUtransform_messagesr*]r+(cdocutils.nodes system_message r,)r-}r.(hhUhq}r/(hu]UlevelKhs]ht]Usourcehmhv]hw]UlineKUtypeUINFOr0uhc]r1h)r2}r3(hhUhq}r4(hu]hv]ht]hs]hw]uhij-hc]r5hX;Hyperlink target "image-transformations" is not referenced.r6r7}r8(hhUhij2ubahohubahoUsystem_messager9ubj,)r:}r;(hhUhq}r<(hu]UlevelKhs]ht]Usourcehmhv]hw]UlineK Utypej0uhc]r=h)r>}r?(hhUhq}r@(hu]hv]ht]hs]hw]uhij:hc]rAhX@Hyperlink target "auto-rotate-transformation" is not referenced.rBrC}rD(hhUhij>ubahohubahoj9ubj,)rE}rF(hhUhq}rG(hu]UlevelKhs]ht]Usourcehmhv]hw]UlineKUtypej0uhc]rHh)rI}rJ(hhUhq}rK(hu]hv]ht]hs]hw]uhijEhc]rLhX;Hyperlink target "border-transformation" is not referenced.rMrN}rO(hhUhijIubahohubahoj9ubj,)rP}rQ(hhUhq}rR(hu]UlevelKhs]ht]Usourcehmhv]hw]UlineK3Utypej0uhc]rSh)rT}rU(hhUhq}rV(hu]hv]ht]hs]hw]uhijPhc]rWhX;Hyperlink target "canvas-transformation" is not referenced.rXrY}rZ(hhUhijTubahohubahoj9ubj,)r[}r\(hhUhq}r](hu]UlevelKhs]ht]Usourcehmhv]hw]UlineKUUtypej0uhc]r^h)r_}r`(hhUhq}ra(hu]hv]ht]hs]hw]uhij[hc]rbhX=Hyperlink target "compress-transformation" is not referenced.rcrd}re(hhUhij_ubahohubahoj9ubj,)rf}rg(hhUhq}rh(hu]UlevelKhs]ht]Usourcehmhv]hw]UlineKeUtypej0uhc]rih)rj}rk(hhUhq}rl(hu]hv]ht]hs]hw]uhijfhc]rmhX<Hyperlink target "convert-transformation" is not referenced.rnro}rp(hhUhijjubahohubahoj9ubj,)rq}rr(hhUhq}rs(hu]UlevelKhs]ht]Usourcehmhv]hw]UlineKvUtypej0uhc]rth)ru}rv(hhUhq}rw(hu]hv]ht]hs]hw]uhijqhc]rxhX9Hyperlink target "crop-transformation" is not referenced.ryrz}r{(hhUhijuubahohubahoj9ubj,)r|}r}(hhUhq}r~(hu]UlevelKhs]ht]Usourcehmhv]hw]UlineKUtypej0uhc]rh)r}r(hhUhq}r(hu]hv]ht]hs]hw]uhij|hc]rhX?Hyperlink target "desaturate-transformation" is not referenced.rr}r(hhUhijubahohubahoj9ubj,)r}r(hhUhq}r(hu]UlevelKhs]ht]Usourcehmhv]hw]UlineKUtypej0uhc]rh)r}r(hhUhq}r(hu]hv]ht]hs]hw]uhijhc]rhXFHyperlink target "flip-horizontally-transformation" is not referenced.rr}r(hhUhijubahohubahoj9ubj,)r}r(hhUhq}r(hu]UlevelKhs]ht]Usourcehmhv]hw]UlineKUtypej0uhc]rh)r}r(hhUhq}r(hu]hv]ht]hs]hw]uhijhc]rhXDHyperlink target "flip-vertically-transformation" is not referenced.rr}r(hhUhijubahohubahoj9ubj,)r}r(hhUhq}r(hu]UlevelKhs]ht]Usourcehmhv]hw]UlineKUtypej0uhc]rh)r}r(hhUhq}r(hu]hv]ht]hs]hw]uhijhc]rhX=Hyperlink target "max-size-transformation" is not referenced.rr}r(hhUhijubahohubahoj9ubj,)r}r(hhUhq}r(hu]UlevelKhs]ht]Usourcehmhv]hw]UlineKUtypej0uhc]rh)r}r(hhUhq}r(hu]hv]ht]hs]hw]uhijhc]rhX=Hyperlink target "modulate-transformation" is not referenced.rr}r(hhUhijubahohubahoj9ubj,)r}r(hhUhq}r(hu]UlevelKhs]ht]Usourcehmhv]hw]UlineKUtypej0uhc]rh)r}r(hhUhq}r(hu]hv]ht]hs]hw]uhijhc]rhX@Hyperlink target "progressive-transformation" is not referenced.rr}r(hhUhijubahohubahoj9ubj,)r}r(hhUhq}r(hu]UlevelKhs]ht]Usourcehmhv]hw]UlineKUtypej0uhc]rh)r}r(hhUhq}r(hu]hv]ht]hs]hw]uhijhc]rhX;Hyperlink target "resize-transformation" is not referenced.rr}r(hhUhijubahohubahoj9ubj,)r}r(hhUhq}r(hu]UlevelKhs]ht]Usourcehmhv]hw]UlineM Utypej0uhc]rh)r}r(hhUhq}r(hu]hv]ht]hs]hw]uhijhc]rhX;Hyperlink target "rotate-transformation" is not referenced.rr}r(hhUhijubahohubahoj9ubj,)r}r(hhUhq}r(hu]UlevelKhs]ht]Usourcehmhv]hw]UlineM!Utypej0uhc]rh)r}r(hhUhq}r(hu]hv]ht]hs]hw]uhijhc]rhX:Hyperlink target "sepia-transformation" is not referenced.rr}r(hhUhijubahohubahoj9ubj,)r}r(hhUhq}r(hu]UlevelKhs]ht]Usourcehmhv]hw]UlineM2Utypej0uhc]rh)r}r(hhUhq}r(hu]hv]ht]hs]hw]uhijhc]rhX:Hyperlink target "strip-transformation" is not referenced.rr}r(hhUhijubahohubahoj9ubj,)r}r(hhUhq}r(hu]UlevelKhs]ht]Usourcehmhv]hw]UlineM=Utypej0uhc]rh)r}r(hhUhq}r(hu]hv]ht]hs]hw]uhijhc]rhX>Hyperlink target "thumbnail-transformation" is not referenced.rr}r(hhUhijubahohubahoj9ubj,)r}r(hhUhq}r(hu]UlevelKhs]ht]Usourcehmhv]hw]UlineMTUtypej0uhc]rh)r}r(hhUhq}r(hu]hv]ht]hs]hw]uhijhc]rhX>Hyperlink target "transpose-transformation" is not referenced.rr}r(hhUhijubahohubahoj9ubj,)r}r(hhUhq}r(hu]UlevelKhs]ht]Usourcehmhv]hw]UlineM_Utypej0uhc]rh)r}r(hhUhq}r(hu]hv]ht]hs]hw]uhijhc]rhX?Hyperlink target "transverse-transformation" is not referenced.rr }r (hhUhijubahohubahoj9ubj,)r }r (hhUhq}r (hu]UlevelKhs]ht]Usourcehmhv]hw]UlineMjUtypej0uhc]rh)r}r(hhUhq}r(hu]hv]ht]hs]hw]uhij hc]rhX>Hyperlink target "watermark-transformation" is not referenced.rr}r(hhUhijubahohubahoj9ubeUreporterrNUid_startrKU autofootnotesr]rU citation_refsr}rUindirect_targetsr]rUsettingsr(cdocutils.frontend Values ror }r!(Ufootnote_backlinksr"KUrecord_dependenciesr#NU rfc_base_urlr$Uhttp://tools.ietf.org/html/r%U tracebackr&Upep_referencesr'NUstrip_commentsr(NU toc_backlinksr)Uentryr*U language_coder+Uenr,U datestampr-NU report_levelr.KU _destinationr/NU halt_levelr0KU strip_classesr1NhNUerror_encoding_error_handlerr2Ubackslashreplacer3Udebugr4NUembed_stylesheetr5Uoutput_encoding_error_handlerr6Ustrictr7U sectnum_xformr8KUdump_transformsr9NU docinfo_xformr:KUwarning_streamr;NUpep_file_url_templater<Upep-%04dr=Uexit_status_levelr>KUconfigr?NUstrict_visitorr@NUcloak_email_addressesrAUtrim_footnote_reference_spacerBUenvrCNUdump_pseudo_xmlrDNUexpose_internalsrENUsectsubtitle_xformrFU source_linkrGNUrfc_referencesrHNUoutput_encodingrIUutf-8rJU source_urlrKNUinput_encodingrLU utf-8-sigrMU_disable_configrNNU id_prefixrOUU tab_widthrPKUerror_encodingrQUUTF-8rRU_sourcerSUP/var/build/user_builds/imbo/checkouts/1.1.1/docs/usage/image-transformations.rstrTUgettext_compactrUU generatorrVNUdump_internalsrWNU smart_quotesrXU pep_base_urlrYUhttp://www.python.org/dev/peps/rZUsyntax_highlightr[Ulongr\Uinput_encoding_error_handlerr]j7Uauto_id_prefixr^Uidr_Udoctitle_xformr`Ustrip_elements_with_classesraNU _config_filesrb]Ufile_insertion_enabledrcU raw_enabledrdKU dump_settingsreNubUsymbol_footnote_startrfKUidsrg}rh(h:j hjhOh|h@j hFjh\jt hDjFhAj)hSj hXjl hUj hWj hCj- hRjAh?jhGjAh9jhHj hIjhJj h`j hMjFhNjhajhPj hQjmh^j( hVjh=j hBj( hYhhZjmh[j- hLjhTjh]jhEjl hKjt h;hhbh|uUsubstitution_namesri}rjhohzhq}rk(hu]hs]ht]Usourcehmhv]hw]uU footnotesrl]rmUrefidsrn}ro(hH]rpj ahI]rqjahJ]rrj ahA]rsj&ahY]rthah^]ruj% ahN]rvjah<]rwjah:]rxj ahU]ryj ah\]rzjq ahP]r{j ah]]r|jahC]r}j* ahM]r~jCahE]rji ahQ]rjjahb]rhfah?]rjahG]rj>ahF]rjauub.PKsNDk3  &imbo-1.1.1/.doctrees/usage/api.doctreecdocutils.nodes document q)q}q(U nametypesq}q(Xstatus-resourceqXshorturl resource - /s/qNX imbo's apiqNXcustom statisticsq NXacceptq Xsupported content typesq NXregular expressionq Xpartially updating metadataq NXstats resource - /statsqNXfetch metadataqNX access-tokensqXcurlqXindex-resourceqXsha-256qXxmlqX cache headersqNXimage-resourceqXerrorsqNX http-dateqXstats-resourceqX-image resource - /users//images/qNXaccess controlqNX&hash-based message authentication codeqXjsonqXresources/endpointsqNX cache-controlqNX last-modifiedq NXjsonpq!X access tokensq"NX httpclientq#Xavailable resourcesq$NXmetadata-resourceq%Xunix timestampq&X9metadata resource - /users//images//metadataq'NXsigning-write-requestsq(X md5 checksumq)Xshorturl-resourceq*X add an imageq+NXuser resource - /users/q,NXdosq-Ximages-resourceq.X entity tagsq/Xsigning write requestsq0NXindex resource - /q1NXremove metadataq2NXetagq3NXadding/replacing metadataq4NX fetch imagesq5NXget image collectionsq6NX delete imagesq7NX&images resource - /users//imagesq8NXrequestsq9X user-resourceq:Xstatus resource - /statusq;NuUsubstitution_defsq<}q=Uparse_messagesq>]q?Ucurrent_sourceq@NU decorationqANUautofootnote_startqBKUnameidsqC}qD(hUstatus-resourceqEhUshorturl-resource-s-idqFhU imbo-s-apiqGh Ucustom-statisticsqHh UacceptqIh Usupported-content-typesqJh Uregular-expressionqKh Upartially-updating-metadataqLhUstats-resource-statsqMhUfetch-metadataqNhU access-tokensqOhUcurlqPhUindex-resourceqQhUsha-256qRhUxmlqShU cache-headersqThUimage-resourceqUhUerrorsqVhU http-dateqWhUstats-resourceqXhU&image-resource-users-user-images-imageqYhUaccess-controlqZhU&hash-based-message-authentication-codeq[hUjsonq\hUresources-endpointsq]hU cache-controlq^h U last-modifiedq_h!Ujsonpq`h"Uid2qah#U httpclientqbh$Uavailable-resourcesqch%Umetadata-resourceqdh&Uunix-timestampqeh'U2metadata-resource-users-user-images-image-metadataqfh(Usigning-write-requestsqgh)U md5-checksumqhh*Ushorturl-resourceqih+U add-an-imageqjh,Uuser-resource-users-userqkh-Udosqlh.Uimages-resourceqmh/U entity-tagsqnh0Uid3qoh1Uid1qph2Uremove-metadataqqh3Uetagqrh4Uadding-replacing-metadataqsh5U fetch-imagesqth6Uget-image-collectionsquh7U delete-imagesqvh8U!images-resource-users-user-imagesqwh9Urequestsqxh:U user-resourceqyh;Ustatus-resource-statusqzuUchildrenq{]q|cdocutils.nodes section q})q~}q(U rawsourceqUUparentqhUsourceqcdocutils.nodes reprunicode qX>/var/build/user_builds/imbo/checkouts/1.1.1/docs/usage/api.rstqq}qbUtagnameqUsectionqU attributesq}q(Udupnamesq]Uclassesq]Ubackrefsq]Uidsq]qhGaUnamesq]qhauUlineqKUdocumentqhh{]q(cdocutils.nodes title q)q}q(hX Imbo's APIqhh~hhhUtitleqh}q(h]h]h]h]h]uhKhhh{]qcdocutils.nodes Text qX Imbo's APIqq}q(hhhhubaubcdocutils.nodes paragraph q)q}q(hXIn this chapter you will learn more about how Imbo's API works, and how you as a user are able to read from and write to Imbo. Most examples listed in this chapter will use `cURL `_, so while playing around with the API it's encouraged to have cURL easily available. For the sake of simplicity the access tokens and authentication information is not used in the examples. See the :ref:`access-tokens` and :ref:`signing-write-requests` sections for more information regarding this.qhh~hhhU paragraphqh}q(h]h]h]h]h]uhKhhh{]q(hXIn this chapter you will learn more about how Imbo's API works, and how you as a user are able to read from and write to Imbo. Most examples listed in this chapter will use qq}q(hXIn this chapter you will learn more about how Imbo's API works, and how you as a user are able to read from and write to Imbo. Most examples listed in this chapter will use hhubcdocutils.nodes reference q)q}q(hX`cURL `_h}q(UnameXcURLUrefuriqXhttp://curl.haxx.se/qh]h]h]h]h]uhhh{]qhXcURLqq}q(hUhhubahU referencequbcdocutils.nodes target q)q}q(hX U referencedqKhhhUtargetqh}q(Urefurihh]qhPah]h]h]h]qhauh{]ubhX, so while playing around with the API it's encouraged to have cURL easily available. For the sake of simplicity the access tokens and authentication information is not used in the examples. See the qq}q(hX, so while playing around with the API it's encouraged to have cURL easily available. For the sake of simplicity the access tokens and authentication information is not used in the examples. See the hhubcsphinx.addnodes pending_xref q)q}q(hX:ref:`access-tokens`qhhhhhU pending_xrefqh}q(UreftypeXrefUrefwarnqƈU reftargetqX access-tokensU refdomainXstdqh]h]U refexplicith]h]h]UrefdocqX usage/apiquhKh{]qcdocutils.nodes emphasis q)q}q(hhh}q(h]h]q(UxrefqhXstd-refqeh]h]h]uhhh{]qhX access-tokensqԅq}q(hUhhubahUemphasisqubaubhX and q؅q}q(hX and hhubh)q}q(hX:ref:`signing-write-requests`qhhhhhhh}q(UreftypeXrefhƈhXsigning-write-requestsU refdomainXstdqh]h]U refexplicith]h]h]hhuhKh{]qh)q}q(hhh}q(h]h]q(hhXstd-refqeh]h]h]uhhh{]qhXsigning-write-requestsq煁q}q(hUhhubahhubaubhX. sections for more information regarding this.qꅁq}q(hX. sections for more information regarding this.hhubeubh})q}q(hUhh~hhhhh}q(h]h]h]h]qh]ah]qhauhKhhh{]q(h)q}q(hXResources/endpointsqhhhhhhh}q(h]h]h]h]h]uhKhhh{]qhXResources/endpointsqq}q(hhhhubaubh)q}q(hX~In this section you will find information on the different resources Imbo's RESTful API expose, along with their capabilities:qhhhhhhh}q(h]h]h]h]h]uhK hhh{]qhX~In this section you will find information on the different resources Imbo's RESTful API expose, along with their capabilities:rr}r(hhhhubaubcdocutils.nodes topic r)r}r(hUhhhhhUtopicrh}r(h]h]r(Ucontentsr Ulocalr eh]h]r hcah]r h$auhK hhh{]r (h)r}r(hXAvailable resourcesrh}r(h]h]h]h]h]uhjh{]rhXAvailable resourcesrr}r(hjhjubahhubcdocutils.nodes bullet_list r)r}r(hUhjhNhU bullet_listrh}r(h]h]h]h]h]uhNhhh{]r(cdocutils.nodes list_item r)r}r(hUh}r(h]h]h]h]h]uhjh{]r h)r!}r"(hUh}r#(h]h]h]h]h]uhjh{]r$h)r%}r&(hUh}r'(h]r(Uid4r)ah]h]h]h]UrefidhQuhj!h{]r*(hXIndex resource - r+r,}r-(hXIndex resource - r.hj%ubcdocutils.nodes literal r/)r0}r1(hX``/``r2h}r3(h]h]h]h]h]uhj%h{]r4hX/r5}r6(hUhj0ubahUliteralr7ubehhubahhubahU list_itemr8ubj)r9}r:(hUh}r;(h]h]h]h]h]uhjh{]r<h)r=}r>(hUh}r?(h]h]h]h]h]uhj9h{]r@h)rA}rB(hUh}rC(h]rDUid5rEah]h]h]h]UrefidhMuhj=h{]rF(hXStats resource - rGrH}rI(hXStats resource - rJhjAubj/)rK}rL(hX ``/stats``rMh}rN(h]h]h]h]h]uhjAh{]rOhX/statsrPrQ}rR(hUhjKubahj7ubehhubahhubahj8ubj)rS}rT(hUh}rU(h]h]h]h]h]uhjh{]rVh)rW}rX(hUh}rY(h]h]h]h]h]uhjSh{]rZh)r[}r\(hUh}r](h]r^Uid6r_ah]h]h]h]UrefidhzuhjWh{]r`(hXStatus resource - rarb}rc(hXStatus resource - rdhj[ubj/)re}rf(hX ``/status``rgh}rh(h]h]h]h]h]uhj[h{]rihX/statusrjrk}rl(hUhjeubahj7ubehhubahhubahj8ubj)rm}rn(hUh}ro(h]h]h]h]h]uhjh{]rph)rq}rr(hUh}rs(h]h]h]h]h]uhjmh{]rth)ru}rv(hUh}rw(h]rxUid7ryah]h]h]h]Urefidhkuhjqh{]rz(hXUser resource - r{r|}r}(hXUser resource - r~hjuubj/)r}r(hX``/users/``rh}r(h]h]h]h]h]uhjuh{]rhX /users/rr}r(hUhjubahj7ubehhubahhubahj8ubj)r}r(hUh}r(h]h]h]h]h]uhjh{]rh)r}r(hUh}r(h]h]h]h]h]uhjh{]rh)r}r(hUh}r(h]rUid8rah]h]h]h]Urefidhwuhjh{]r(hXImages resource - rr}r(hXImages resource - rhjubj/)r}r(hX``/users//images``rh}r(h]h]h]h]h]uhjh{]rhX/users//imagesrr}r(hUhjubahj7ubehhubahhubahj8ubj)r}r(hUh}r(h]h]h]h]h]uhjh{]rh)r}r(hUh}r(h]h]h]h]h]uhjh{]rh)r}r(hUh}r(h]rUid9rah]h]h]h]UrefidhYuhjh{]r(hXImage resource - rr}r(hXImage resource - rhjubj/)r}r(hX ``/users//images/``rh}r(h]h]h]h]h]uhjh{]rhX/users//images/rr}r(hUhjubahj7ubehhubahhubahj8ubj)r}r(hUh}r(h]h]h]h]h]uhjh{]rh)r}r(hUh}r(h]h]h]h]h]uhjh{]rh)r}r(hUh}r(h]rUid10rah]h]h]h]UrefidhFuhjh{]r(hXShortURL resource - rr}r(hXShortURL resource - rhjubj/)r}r(hX ``/s/``rh}r(h]h]h]h]h]uhjh{]rhX/s/rr}r(hUhjubahj7ubehhubahhubahj8ubj)r}r(hUh}r(h]h]h]h]h]uhjh{]rh)r}r(hUh}r(h]h]h]h]h]uhjh{]rh)r}r(hUh}r(h]rUid11rah]h]h]h]Urefidhfuhjh{]r(hXMetadata resource - rr}r(hXMetadata resource - rhjubj/)r}r(hX)``/users//images//metadata``rh}r(h]h]h]h]h]uhjh{]rhX%/users//images//metadatarr}r(hUhjubahj7ubehhubahhubahj8ubeubeubh)r}r(hX.. _index-resource:hhhhhhh}r(h]h]h]h]h]UrefidrhQuhKhhh{]ubh})r}r(hUhhhhUexpect_referenced_by_namer}rhjshhh}r(h]h]h]h]r(hQhpeh]r(h1heuhKhhUexpect_referenced_by_idr}rhQjsh{]r(h)r}r(hXIndex resource - ``/``rhjhhhhh}r(h]h]h]h]h]jj)uhKhhh{]r(hXIndex resource - rr}r(hj.hjubj/)r}r(hj2h}r(h]h]h]h]h]uhjh{]rhX/r }r (hUhjubahj7ubeubh)r }r (hXThe index resource shows the version of the Imbo installation along with some external URL's for Imbo-related information, and some internal URL's for the available endpoints.r hjhhhhh}r(h]h]h]h]h]uhKhhh{]rhXThe index resource shows the version of the Imbo installation along with some external URL's for Imbo-related information, and some internal URL's for the available endpoints.rr}r(hj hj ubaubcdocutils.nodes literal_block r)r}r(hX-curl -H"Accept: application/json" http://imbohjhhhU literal_blockrh}r(UlinenosrUlanguagerXbashU xml:spacerUpreserverh]h]h]h]h]uhKhhh{]rhX-curl -H"Accept: application/json" http://imborr}r(hUhjubaubh)r }r!(hX results in:r"hjhhhhh}r#(h]h]h]h]h]uhKhhh{]r$hX results in:r%r&}r'(hj"hj ubaubj)r(}r)(hXc{ "version": "dev", "urls": { "site": "http://www.imbo-project.org", "source": "https://github.com/imbo/imbo", "issues": "https://github.com/imbo/imbo/issues", "docs": "http://docs.imbo-project.org" }, "endpoints": { "status": "http://imbo/status", "stats": "http://imbo/stats", "user": "http://imbo/users/{publicKey}", "images": "http://imbo/users/{publicKey}/images", "image": "http://imbo/users/{publicKey}/images/{imageIdentifier}", "shortImageUrl": "http://imbo/s/{id}", "metadata": "http://imbo/users/{publicKey}/images/{imageIdentifier}/metadata" } }hjhhhjh}r*(jjX javascriptjjh]h]h]h]h]uhKhhh{]r+hXc{ "version": "dev", "urls": { "site": "http://www.imbo-project.org", "source": "https://github.com/imbo/imbo", "issues": "https://github.com/imbo/imbo/issues", "docs": "http://docs.imbo-project.org" }, "endpoints": { "status": "http://imbo/status", "stats": "http://imbo/stats", "user": "http://imbo/users/{publicKey}", "images": "http://imbo/users/{publicKey}/images", "image": "http://imbo/users/{publicKey}/images/{imageIdentifier}", "shortImageUrl": "http://imbo/s/{id}", "metadata": "http://imbo/users/{publicKey}/images/{imageIdentifier}/metadata" } }r,r-}r.(hUhj(ubaubh)r/}r0(hXThis resource does not support any extensions in the URI, so you will need to use the ``Accept`` header to fetch different representations of the data.r1hjhhhhh}r2(h]h]h]h]h]uhK1hhh{]r3(hXVThis resource does not support any extensions in the URI, so you will need to use the r4r5}r6(hXVThis resource does not support any extensions in the URI, so you will need to use the hj/ubj/)r7}r8(hX ``Accept``h}r9(h]h]h]h]h]uhj/h{]r:hXAcceptr;r<}r=(hUhj7ubahj7ubhX7 header to fetch different representations of the data.r>r?}r@(hX7 header to fetch different representations of the data.hj/ubeubh)rA}rB(hXCThe index resource does not require any authentication per default.rChjhhhhh}rD(h]h]h]h]h]uhK3hhh{]rEhXCThe index resource does not require any authentication per default.rFrG}rH(hjChjAubaubh)rI}rJ(hX**Typical response codes:**rKhjhhhhh}rL(h]h]h]h]h]uhK5hhh{]rMcdocutils.nodes strong rN)rO}rP(hjKh}rQ(h]h]h]h]h]uhjIh{]rRhXTypical response codes:rSrT}rU(hUhjOubahUstrongrVubaubj)rW}rX(hUhjhhhjh}rY(UbulletrZX*h]h]h]h]h]uhK7hhh{]r[j)r\}r](hX200 Hell Yeah hjWhhhj8h}r^(h]h]h]h]h]uhNhhh{]r_h)r`}ra(hX 200 Hell Yeahrbhj\hhhhh}rc(h]h]h]h]h]uhK7h{]rdhX 200 Hell Yeahrerf}rg(hjbhj`ubaubaubaubcdocutils.nodes note rh)ri}rj(hX%The index resource is not cache-able.rkhjhhhUnoterlh}rm(h]h]h]h]h]uhNhhh{]rnh)ro}rp(hjkhjihhhhh}rq(h]h]h]h]h]uhK9h{]rrhX%The index resource is not cache-able.rsrt}ru(hjkhjoubaubaubh)rv}rw(hX.. _stats-resource:hjhhhhh}rx(h]h]h]h]h]jhXuhK;hhh{]ubeubh})ry}rz(hUhhhhj}r{hjvshhh}r|(h]h]h]h]r}(hMhXeh]r~(hheuhK>hhj}rhXjvsh{]r(h)r}r(hXStats resource - ``/stats``rhjyhhhhh}r(h]h]h]h]h]jjEuhK>hhh{]r(hXStats resource - rr}r(hjJhjubj/)r}r(hjMh}r(h]h]h]h]h]uhjh{]rhX/statsrr}r(hUhjubahj7ubeubh)r}r(hXWImbo provides an endpoint for fetching simple statistics about the data stored in Imbo.rhjyhhhhh}r(h]h]h]h]h]uhK@hhh{]rhXWImbo provides an endpoint for fetching simple statistics about the data stored in Imbo.rr}r(hjhjubaubj)r}r(hXcurl http://imbo/stats.jsonhjyhhhjh}r(jjXbashjjh]h]h]h]h]uhKBhhh{]rhXcurl http://imbo/stats.jsonrr}r(hUhjubaubh)r}r(hX results in:rhjyhhhhh}r(h]h]h]h]h]uhKFhhh{]rhX results in:rr}r(hjhjubaubj)r}r(hX { "users": { "someuser": { "numImages": 11, "numBytes": 3817197 }, "someotheruser": { "numImages": 1, "numBytes": 81097 } }, "total": { "numImages": 12, "numUsers": 2, "numBytes": 3898294 }, "custom": {} }hjyhhhjh}r(jjX javascriptjjh]h]h]h]h]uhKHhhh{]rhX { "users": { "someuser": { "numImages": 11, "numBytes": 3817197 }, "someotheruser": { "numImages": 1, "numBytes": 81097 } }, "total": { "numImages": 12, "numUsers": 2, "numBytes": 3898294 }, "custom": {} }rr}r(hUhjubaubh)r}r(hX3if the client making the request is allowed access.rhjyhhhhh}r(h]h]h]h]h]uhK]hhh{]rhX3if the client making the request is allowed access.rr}r(hjhjubaubh})r}r(hUhjyhhhhh}r(h]h]h]h]rhZah]rhauhK`hhh{]r(h)r}r(hXAccess controlrhjhhhhh}r(h]h]h]h]h]uhK`hhh{]rhXAccess controlrr}r(hjhjubaubh)r}r(hX;The access control for the stats endpoint is controlled by an event listener, which is enabled per default, and only allows connections from ``127.0.0.1`` (IPv4) and ``::1`` (IPv6). Read more about how to configure this event listener in the :ref:`Stats access event listener ` section.rhjhhhhh}r(h]h]h]h]h]uhKbhhh{]r(hXThe access control for the stats endpoint is controlled by an event listener, which is enabled per default, and only allows connections from rr}r(hXThe access control for the stats endpoint is controlled by an event listener, which is enabled per default, and only allows connections from hjubj/)r}r(hX ``127.0.0.1``h}r(h]h]h]h]h]uhjh{]rhX 127.0.0.1rr}r(hUhjubahj7ubhX (IPv4) and rr}r(hX (IPv4) and hjubj/)r}r(hX``::1``h}r(h]h]h]h]h]uhjh{]rhX::1rr}r(hUhjubahj7ubhXE (IPv6). Read more about how to configure this event listener in the rr}r(hXE (IPv6). Read more about how to configure this event listener in the hjubh)r}r(hX@:ref:`Stats access event listener `rhjhhhhh}r(UreftypeXrefhƈhXstats-access-event-listenerU refdomainXstdrh]h]U refexplicith]h]h]hhuhKbh{]rh)r}r(hjh}r(h]h]r(hjXstd-refreh]h]h]uhjh{]rhXStats access event listenerrr}r(hUhjubahhubaubhX section.rr}r(hX section.hjubeubeubh})r}r(hUhjyhhhhh}r(h]h]h]h]rhHah]rh auhKehhh{]r(h)r}r(hXCustom statisticsrhjhhhhh}r(h]h]h]h]h]uhKehhh{]rhXCustom statisticsrr}r(hjhjubaubh)r}r(hXThe stats resource enables users to attach custom statistics via event listeners by using the data model as a regular associative array. The following example attaches a simple event listener in the configuration file that populates some custom data in the statistics model:rhjhhhhh}r(h]h]h]h]h]uhKghhh{]rhXThe stats resource enables users to attach custom statistics via event listeners by using the data model as a regular associative array. The following example attaches a simple event listener in the configuration file that populates some custom data in the statistics model:rr}r(hjhjubaubj)r}r (hXD array( 'customStats' => array( 'events' => array('stats.get'), 'callback' => function($event) { // Fetch the model from the response $model = $event->getResponse()->getModel(); // Set some values $model['someValue'] = 123; $model['someOtherValue'] = array( 'foo' => 'bar', ); $model['someList'] = array(1, 2, 3); } ), ), // ... );hjhhhjh}r (jjXphpjjh]h]h]h]h]uhKihhh{]r hXD array( 'customStats' => array( 'events' => array('stats.get'), 'callback' => function($event) { // Fetch the model from the response $model = $event->getResponse()->getModel(); // Set some values $model['someValue'] = 123; $model['someOtherValue'] = array( 'foo' => 'bar', ); $model['someList'] = array(1, 2, 3); } ), ), // ... );r r }r(hUhjubaubh)r}r(hXCWhen requesting the stats endpoint, the output will look like this:rhjhhhhh}r(h]h]h]h]h]uhKhhh{]rhXCWhen requesting the stats endpoint, the output will look like this:rr}r(hjhjubaubj)r}r(hXp{ "users": { "someuser": { "numImages": 11, "numBytes": 3817197 }, "someotheruser": { "numImages": 1, "numBytes": 81097 } }, "total": { "numImages": 12, "numUsers": 2, "numBytes": 3898294 }, "custom": { "someValue": 123, "someOtherValue": { "foo": "bar" }, "someList": [1, 2, 3] } }hjhhhjh}r(jjX javascriptjjh]h]h]h]h]uhKhhh{]rhXp{ "users": { "someuser": { "numImages": 11, "numBytes": 3817197 }, "someotheruser": { "numImages": 1, "numBytes": 81097 } }, "total": { "numImages": 12, "numUsers": 2, "numBytes": 3898294 }, "custom": { "someValue": 123, "someOtherValue": { "foo": "bar" }, "someList": [1, 2, 3] } }rr}r(hUhjubaubh)r}r(hXUse cases for this might be to simply store data in some backend in various events (for instance ``image.get`` or ``metadata.get``) and then fetch these and display then when requesting the stats endpoint (``stats.get``).r hjhhhhh}r!(h]h]h]h]h]uhKhhh{]r"(hXaUse cases for this might be to simply store data in some backend in various events (for instance r#r$}r%(hXaUse cases for this might be to simply store data in some backend in various events (for instance hjubj/)r&}r'(hX ``image.get``h}r((h]h]h]h]h]uhjh{]r)hX image.getr*r+}r,(hUhj&ubahj7ubhX or r-r.}r/(hX or hjubj/)r0}r1(hX``metadata.get``h}r2(h]h]h]h]h]uhjh{]r3hX metadata.getr4r5}r6(hUhj0ubahj7ubhXL) and then fetch these and display then when requesting the stats endpoint (r7r8}r9(hXL) and then fetch these and display then when requesting the stats endpoint (hjubj/)r:}r;(hX ``stats.get``h}r<(h]h]h]h]h]uhjh{]r=hX stats.getr>r?}r@(hUhj:ubahj7ubhX).rArB}rC(hX).hjubeubjh)rD}rE(hX%The stats resource is not cache-able.rFhjhhhjlh}rG(h]h]h]h]h]uhNhhh{]rHh)rI}rJ(hjFhjDhhhhh}rK(h]h]h]h]h]uhKh{]rLhX%The stats resource is not cache-able.rMrN}rO(hjFhjIubaubaubh)rP}rQ(hX.. _status-resource:hjhhhhh}rR(h]h]h]h]h]jhEuhKhhh{]ubeubeubh})rS}rT(hUhhhhj}rUhjPshhh}rV(h]h]h]h]rW(hzhEeh]rX(h;heuhKhhj}rYhEjPsh{]rZ(h)r[}r\(hXStatus resource - ``/status``r]hjShhhhh}r^(h]h]h]h]h]jj_uhKhhh{]r_(hXStatus resource - r`ra}rb(hjdhj[ubj/)rc}rd(hjgh}re(h]h]h]h]h]uhj[h{]rfhX/statusrgrh}ri(hUhjcubahj7ubeubh)rj}rk(hX^Imbo includes a simple status resource that can be used with for instance monitoring software.rlhjShhhhh}rm(h]h]h]h]h]uhKhhh{]rnhX^Imbo includes a simple status resource that can be used with for instance monitoring software.rorp}rq(hjlhjjubaubj)rr}rs(hXcurl http://imbo/status.jsonhjShhhjh}rt(jjXbashjjh]h]h]h]h]uhKhhh{]ruhXcurl http://imbo/status.jsonrvrw}rx(hUhjrubaubh)ry}rz(hX results in:r{hjShhhhh}r|(h]h]h]h]h]uhKhhh{]r}hX results in:r~r}r(hj{hjyubaubj)r}r(hXY{ "timestamp": "Tue, 24 Apr 2012 14:12:58 GMT", "database": true, "storage": true }hjShhhjh}r(jjX javascriptjjh]h]h]h]h]uhKhhh{]rhXY{ "timestamp": "Tue, 24 Apr 2012 14:12:58 GMT", "database": true, "storage": true }rr}r(hUhjubaubh)r}r(hX$where ``timestamp`` is the current timestamp on the server, and ``database`` and ``storage`` are boolean values informing of the status of the current database and storage adapters respectively. If both are ``true`` the HTTP status code is ``200 OK``, and if one or both are ``false`` the status code is ``503``. When the status code is ``503`` the reason phrase will inform you whether it's the database or the storage adapter (or both) that is having issues. As soon as the status code does not equal ``200`` Imbo will no longer work as expected.rhjShhhhh}r(h]h]h]h]h]uhKhhh{]r(hXwhere rr}r(hXwhere hjubj/)r}r(hX ``timestamp``h}r(h]h]h]h]h]uhjh{]rhX timestamprr}r(hUhjubahj7ubhX- is the current timestamp on the server, and rr}r(hX- is the current timestamp on the server, and hjubj/)r}r(hX ``database``h}r(h]h]h]h]h]uhjh{]rhXdatabaserr}r(hUhjubahj7ubhX and rr}r(hX and hjubj/)r}r(hX ``storage``h}r(h]h]h]h]h]uhjh{]rhXstoragerr}r(hUhjubahj7ubhXs are boolean values informing of the status of the current database and storage adapters respectively. If both are rr}r(hXs are boolean values informing of the status of the current database and storage adapters respectively. If both are hjubj/)r}r(hX``true``h}r(h]h]h]h]h]uhjh{]rhXtruerr}r(hUhjubahj7ubhX the HTTP status code is rr}r(hX the HTTP status code is hjubj/)r}r(hX ``200 OK``h}r(h]h]h]h]h]uhjh{]rhX200 OKrr}r(hUhjubahj7ubhX, and if one or both are rr}r(hX, and if one or both are hjubj/)r}r(hX ``false``h}r(h]h]h]h]h]uhjh{]rhXfalserr}r(hUhjubahj7ubhX the status code is rr}r(hX the status code is hjubj/)r}r(hX``503``h}r(h]h]h]h]h]uhjh{]rhX503rr}r(hUhjubahj7ubhX. When the status code is rr}r(hX. When the status code is hjubj/)r}r(hX``503``h}r(h]h]h]h]h]uhjh{]rhX503rr}r(hUhjubahj7ubhX the reason phrase will inform you whether it's the database or the storage adapter (or both) that is having issues. As soon as the status code does not equal rr}r(hX the reason phrase will inform you whether it's the database or the storage adapter (or both) that is having issues. As soon as the status code does not equal hjubj/)r}r(hX``200``h}r(h]h]h]h]h]uhjh{]rhX200rr}r(hUhjubahj7ubhX& Imbo will no longer work as expected.rr}r(hX& Imbo will no longer work as expected.hjubeubh)r}r(hXThe reason for adapter failures depends on what kind of adapter you are using. The :ref:`file system storage adapter ` will for instance return a failure if it can no longer write to the storage directory. The :ref:`MongoDB ` and :ref:`Doctrine ` database adapters will fail if they can no longer connect to the server they are configured to communicate with.rhjShhhhh}r(h]h]h]h]h]uhKhhh{]r(hXSThe reason for adapter failures depends on what kind of adapter you are using. The rr}r(hXSThe reason for adapter failures depends on what kind of adapter you are using. The hjubh)r}r(hX?:ref:`file system storage adapter `rhjhhhhh}r(UreftypeXrefhƈhXfilesystem-storage-adapterU refdomainXstdrh]h]U refexplicith]h]h]hhuhKh{]rh)r}r(hjh}r(h]h]r(hjXstd-refreh]h]h]uhjh{]rhXfile system storage adapterrr}r(hUhjubahhubaubhX\ will for instance return a failure if it can no longer write to the storage directory. The rr}r(hX\ will for instance return a failure if it can no longer write to the storage directory. The hjubh)r}r(hX):ref:`MongoDB `rhjhhhhh}r(UreftypeXrefhƈhXmongodb-database-adapterU refdomainXstdrh]h]U refexplicith]h]h]hhuhKh{]r h)r }r (hjh}r (h]h]r (hjXstd-refreh]h]h]uhjh{]rhXMongoDBrr}r(hUhj ubahhubaubhX and rr}r(hX and hjubh)r}r(hX+:ref:`Doctrine `rhjhhhhh}r(UreftypeXrefhƈhXdoctrine-database-adapterU refdomainXstdrh]h]U refexplicith]h]h]hhuhKh{]rh)r}r(hjh}r(h]h]r(hjXstd-refr eh]h]h]uhjh{]r!hXDoctriner"r#}r$(hUhjubahhubaubhXq database adapters will fail if they can no longer connect to the server they are configured to communicate with.r%r&}r'(hXq database adapters will fail if they can no longer connect to the server they are configured to communicate with.hjubeubh)r(}r)(hX**Typical response codes:**r*hjShhhhh}r+(h]h]h]h]h]uhKhhh{]r,jN)r-}r.(hj*h}r/(h]h]h]h]h]uhj(h{]r0hXTypical response codes:r1r2}r3(hUhj-ubahjVubaubj)r4}r5(hUhjShhhjh}r6(jZX*h]h]h]h]h]uhKhhh{]r7(j)r8}r9(hX200 OKr:hj4hhhj8h}r;(h]h]h]h]h]uhNhhh{]r<h)r=}r>(hj:hj8hhhhh}r?(h]h]h]h]h]uhKh{]r@hX200 OKrArB}rC(hj:hj=ubaubaubj)rD}rE(hX503 Database errorrFhj4hhhj8h}rG(h]h]h]h]h]uhNhhh{]rHh)rI}rJ(hjFhjDhhhhh}rK(h]h]h]h]h]uhKh{]rLhX503 Database errorrMrN}rO(hjFhjIubaubaubj)rP}rQ(hX503 Storage errorrRhj4hhhj8h}rS(h]h]h]h]h]uhNhhh{]rTh)rU}rV(hjRhjPhhhhh}rW(h]h]h]h]h]uhKh{]rXhX503 Storage errorrYrZ}r[(hjRhjUubaubaubj)r\}r](hX503 Storage and database error hj4hhhj8h}r^(h]h]h]h]h]uhNhhh{]r_h)r`}ra(hX503 Storage and database errorrbhj\hhhhh}rc(h]h]h]h]h]uhKh{]rdhX503 Storage and database errorrerf}rg(hjbhj`ubaubaubeubjh)rh}ri(hX&The status resource is not cache-able.rjhjShhhjlh}rk(h]h]h]h]h]uhNhhh{]rlh)rm}rn(hjjhjhhhhhh}ro(h]h]h]h]h]uhKh{]rphX&The status resource is not cache-able.rqrr}rs(hjjhjmubaubaubh)rt}ru(hX.. _user-resource:hjShhhhh}rv(h]h]h]h]h]jhyuhKhhh{]ubeubh})rw}rx(hUhhhhj}ryh:jtshhh}rz(h]h]h]h]r{(hkhyeh]r|(h,h:euhKhhj}r}hyjtsh{]r~(h)r}r(hX!User resource - ``/users/``rhjwhhhhh}r(h]h]h]h]h]jjyuhKhhh{]r(hXUser resource - rr}r(hj~hjubj/)r}r(hjh}r(h]h]h]h]h]uhjh{]rhX /users/rr}r(hUhjubahj7ubeubh)r}r(hXxThe user resource represents a single user on the current Imbo installation. The output contains basic user information:rhjwhhhhh}r(h]h]h]h]h]uhKhhh{]rhXxThe user resource represents a single user on the current Imbo installation. The output contains basic user information:rr}r(hjhjubaubj)r}r(hX"curl http://imbo/users/.jsonhjwhhhjh}r(jjXbashjjh]h]h]h]h]uhKhhh{]rhX"curl http://imbo/users/.jsonrr}r(hUhjubaubh)r}r(hX results in:rhjwhhhhh}r(h]h]h]h]h]uhKhhh{]rhX results in:rr}r(hjhjubaubj)r}r(hXa{ "publicKey": "", "numImages": 42, "lastModified": "Wed, 18 Apr 2012 15:12:52 GMT" }hjwhhhjh}r(jjX javascriptjjh]h]h]h]h]uhKhhh{]rhXa{ "publicKey": "", "numImages": 42, "lastModified": "Wed, 18 Apr 2012 15:12:52 GMT" }rr}r(hUhjubaubh)r}r(hXwhere ``publicKey`` is the public key of the user (the same used in the URI of the request), ``numImages`` is the number of images the user has stored in Imbo and ``lastModified`` is when the user last uploaded or deleted an image, or when the user last updated metadata of an image. If the user has not added any images yet, the ``lastModified`` value will be set to the current time on the server.rhjwhhhhh}r(h]h]h]h]h]uhKhhh{]r(hXwhere rr}r(hXwhere hjubj/)r}r(hX ``publicKey``h}r(h]h]h]h]h]uhjh{]rhX publicKeyrr}r(hUhjubahj7ubhXJ is the public key of the user (the same used in the URI of the request), rr}r(hXJ is the public key of the user (the same used in the URI of the request), hjubj/)r}r(hX ``numImages``h}r(h]h]h]h]h]uhjh{]rhX numImagesrr}r(hUhjubahj7ubhX9 is the number of images the user has stored in Imbo and rr}r(hX9 is the number of images the user has stored in Imbo and hjubj/)r}r(hX``lastModified``h}r(h]h]h]h]h]uhjh{]rhX lastModifiedrr}r(hUhjubahj7ubhX is when the user last uploaded or deleted an image, or when the user last updated metadata of an image. If the user has not added any images yet, the rr}r(hX is when the user last uploaded or deleted an image, or when the user last updated metadata of an image. If the user has not added any images yet, the hjubj/)r}r(hX``lastModified``h}r(h]h]h]h]h]uhjh{]rhX lastModifiedrr}r(hUhjubahj7ubhX5 value will be set to the current time on the server.rr}r(hX5 value will be set to the current time on the server.hjubeubh)r}r(hX**Typical response codes:**rhjwhhhhh}r(h]h]h]h]h]uhKhhh{]rjN)r}r(hjh}r(h]h]h]h]h]uhjh{]rhXTypical response codes:rr}r(hUhjubahjVubaubj)r}r(hUhjwhhhjh}r(jZX*h]h]h]h]h]uhKhhh{]r(j)r}r(hX200 OKrhjhhhj8h}r(h]h]h]h]h]uhNhhh{]rh)r}r(hjhjhhhhh}r(h]h]h]h]h]uhKh{]rhX200 OKrr}r(hjhjubaubaubj)r}r(hX304 Not modifiedrhjhhhj8h}r(h]h]h]h]h]uhNhhh{]rh)r}r(hjhjhhhhh}r(h]h]h]h]h]uhKh{]rhX304 Not modifiedrr}r(hjhjubaubaubj)r}r(hX404 Public key not found hjhhhj8h}r(h]h]h]h]h]uhNhhh{]rh)r}r (hX404 Public key not foundr hjhhhhh}r (h]h]h]h]h]uhKh{]r hX404 Public key not foundr r}r(hj hjubaubaubeubh)r}r(hX.. _images-resource:hjwhhhhh}r(h]h]h]h]h]jhmuhKhhh{]ubeubh})r}r(hUhhhhj}rh.jshhh}r(h]h]h]h]r(hwhmeh]r(h8h.euhKhhj}rhmjsh{]r(h)r}r(hX*Images resource - ``/users//images``rhjhhhhh}r(h]h]h]h]h]jjuhKhhh{]r(hXImages resource - r r!}r"(hjhjubj/)r#}r$(hjh}r%(h]h]h]h]h]uhjh{]r&hX/users//imagesr'r(}r)(hUhj#ubahj7ubeubh)r*}r+(hXThe images resource is the collection of images owned by a specific user. This resource can be used to search added images, and is also used to add new images to a collection.r,hjhhhhh}r-(h]h]h]h]h]uhKhhh{]r.hXThe images resource is the collection of images owned by a specific user. This resource can be used to search added images, and is also used to add new images to a collection.r/r0}r1(hj,hj*ubaubh})r2}r3(hUhjhhhhh}r4(h]h]h]h]r5hjah]r6h+auhKhhh{]r7(h)r8}r9(hX Add an imager:hj2hhhhh}r;(h]h]h]h]h]uhKhhh{]r<hX Add an imager=r>}r?(hj:hj8ubaubh)r@}rA(hXPTo be able to display images stored in Imbo you will first need to add one or more images. This is done by requesting this endpoint with an image attached to the request body, and changing the HTTP METHOD to ``POST``. The body of the response for such a request contains a JSON object containing the image identifier of the added image:rBhj2hhhhh}rC(h]h]h]h]h]uhKhhh{]rD(hXTo be able to display images stored in Imbo you will first need to add one or more images. This is done by requesting this endpoint with an image attached to the request body, and changing the HTTP METHOD to rErF}rG(hXTo be able to display images stored in Imbo you will first need to add one or more images. This is done by requesting this endpoint with an image attached to the request body, and changing the HTTP METHOD to hj@ubj/)rH}rI(hX``POST``h}rJ(h]h]h]h]h]uhj@h{]rKhXPOSTrLrM}rN(hUhjHubahj7ubhXx. The body of the response for such a request contains a JSON object containing the image identifier of the added image:rOrP}rQ(hXx. The body of the response for such a request contains a JSON object containing the image identifier of the added image:hj@ubeubj)rR}rS(hXHcurl -XPOST http://imbo/users//images --data-binary @hj2hhhjh}rT(jjXbashjjh]h]h]h]h]uhKhhh{]rUhXHcurl -XPOST http://imbo/users//images --data-binary @rVrW}rX(hUhjRubaubh)rY}rZ(hX results in:r[hj2hhhhh}r\(h]h]h]h]h]uhKhhh{]r]hX results in:r^r_}r`(hj[hjYubaubj)ra}rb(hXt{ "imageIdentifier": "", "width": , "height": , "extension": "" }hj2hhhjh}rc(jjX javascriptjjh]h]h]h]h]uhKhhh{]rdhXt{ "imageIdentifier": "", "width": , "height": , "extension": "" }rerf}rg(hUhjaubaubh)rh}ri(hXThe ```` in the response is the identifier of the added image. This is used with the `image resource<>`. The response body also contains the ``width``, ``height`` and ``extension`` of the image that was just added.rjhj2hhhhh}rk(h]h]h]h]h]uhKhhh{]rl(hXThe rmrn}ro(hXThe hjhubj/)rp}rq(hX````h}rr(h]h]h]h]h]uhjhh{]rshXrtru}rv(hUhjpubahj7ubhXM in the response is the identifier of the added image. This is used with the rwrx}ry(hXM in the response is the identifier of the added image. This is used with the hjhubcdocutils.nodes title_reference rz)r{}r|(hX`image resource<>`h}r}(h]h]h]h]h]uhjhh{]r~hXimage resource<>rr}r(hUhj{ubahUtitle_referencerubhX&. The response body also contains the rr}r(hX&. The response body also contains the hjhubj/)r}r(hX ``width``h}r(h]h]h]h]h]uhjhh{]rhXwidthrr}r(hUhjubahj7ubhX, rr}r(hX, hjhubj/)r}r(hX ``height``h}r(h]h]h]h]h]uhjhh{]rhXheightrr}r(hUhjubahj7ubhX and rr}r(hX and hjhubj/)r}r(hX ``extension``h}r(h]h]h]h]h]uhjhh{]rhX extensionrr}r(hUhjubahj7ubhX" of the image that was just added.rr}r(hX" of the image that was just added.hjhubeubh)r}r(hX**Typical response codes:**rhj2hhhhh}r(h]h]h]h]h]uhMhhh{]rjN)r}r(hjh}r(h]h]h]h]h]uhjh{]rhXTypical response codes:rr}r(hUhjubahjVubaubj)r}r(hUhj2hhhjh}r(jZX*h]h]h]h]h]uhMhhh{]r(j)r}r(hX200 OKrhjhhhj8h}r(h]h]h]h]h]uhNhhh{]rh)r}r(hjhjhhhhh}r(h]h]h]h]h]uhMh{]rhX200 OKrr}r(hjhjubaubaubj)r}r(hX 201 Createdrhjhhhj8h}r(h]h]h]h]h]uhNhhh{]rh)r}r(hjhjhhhhh}r(h]h]h]h]h]uhMh{]rhX 201 Createdrr}r(hjhjubaubaubj)r}r(hX400 Bad request hjhhhj8h}r(h]h]h]h]h]uhNhhh{]rh)r}r(hX400 Bad requestrhjhhhhh}r(h]h]h]h]h]uhMh{]rhX400 Bad requestrr}r(hjhjubaubaubeubeubh})r}r(hUhjhhhhh}r(h]h]h]h]rhuah]rh6auhMhhh{]r(h)r}r(hXGet image collectionsrhjhhhhh}r(h]h]h]h]h]uhMhhh{]rhXGet image collectionsrr}r(hjhjubaubh)r}r(hXThe images resource can also be used to gather information on which images a user owns. This is done by requesting this resource using ``HTTP GET``. Supported query parameters are:rhjhhhhh}r(h]h]h]h]h]uhM hhh{]r(hXThe images resource can also be used to gather information on which images a user owns. This is done by requesting this resource using rr}r(hXThe images resource can also be used to gather information on which images a user owns. This is done by requesting this resource using hjubj/)r}r(hX ``HTTP GET``h}r(h]h]h]h]h]uhjh{]rhXHTTP GETrr}r(hUhjubahj7ubhX!. Supported query parameters are:rr}r(hX!. Supported query parameters are:hjubeubcdocutils.nodes definition_list r)r}r(hUhjhhhUdefinition_listrh}r(h]h]h]h]h]uhNhhh{]r(cdocutils.nodes definition_list_item r)r}r(hX-``page`` The page number. Defaults to ``1``. hjhhhUdefinition_list_itemrh}r(h]h]h]h]h]uhM h{]r(cdocutils.nodes term r)r}r(hX``page``rhjhhhUtermrh}r (h]h]h]h]h]uhM h{]r j/)r }r (hjh}r (h]h]h]h]h]uhjh{]rhXpagerr}r(hUhj ubahj7ubaubcdocutils.nodes definition r)r}r(hUh}r(h]h]h]h]h]uhjh{]rh)r}r(hX#The page number. Defaults to ``1``.hjhhhhh}r(h]h]h]h]h]uhM h{]r(hXThe page number. Defaults to rr}r(hXThe page number. Defaults to hjubj/)r}r(hX``1``h}r (h]h]h]h]h]uhjh{]r!hX1r"}r#(hUhjubahj7ubhX.r$}r%(hX.hjubeubahU definitionr&ubeubj)r'}r((hX9``limit`` Number of images per page. Defaults to ``20``. hjhhhjh}r)(h]h]h]h]h]uhMhhh{]r*(j)r+}r,(hX ``limit``r-hj'hhhjh}r.(h]h]h]h]h]uhMh{]r/j/)r0}r1(hj-h}r2(h]h]h]h]h]uhj+h{]r3hXlimitr4r5}r6(hUhj0ubahj7ubaubj)r7}r8(hUh}r9(h]h]h]h]h]uhj'h{]r:h)r;}r<(hX.Number of images per page. Defaults to ``20``.hj7hhhhh}r=(h]h]h]h]h]uhMh{]r>(hX'Number of images per page. Defaults to r?r@}rA(hX'Number of images per page. Defaults to hj;ubj/)rB}rC(hX``20``h}rD(h]h]h]h]h]uhj;h{]rEhX20rFrG}rH(hUhjBubahj7ubhX.rI}rJ(hX.hj;ubeubahj&ubeubj)rK}rL(hXj``metadata`` Whether or not to include metadata in the output. Defaults to ``0``, set to ``1`` to enable. hjhhhjh}rM(h]h]h]h]h]uhMhhh{]rN(j)rO}rP(hX ``metadata``rQhjKhhhjh}rR(h]h]h]h]h]uhMh{]rSj/)rT}rU(hjQh}rV(h]h]h]h]h]uhjOh{]rWhXmetadatarXrY}rZ(hUhjTubahj7ubaubj)r[}r\(hUh}r](h]h]h]h]h]uhjKh{]r^h)r_}r`(hX\Whether or not to include metadata in the output. Defaults to ``0``, set to ``1`` to enable.hj[hhhhh}ra(h]h]h]h]h]uhMh{]rb(hX>Whether or not to include metadata in the output. Defaults to rcrd}re(hX>Whether or not to include metadata in the output. Defaults to hj_ubj/)rf}rg(hX``0``h}rh(h]h]h]h]h]uhj_h{]rihX0rj}rk(hUhjfubahj7ubhX , set to rlrm}rn(hX , set to hj_ubj/)ro}rp(hX``1``h}rq(h]h]h]h]h]uhj_h{]rrhX1rs}rt(hUhjoubahj7ubhX to enable.rurv}rw(hX to enable.hj_ubeubahj&ubeubj)rx}ry(hXj``from`` Fetch images starting from this `Unix timestamp `_. hjhhhjh}rz(h]h]h]h]h]uhMhhh{]r{(j)r|}r}(hX``from``r~hjxhhhjh}r(h]h]h]h]h]uhMh{]rj/)r}r(hj~h}r(h]h]h]h]h]uhj|h{]rhXfromrr}r(hUhjubahj7ubaubj)r}r(hUh}r(h]h]h]h]h]uhjxh{]rh)r}r(hX`Fetch images starting from this `Unix timestamp `_.hjhhhhh}r(h]h]h]h]h]uhMh{]r(hX Fetch images starting from this rr}r(hX Fetch images starting from this hjubh)r}r(hX?`Unix timestamp `_h}r(UnameXUnix timestamphX+http://en.wikipedia.org/wiki/Unix_timestamprh]h]h]h]h]uhjh{]rhXUnix timestamprr}r(hUhjubahhubh)r}r(hX. hKhjhhh}r(Urefurijh]rheah]h]h]h]rh&auh{]ubhX.r}r(hX.hjubeubahj&ubeubj)r}r(hX-``to`` Fetch images up until this timestamp. hjhhhjh}r(h]h]h]h]h]uhMhhh{]r(j)r}r(hX``to``rhjhhhjh}r(h]h]h]h]h]uhMh{]rj/)r}r(hjh}r(h]h]h]h]h]uhjh{]rhXtorr}r(hUhjubahj7ubaubj)r}r(hUh}r(h]h]h]h]h]uhjh{]rh)r}r(hX%Fetch images up until this timestamp.rhjhhhhh}r(h]h]h]h]h]uhMh{]rhX%Fetch images up until this timestamp.rr}r(hjhjubaubahj&ubeubj)r}r(hX_``fields[]`` An array with fields to display. When not specified all fields will be displayed. hjhhhjh}r(h]h]h]h]h]uhMhhh{]r(j)r}r(hX ``fields[]``rhjhhhjh}r(h]h]h]h]h]uhMh{]rj/)r}r(hjh}r(h]h]h]h]h]uhjh{]rhXfields[]rr}r(hUhjubahj7ubaubj)r}r(hUh}r(h]h]h]h]h]uhjh{]rh)r}r(hXQAn array with fields to display. When not specified all fields will be displayed.rhjhhhhh}r(h]h]h]h]h]uhMh{]rhXQAn array with fields to display. When not specified all fields will be displayed.rr}r(hjhjubaubahj&ubeubj)r}r(hX``sort[]`` An array with fields to sort by. The direction of the sort is specified by appending ``asc`` or ``desc`` to the field, delimited by ``:``. If no direction is specified ``asc`` will be used. Example: ``?sort[]=size&sort[]=width:desc`` is the same as ``?sort[]=size:asc&sort[]=width:desc``. If no ``sort`` is specified Imbo will sort by the date the images was added, in a descending fashion. hjhhhjh}r(h]h]h]h]h]uhMhhh{]r(j)r}r(hX ``sort[]``rhjhhhjh}r(h]h]h]h]h]uhMh{]rj/)r}r(hjh}r(h]h]h]h]h]uhjh{]rhXsort[]rr}r(hUhjubahj7ubaubj)r}r(hUh}r(h]h]h]h]h]uhjh{]rh)r}r(hXAn array with fields to sort by. The direction of the sort is specified by appending ``asc`` or ``desc`` to the field, delimited by ``:``. If no direction is specified ``asc`` will be used. Example: ``?sort[]=size&sort[]=width:desc`` is the same as ``?sort[]=size:asc&sort[]=width:desc``. If no ``sort`` is specified Imbo will sort by the date the images was added, in a descending fashion.hjhhhhh}r(h]h]h]h]h]uhMh{]r(hXUAn array with fields to sort by. The direction of the sort is specified by appending rr}r(hXUAn array with fields to sort by. The direction of the sort is specified by appending hjubj/)r}r(hX``asc``h}r(h]h]h]h]h]uhjh{]rhXascrr}r(hUhjubahj7ubhX or rr}r(hX or hjubj/)r}r(hX``desc``h}r(h]h]h]h]h]uhjh{]rhXdescrr}r(hUhjubahj7ubhX to the field, delimited by rr}r(hX to the field, delimited by hjubj/)r }r (hX``:``h}r (h]h]h]h]h]uhjh{]r hX:r }r(hUhj ubahj7ubhX. If no direction is specified rr}r(hX. If no direction is specified hjubj/)r}r(hX``asc``h}r(h]h]h]h]h]uhjh{]rhXascrr}r(hUhjubahj7ubhX will be used. Example: rr}r(hX will be used. Example: hjubj/)r}r(hX"``?sort[]=size&sort[]=width:desc``h}r(h]h]h]h]h]uhjh{]rhX?sort[]=size&sort[]=width:descr r!}r"(hUhjubahj7ubhX is the same as r#r$}r%(hX is the same as hjubj/)r&}r'(hX&``?sort[]=size:asc&sort[]=width:desc``h}r((h]h]h]h]h]uhjh{]r)hX"?sort[]=size:asc&sort[]=width:descr*r+}r,(hUhj&ubahj7ubhX. If no r-r.}r/(hX. If no hjubj/)r0}r1(hX``sort``h}r2(h]h]h]h]h]uhjh{]r3hXsortr4r5}r6(hUhj0ubahj7ubhXW is specified Imbo will sort by the date the images was added, in a descending fashion.r7r8}r9(hXW is specified Imbo will sort by the date the images was added, in a descending fashion.hjubeubahj&ubeubj)r:}r;(hXB``ids[]`` An array of image identifiers to filter the results by. hjhhhjh}r<(h]h]h]h]h]uhM!hhh{]r=(j)r>}r?(hX ``ids[]``r@hj:hhhjh}rA(h]h]h]h]h]uhM!h{]rBj/)rC}rD(hj@h}rE(h]h]h]h]h]uhj>h{]rFhXids[]rGrH}rI(hUhjCubahj7ubaubj)rJ}rK(hUh}rL(h]h]h]h]h]uhj:h{]rMh)rN}rO(hX7An array of image identifiers to filter the results by.rPhjJhhhhh}rQ(h]h]h]h]h]uhM!h{]rRhX7An array of image identifiers to filter the results by.rSrT}rU(hjPhjNubaubahj&ubeubj)rV}rW(hXF``checksums[]`` An array of image checksums to filter the results by. hjhhhjh}rX(h]h]h]h]h]uhM$hhh{]rY(j)rZ}r[(hX``checksums[]``r\hjVhhhjh}r](h]h]h]h]h]uhM$h{]r^j/)r_}r`(hj\h}ra(h]h]h]h]h]uhjZh{]rbhX checksums[]rcrd}re(hUhj_ubahj7ubaubj)rf}rg(hUh}rh(h]h]h]h]h]uhjVh{]rih)rj}rk(hX5An array of image checksums to filter the results by.rlhjfhhhhh}rm(h]h]h]h]h]uhM$h{]rnhX5An array of image checksums to filter the results by.rorp}rq(hjlhjjubaubahj&ubeubeubj)rr}rs(hX>curl "http://imbo/users//images.json?limit=1&metadata=1"hjhhhjh}rt(jjXbashjjh]h]h]h]h]uhM&hhh{]ruhX>curl "http://imbo/users//images.json?limit=1&metadata=1"rvrw}rx(hUhjrubaubh)ry}rz(hX results in:r{hjhhhhh}r|(h]h]h]h]h]uhM*hhh{]r}hX results in:r~r}r(hj{hjyubaubj)r}r(hX{ "search": { "hits": 3, "page": 1, "limit": 1, "count": 1 }, "images": [ { "added": "Mon, 10 Dec 2012 11:57:51 GMT", "extension": "png", "height": 77, "imageIdentifier": "", "metadata": { "key": "value", "foo": "bar" }, "mime": "image/png", "publicKey": "", "size": 6791, "updated": "Mon, 10 Dec 2012 11:57:51 GMT", "width": 1306 } ] }hjhhhjh}r(jjX javascriptjjh]h]h]h]h]uhM,hhh{]rhX{ "search": { "hits": 3, "page": 1, "limit": 1, "count": 1 }, "images": [ { "added": "Mon, 10 Dec 2012 11:57:51 GMT", "extension": "png", "height": 77, "imageIdentifier": "", "metadata": { "key": "value", "foo": "bar" }, "mime": "image/png", "publicKey": "", "size": 6791, "updated": "Mon, 10 Dec 2012 11:57:51 GMT", "width": 1306 } ] }rr}r(hUhjubaubh)r}r(hXThe ``search`` object is data related to pagination, where ``hits`` is the number of images found by your query, ``page`` is the current page, ``limit`` is the current limit, and ``count`` is the number of images in the visible collection.rhjhhhhh}r(h]h]h]h]h]uhMHhhh{]r(hXThe rr}r(hXThe hjubj/)r}r(hX ``search``h}r(h]h]h]h]h]uhjh{]rhXsearchrr}r(hUhjubahj7ubhX- object is data related to pagination, where rr}r(hX- object is data related to pagination, where hjubj/)r}r(hX``hits``h}r(h]h]h]h]h]uhjh{]rhXhitsrr}r(hUhjubahj7ubhX. is the number of images found by your query, rr}r(hX. is the number of images found by your query, hjubj/)r}r(hX``page``h}r(h]h]h]h]h]uhjh{]rhXpagerr}r(hUhjubahj7ubhX is the current page, rr}r(hX is the current page, hjubj/)r}r(hX ``limit``h}r(h]h]h]h]h]uhjh{]rhXlimitrr}r(hUhjubahj7ubhX is the current limit, and rr}r(hX is the current limit, and hjubj/)r}r(hX ``count``h}r(h]h]h]h]h]uhjh{]rhXcountrr}r(hUhjubahj7ubhX3 is the number of images in the visible collection.rr}r(hX3 is the number of images in the visible collection.hjubeubh)r}r(hX}The ``images`` list contains image objects, where ``added`` is a formatted date of when the image was added to Imbo, ``extension`` is the original image extension, ``height`` is the height of the image in pixels, ``imageIdentifier`` is the image identifier (`MD5 checksum `_ of the file itself), ``metadata`` is a JSON object containing metadata attached to the image, ``mime`` is the mime type of the image, ``publicKey`` is the public key of the user who owns the image, ``size`` is the size of the image in bytes, ``updated`` is a formatted date of when the image was last updated (read: when metadata attached to the image was last updated, as the image itself never changes), and ``width`` is the width of the image in pixels. The fact that the image identifier is the MD5 checksum of the image is an implementation detail and might change in the future.rhjhhhhh}r(h]h]h]h]h]uhMJhhh{]r(hXThe rr}r(hXThe hjubj/)r}r(hX ``images``h}r(h]h]h]h]h]uhjh{]rhXimagesrr}r(hUhjubahj7ubhX$ list contains image objects, where rr}r(hX$ list contains image objects, where hjubj/)r}r(hX ``added``h}r(h]h]h]h]h]uhjh{]rhXaddedrr}r(hUhjubahj7ubhX: is a formatted date of when the image was added to Imbo, rr}r(hX: is a formatted date of when the image was added to Imbo, hjubj/)r}r(hX ``extension``h}r(h]h]h]h]h]uhjh{]rhX extensionrr}r(hUhjubahj7ubhX" is the original image extension, rr}r(hX" is the original image extension, hjubj/)r}r(hX ``height``h}r(h]h]h]h]h]uhjh{]rhXheightrr}r(hUhjubahj7ubhX' is the height of the image in pixels, rr}r(hX' is the height of the image in pixels, hjubj/)r}r(hX``imageIdentifier``h}r(h]h]h]h]h]uhjh{]rhXimageIdentifierrr}r(hUhjubahj7ubhX is the image identifier (rr}r(hX is the image identifier (hjubh)r}r(hX2`MD5 checksum `_h}r(UnameX MD5 checksumhX http://en.wikipedia.org/wiki/MD5rh]h]h]h]h]uhjh{]rhX MD5 checksumrr}r(hUhjubahhubh)r}r(hX# hKhjhhh}r(Urefurijh]rhhah]h]h]h]rh)auh{]ubhX of the file itself), r r }r (hX of the file itself), hjubj/)r }r (hX ``metadata``h}r(h]h]h]h]h]uhjh{]rhXmetadatarr}r(hUhj ubahj7ubhX= is a JSON object containing metadata attached to the image, rr}r(hX= is a JSON object containing metadata attached to the image, hjubj/)r}r(hX``mime``h}r(h]h]h]h]h]uhjh{]rhXmimerr}r(hUhjubahj7ubhX is the mime type of the image, rr}r(hX is the mime type of the image, hjubj/)r }r!(hX ``publicKey``h}r"(h]h]h]h]h]uhjh{]r#hX publicKeyr$r%}r&(hUhj ubahj7ubhX3 is the public key of the user who owns the image, r'r(}r)(hX3 is the public key of the user who owns the image, hjubj/)r*}r+(hX``size``h}r,(h]h]h]h]h]uhjh{]r-hXsizer.r/}r0(hUhj*ubahj7ubhX$ is the size of the image in bytes, r1r2}r3(hX$ is the size of the image in bytes, hjubj/)r4}r5(hX ``updated``h}r6(h]h]h]h]h]uhjh{]r7hXupdatedr8r9}r:(hUhj4ubahj7ubhX is a formatted date of when the image was last updated (read: when metadata attached to the image was last updated, as the image itself never changes), and r;r<}r=(hX is a formatted date of when the image was last updated (read: when metadata attached to the image was last updated, as the image itself never changes), and hjubj/)r>}r?(hX ``width``h}r@(h]h]h]h]h]uhjh{]rAhXwidthrBrC}rD(hUhj>ubahj7ubhX is the width of the image in pixels. The fact that the image identifier is the MD5 checksum of the image is an implementation detail and might change in the future.rErF}rG(hX is the width of the image in pixels. The fact that the image identifier is the MD5 checksum of the image is an implementation detail and might change in the future.hjubeubh)rH}rI(hXfThe ``metadata`` field is only available if you used the ``metadata`` query parameter described above.rJhjhhhhh}rK(h]h]h]h]h]uhMLhhh{]rL(hXThe rMrN}rO(hXThe hjHubj/)rP}rQ(hX ``metadata``h}rR(h]h]h]h]h]uhjHh{]rShXmetadatarTrU}rV(hUhjPubahj7ubhX) field is only available if you used the rWrX}rY(hX) field is only available if you used the hjHubj/)rZ}r[(hX ``metadata``h}r\(h]h]h]h]h]uhjHh{]r]hXmetadatar^r_}r`(hUhjZubahj7ubhX! query parameter described above.rarb}rc(hX! query parameter described above.hjHubeubh)rd}re(hX**Typical response codes:**rfhjhhhhh}rg(h]h]h]h]h]uhMNhhh{]rhjN)ri}rj(hjfh}rk(h]h]h]h]h]uhjdh{]rlhXTypical response codes:rmrn}ro(hUhjiubahjVubaubj)rp}rq(hUhjhhhjh}rr(jZX*h]h]h]h]h]uhMPhhh{]rs(j)rt}ru(hX200 OKrvhjphhhj8h}rw(h]h]h]h]h]uhNhhh{]rxh)ry}rz(hjvhjthhhhh}r{(h]h]h]h]h]uhMPh{]r|hX200 OKr}r~}r(hjvhjyubaubaubj)r}r(hX304 Not modifiedrhjphhhj8h}r(h]h]h]h]h]uhNhhh{]rh)r}r(hjhjhhhhh}r(h]h]h]h]h]uhMQh{]rhX304 Not modifiedrr}r(hjhjubaubaubj)r}r(hX404 Public key not found hjphhhj8h}r(h]h]h]h]h]uhNhhh{]rh)r}r(hX404 Public key not foundrhjhhhhh}r(h]h]h]h]h]uhMRh{]rhX404 Public key not foundrr}r(hjhjubaubaubeubh)r}r(hX.. _image-resource:hjhhhhh}r(h]h]h]h]h]jhUuhMThhh{]ubeubeubh})r}r(hUhhhhj}rhjshhh}r(h]h]h]h]r(hYhUeh]r(hheuhMWhhj}rhUjsh{]r(h)r}r(hX1Image resource - ``/users//images/``rhjhhhhh}r(h]h]h]h]h]jjuhMWhhh{]r(hXImage resource - rr}r(hjhjubj/)r}r(hjh}r(h]h]h]h]h]uhjh{]rhX/users//images/rr}r(hUhjubahj7ubeubh)r}r(hXThe image resource represents specific images owned by a user. This resource is used to retrieve and remove images. It's also responsible for transforming the images based on the transformation parameters in the query.rhjhhhhh}r(h]h]h]h]h]uhMYhhh{]rhXThe image resource represents specific images owned by a user. This resource is used to retrieve and remove images. It's also responsible for transforming the images based on the transformation parameters in the query.rr}r(hjhjubaubh})r}r(hUhjhhhhh}r(h]h]h]h]rhtah]rh5auhM\hhh{]r(h)r}r(hX Fetch imagesrhjhhhhh}r(h]h]h]h]h]uhM\hhh{]rhX Fetch imagesrr}r(hjhjubaubh)r}r(hXcFetching images added to Imbo is done by requesting the image identifiers (checksum) of the images.rhjhhhhh}r(h]h]h]h]h]uhM^hhh{]rhXcFetching images added to Imbo is done by requesting the image identifiers (checksum) of the images.rr}r(hjhjubaubj)r}r(hX,curl http://imbo/users//images/hjhhhjh}r(jjXbashjjh]h]h]h]h]uhM`hhh{]rhX,curl http://imbo/users//images/rr}r(hUhjubaubh)r}r(hX results in:rhjhhhhh}r(h]h]h]h]h]uhMdhhh{]rhX results in:rr}r(hjhjubaubj)r}r(hX#hjhhhjh}r(jjXbashjjh]h]h]h]h]uhMfhhh{]rhX#rr}r(hUhjubaubh)r}r(hXaWhen fetching images Imbo also sends a set of custom HTTP response headers related to the image::rhjhhhhh}r(h]h]h]h]h]uhMjhhh{]rhX`When fetching images Imbo also sends a set of custom HTTP response headers related to the image:rr}r(hX`When fetching images Imbo also sends a set of custom HTTP response headers related to the image:hjubaubj)r}r(hXX-Imbo-Originalextension: png X-Imbo-Originalmimetype: image/png X-Imbo-Originalfilesize: 45826 X-Imbo-Originalheight: 390 X-Imbo-Originalwidth: 380 X-Imbo-ShortUrl: http://imbo/s/w7CiqDMhjhhhjh}r(jjh]h]h]h]h]uhMlhhh{]rhXX-Imbo-Originalextension: png X-Imbo-Originalmimetype: image/png X-Imbo-Originalfilesize: 45826 X-Imbo-Originalheight: 390 X-Imbo-Originalwidth: 380 X-Imbo-ShortUrl: http://imbo/s/w7CiqDMrr}r(hUhjubaubh)r}r(hX;These are all related to the image that was just requested.rhjhhhhh}r(h]h]h]h]h]uhMshhh{]rhX;These are all related to the image that was just requested.rr}r(hjhjubaubh)r}r(hX}How to use this resource to generate image transformations is described in the :doc:`../usage/image-transformations` chapter.rhjhhhhh}r (h]h]h]h]h]uhMuhhh{]r (hXOHow to use this resource to generate image transformations is described in the r r }r (hXOHow to use this resource to generate image transformations is described in the hjubh)r }r (hX%:doc:`../usage/image-transformations`r hjhhhhh}r (UreftypeXdocr hƈhX../usage/image-transformationsU refdomainUh]h]U refexplicith]h]h]hhuhMuh{]r j/)r }r (hj h}r (h]h]r (hj eh]h]h]uhj h{]r hX../usage/image-transformationsr r }r (hUhj ubahj7ubaubhX chapter.r r }r (hX chapter.hjubeubh)r }r (hX**Typical response codes:**r hjhhhhh}r (h]h]h]h]h]uhMwhhh{]r jN)r }r (hj h}r (h]h]h]h]h]uhj h{]r hXTypical response codes:r r }r! (hUhj ubahjVubaubj)r" }r# (hUhjhhhjh}r$ (jZX*h]h]h]h]h]uhMyhhh{]r% (j)r& }r' (hX200 OKr( hj" hhhj8h}r) (h]h]h]h]h]uhNhhh{]r* h)r+ }r, (hj( hj& hhhhh}r- (h]h]h]h]h]uhMyh{]r. hX200 OKr/ r0 }r1 (hj( hj+ ubaubaubj)r2 }r3 (hX304 Not modifiedr4 hj" hhhj8h}r5 (h]h]h]h]h]uhNhhh{]r6 h)r7 }r8 (hj4 hj2 hhhhh}r9 (h]h]h]h]h]uhMzh{]r: hX304 Not modifiedr; r< }r= (hj4 hj7 ubaubaubj)r> }r? (hX400 Bad requestr@ hj" hhhj8h}rA (h]h]h]h]h]uhNhhh{]rB h)rC }rD (hj@ hj> hhhhh}rE (h]h]h]h]h]uhM{h{]rF hX400 Bad requestrG rH }rI (hj@ hjC ubaubaubj)rJ }rK (hX404 Image not found hj" hhhj8h}rL (h]h]h]h]h]uhNhhh{]rM h)rN }rO (hX404 Image not foundrP hjJ hhhhh}rQ (h]h]h]h]h]uhM|h{]rR hX404 Image not foundrS rT }rU (hjP hjN ubaubaubeubeubh})rV }rW (hUhjhhhhh}rX (h]h]h]h]rY hvah]rZ h7auhMhhh{]r[ (h)r\ }r] (hX Delete imagesr^ hjV hhhhh}r_ (h]h]h]h]h]uhMhhh{]r` hX Delete imagesra rb }rc (hj^ hj\ ubaubh)rd }re (hXDeleting images from Imbo is accomplished by requesting the image URIs using ``HTTP DELETE``. All metadata attached to the image will be removed as well.rf hjV hhhhh}rg (h]h]h]h]h]uhMhhh{]rh (hXMDeleting images from Imbo is accomplished by requesting the image URIs using ri rj }rk (hXMDeleting images from Imbo is accomplished by requesting the image URIs using hjd ubj/)rl }rm (hX``HTTP DELETE``h}rn (h]h]h]h]h]uhjd h{]ro hX HTTP DELETErp rq }rr (hUhjl ubahj7ubhX=. All metadata attached to the image will be removed as well.rs rt }ru (hX=. All metadata attached to the image will be removed as well.hjd ubeubj)rv }rw (hX5curl -XDELETE http://imbo/users//images/hjV hhhjh}rx (jjXbashjjh]h]h]h]h]uhMhhh{]ry hX5curl -XDELETE http://imbo/users//images/rz r{ }r| (hUhjv ubaubh)r} }r~ (hX results in:r hjV hhhhh}r (h]h]h]h]h]uhMhhh{]r hX results in:r r }r (hj hj} ubaubj)r }r (hX"{ "imageIdentifier": "" }hjV hhhjh}r (jjX javascriptjjh]h]h]h]h]uhMhhh{]r hX"{ "imageIdentifier": "" }r r }r (hUhj ubaubh)r }r (hXswhere ```` is the image identifier of the image that was just deleted (the same as the one used in the URI).r hjV hhhhh}r (h]h]h]h]h]uhMhhh{]r (hXwhere r r }r (hXwhere hj ubj/)r }r (hX ````h}r (h]h]h]h]h]uhj h{]r hXr r }r (hUhj ubahj7ubhXb is the image identifier of the image that was just deleted (the same as the one used in the URI).r r }r (hXb is the image identifier of the image that was just deleted (the same as the one used in the URI).hj ubeubh)r }r (hX**Typical response codes:**r hjV hhhhh}r (h]h]h]h]h]uhMhhh{]r jN)r }r (hj h}r (h]h]h]h]h]uhj h{]r hXTypical response codes:r r }r (hUhj ubahjVubaubj)r }r (hUhjV hhhjh}r (jZX*h]h]h]h]h]uhMhhh{]r (j)r }r (hX200 OKr hj hhhj8h}r (h]h]h]h]h]uhNhhh{]r h)r }r (hj hj hhhhh}r (h]h]h]h]h]uhMh{]r hX200 OKr r }r (hj hj ubaubaubj)r }r (hX400 Bad requestr hj hhhj8h}r (h]h]h]h]h]uhNhhh{]r h)r }r (hj hj hhhhh}r (h]h]h]h]h]uhMh{]r hX400 Bad requestr r }r (hj hj ubaubaubj)r }r (hX404 Image not found hj hhhj8h}r (h]h]h]h]h]uhNhhh{]r h)r }r (hX404 Image not foundr hj hhhhh}r (h]h]h]h]h]uhMh{]r hX404 Image not foundr r }r (hj hj ubaubaubeubh)r }r (hX.. _shorturl-resource:hjV hhhhh}r (h]h]h]h]h]jhiuhMhhh{]ubeubeubh})r }r (hUhhhhj}r h*j shhh}r (h]h]h]h]r (hFhieh]r (hh*euhMhhj}r hij sh{]r (h)r }r (hXShortURL resource - ``/s/``r hj hhhhh}r (h]h]h]h]h]jjuhMhhh{]r (hXShortURL resource - r r }r (hjhj ubj/)r }r (hjh}r (h]h]h]h]h]uhj h{]r hX/s/r r }r (hUhj ubahj7ubeubh)r }r (hXImages in Imbo have short URLs associated with them, which are generated on request when you access an image (with or without image transformations) for the first time. These URLs do not take any query parameters and can be used in place for original image URLs. To fetch these URLs you can request an image using ``HTTP HEAD``, then look for the ``X-Imbo-ShortUrl`` header in the response::r hj hhhhh}r (h]h]h]h]h]uhMhhh{]r (hX:Images in Imbo have short URLs associated with them, which are generated on request when you access an image (with or without image transformations) for the first time. These URLs do not take any query parameters and can be used in place for original image URLs. To fetch these URLs you can request an image using r r }r (hX:Images in Imbo have short URLs associated with them, which are generated on request when you access an image (with or without image transformations) for the first time. These URLs do not take any query parameters and can be used in place for original image URLs. To fetch these URLs you can request an image using hj ubj/)r }r (hX ``HTTP HEAD``h}r (h]h]h]h]h]uhj h{]r hX HTTP HEADr r }r (hUhj ubahj7ubhX, then look for the r r }r (hX, then look for the hj ubj/)r }r (hX``X-Imbo-ShortUrl``h}r (h]h]h]h]h]uhj h{]r hXX-Imbo-ShortUrlr r }r (hUhj ubahj7ubhX header in the response:r r }r (hX header in the response:hj ubeubj)r }r (hXcurl -Ig "http://imbo/users//images/?t[]=thumbnail&t[]=desaturate&t[]=border&accessToken=f3fa1d9f0649cfad61e840a6e09b156e851858799364d1d8ee61b386e10b0c05"|grep Imbohj hhhjh}r (jjh]h]h]h]h]uhMhhh{]r hXcurl -Ig "http://imbo/users//images/?t[]=thumbnail&t[]=desaturate&t[]=border&accessToken=f3fa1d9f0649cfad61e840a6e09b156e851858799364d1d8ee61b386e10b0c05"|grep Imbor r }r (hUhj ubaubh)r }r (hX"results in (some headers omitted):r hj hhhhh}r (h]h]h]h]h]uhMhhh{]r hX"results in (some headers omitted):r r }r (hj hj ubaubj)r }r (hXX-Imbo-OriginalMimeType: image/gif X-Imbo-OriginalWidth: 771 X-Imbo-OriginalHeight: 771 X-Imbo-OriginalFileSize: 152066 X-Imbo-OriginalExtension: gif X-Imbo-ShortUrl: http://imbo/s/3VEFrpB X-Imbo-ImageIdentifier: 4492acb937a1f056ae43509bc7f85d21hj hhhjh}r (jjXnonejjh]h]h]Uhighlight_argsr }r Uhl_linesr ]r Kash]h]uhMhhh{]r hXX-Imbo-OriginalMimeType: image/gif X-Imbo-OriginalWidth: 771 X-Imbo-OriginalHeight: 771 X-Imbo-OriginalFileSize: 152066 X-Imbo-OriginalExtension: gif X-Imbo-ShortUrl: http://imbo/s/3VEFrpB X-Imbo-ImageIdentifier: 4492acb937a1f056ae43509bc7f85d21r r }r! (hUhj ubaubh)r" }r# (hXThe value of the ``X-Imbo-ShortUrl`` can be used to request the image with the applied transformations, and does not require an access token query parameter.r$ hj hhhhh}r% (h]h]h]h]h]uhMhhh{]r& (hXThe value of the r' r( }r) (hXThe value of the hj" ubj/)r* }r+ (hX``X-Imbo-ShortUrl``h}r, (h]h]h]h]h]uhj" h{]r- hXX-Imbo-ShortUrlr. r/ }r0 (hUhj* ubahj7ubhXy can be used to request the image with the applied transformations, and does not require an access token query parameter.r1 r2 }r3 (hXy can be used to request the image with the applied transformations, and does not require an access token query parameter.hj" ubeubh)r4 }r5 (hXThe format of the random ID part of the short URL can be matched with the following `regular expression `_::r6 hj hhhhh}r7 (h]h]h]h]h]uhMhhh{]r8 (hXTThe format of the random ID part of the short URL can be matched with the following r9 r: }r; (hXTThe format of the random ID part of the short URL can be matched with the following hj4 ubh)r< }r= (hXG`regular expression `_h}r> (UnameXregular expressionhX/http://en.wikipedia.org/wiki/Regular_expressionr? h]h]h]h]h]uhj4 h{]r@ hXregular expressionrA rB }rC (hUhj< ubahhubh)rD }rE (hX2 hKhj4 hhh}rF (Urefurij? h]rG hKah]h]h]h]rH h auh{]ubhX:rI }rJ (hX:hj4 ubeubj)rK }rL (hX/^[a-zA-Z0-9]{7}$/hj hhhjh}rM (jjh]h]h]h]h]uhMhhh{]rN hX/^[a-zA-Z0-9]{7}$/rO rP }rQ (hUhjK ubaubh)rR }rS (hX0There are some caveats regarding the short URLs:rT hj hhhhh}rU (h]h]h]h]h]uhMhhh{]rV hX0There are some caveats regarding the short URLs:rW rX }rY (hjT hjR ubaubcdocutils.nodes enumerated_list rZ )r[ }r\ (hUhj hhhUenumerated_listr] h}r^ (Usuffixr_ U)h]h]h]Uprefixr` Uh]h]Uenumtypera Uarabicrb uhMhhh{]rc (j)rd }re (hXIf the URL used to generate the short URL contained an image extension, content negotiation will not be applied to the short URL. You will always get the mime type associated with the extension used to generate the short URL.rf hj[ hhhj8h}rg (h]h]h]h]h]uhNhhh{]rh h)ri }rj (hjf hjd hhhhh}rk (h]h]h]h]h]uhMh{]rl hXIf the URL used to generate the short URL contained an image extension, content negotiation will not be applied to the short URL. You will always get the mime type associated with the extension used to generate the short URL.rm rn }ro (hjf hji ubaubaubj)rp }rq (hXIf the URL used to generate the short URL did not contain an image extension you can use the ``Accept`` header to decide the mime type of the generated image when requesting the short URL.rr hj[ hhhj8h}rs (h]h]h]h]h]uhNhhh{]rt h)ru }rv (hjr hjp hhhhh}rw (h]h]h]h]h]uhMh{]rx (hX]If the URL used to generate the short URL did not contain an image extension you can use the ry rz }r{ (hX]If the URL used to generate the short URL did not contain an image extension you can use the hju ubj/)r| }r} (hX ``Accept``h}r~ (h]h]h]h]h]uhju h{]r hXAcceptr r }r (hUhj| ubahj7ubhXU header to decide the mime type of the generated image when requesting the short URL.r r }r (hXU header to decide the mime type of the generated image when requesting the short URL.hju ubeubaubj)r }r (hXShort URLs do not support extensions, so you can not append ``.jpg`` to force ``image/jpeg``. If you need to make sure the image is always a JPEG, simply append ``.jpg`` to the URL when generating the short URL. hj[ hhhj8h}r (h]h]h]h]h]uhNhhh{]r h)r }r (hXShort URLs do not support extensions, so you can not append ``.jpg`` to force ``image/jpeg``. If you need to make sure the image is always a JPEG, simply append ``.jpg`` to the URL when generating the short URL.hj hhhhh}r (h]h]h]h]h]uhMh{]r (hX<Short URLs do not support extensions, so you can not append r r }r (hX<Short URLs do not support extensions, so you can not append hj ubj/)r }r (hX``.jpg``h}r (h]h]h]h]h]uhj h{]r hX.jpgr r }r (hUhj ubahj7ubhX to force r r }r (hX to force hj ubj/)r }r (hX``image/jpeg``h}r (h]h]h]h]h]uhj h{]r hX image/jpegr r }r (hUhj ubahj7ubhXE. If you need to make sure the image is always a JPEG, simply append r r }r (hXE. If you need to make sure the image is always a JPEG, simply append hj ubj/)r }r (hX``.jpg``h}r (h]h]h]h]h]uhj h{]r hX.jpgr r }r (hUhj ubahj7ubhX* to the URL when generating the short URL.r r }r (hX* to the URL when generating the short URL.hj ubeubaubeubjh)r }r (hX$In Imbo only images have short URL'sr hj hhhjlh}r (h]h]h]h]h]uhNhhh{]r h)r }r (hj hj hhhhh}r (h]h]h]h]h]uhMh{]r hX$In Imbo only images have short URL'sr r }r (hj hj ubaubaubh)r }r (hX.. _metadata-resource:hj hhhhh}r (h]h]h]h]h]jhduhMhhh{]ubeubh})r }r (hUhhhhj}r h%j shhh}r (h]h]h]h]r (hfhdeh]r (h'h%euhMhhj}r hdj sh{]r (h)r }r (hX=Metadata resource - ``/users//images//metadata``r hj hhhhh}r (h]h]h]h]h]jjuhMhhh{]r (hXMetadata resource - r r }r (hjhj ubj/)r }r (hjh}r (h]h]h]h]h]uhj h{]r hX%/users//images//metadatar r }r (hUhj ubahj7ubeubh)r }r (hXImbo can also be used to attach metadata to the stored images. The metadata is based on a simple ``key => value`` model, for instance:r hj hhhhh}r (h]h]h]h]h]uhMhhh{]r (hXaImbo can also be used to attach metadata to the stored images. The metadata is based on a simple r r }r (hXaImbo can also be used to attach metadata to the stored images. The metadata is based on a simple hj ubj/)r }r (hX``key => value``h}r (h]h]h]h]h]uhj h{]r hX key => valuer r }r (hUhj ubahj7ubhX model, for instance:r r }r (hX model, for instance:hj ubeubj)r }r (hUhj hhhjh}r (jZX*h]h]h]h]h]uhMhhh{]r (j)r }r (hX``category: Music``r hj hhhj8h}r (h]h]h]h]h]uhNhhh{]r h)r }r (hj hj hhhhh}r (h]h]h]h]h]uhMh{]r j/)r }r (hj h}r (h]h]h]h]h]uhj h{]r hXcategory: Musicr r }r (hUhj ubahj7ubaubaubj)r }r (hX``band: Koldbrann``r hj hhhj8h}r (h]h]h]h]h]uhNhhh{]r h)r }r (hj hj hhhhh}r (h]h]h]h]h]uhMh{]r j/)r }r (hj h}r (h]h]h]h]h]uhj h{]r hXband: Koldbrannr r }r (hUhj ubahj7ubaubaubj)r }r (hX``genre: Black metal``r hj hhhj8h}r (h]h]h]h]h]uhNhhh{]r h)r }r (hj hj hhhhh}r (h]h]h]h]h]uhMh{]r j/)r }r (hj h}r (h]h]h]h]h]uhj h{]r hXgenre: Black metalr r }r (hUhj ubahj7ubaubaubj)r }r (hX``country: Norway`` hj hhhj8h}r (h]h]h]h]h]uhNhhh{]r h)r }r (hX``country: Norway``r! hj hhhhh}r" (h]h]h]h]h]uhMh{]r# j/)r$ }r% (hj! h}r& (h]h]h]h]h]uhj h{]r' hXcountry: Norwayr( r) }r* (hUhj$ ubahj7ubaubaubeubh)r+ }r, (hX,Values can be nested ``key => value`` pairs.r- hj hhhhh}r. (h]h]h]h]h]uhMhhh{]r/ (hXValues can be nested r0 r1 }r2 (hXValues can be nested hj+ ubj/)r3 }r4 (hX``key => value``h}r5 (h]h]h]h]h]uhj+ h{]r6 hX key => valuer7 r8 }r9 (hUhj3 ubahj7ubhX pairs.r: r; }r< (hX pairs.hj+ ubeubh})r= }r> (hUhj hhhhh}r? (h]h]h]h]r@ hsah]rA h4auhMhhh{]rB (h)rC }rD (hXAdding/replacing metadatarE hj= hhhhh}rF (h]h]h]h]h]uhMhhh{]rG hXAdding/replacing metadatarH rI }rJ (hjE hjC ubaubh)rK }rL (hXTo add (or replace all existing metadata) on an image a client should make a request against this resource using ``HTTP PUT`` with the metadata attached in the request body as a JSON object.rM hj= hhhhh}rN (h]h]h]h]h]uhMhhh{]rO (hXqTo add (or replace all existing metadata) on an image a client should make a request against this resource using rP rQ }rR (hXqTo add (or replace all existing metadata) on an image a client should make a request against this resource using hjK ubj/)rS }rT (hX ``HTTP PUT``h}rU (h]h]h]h]h]uhjK h{]rV hXHTTP PUTrW rX }rY (hUhjS ubahj7ubhXA with the metadata attached in the request body as a JSON object.rZ r[ }r\ (hXA with the metadata attached in the request body as a JSON object.hjK ubeubj)r] }r^ (hXcurl -XPUT http://imbo/users//images//metadata.json -d '{ "beer":"Dark Horizon First Edition", "brewery":"Nøgne Ø", "style":"Imperial Stout" }'hj= hhhjh}r_ (jjXbashjjh]h]h]h]h]uhMhhh{]r` hXcurl -XPUT http://imbo/users//images//metadata.json -d '{ "beer":"Dark Horizon First Edition", "brewery":"Nøgne Ø", "style":"Imperial Stout" }'ra rb }rc (hUhj] ubaubh)rd }re (hX results in:rf hj= hhhhh}rg (h]h]h]h]h]uhMhhh{]rh hX results in:ri rj }rk (hjf hjd ubaubj)rl }rm (hX"{ "imageIdentifier": "" }hj= hhhjh}rn (jjX javascriptjjh]h]h]h]h]uhMhhh{]ro hX"{ "imageIdentifier": "" }rp rq }rr (hUhjl ubaubh)rs }rt (hX5where ```` is the image that just got updated.ru hj= hhhhh}rv (h]h]h]h]h]uhMhhh{]rw (hXwhere rx ry }rz (hXwhere hjs ubj/)r{ }r| (hX ````h}r} (h]h]h]h]h]uhjs h{]r~ hXr r }r (hUhj{ ubahj7ubhX$ is the image that just got updated.r r }r (hX$ is the image that just got updated.hjs ubeubjh)r }r (hXrWhen using the :ref:`Doctrine database adapter `, metadata keys can not contain ``::``.r hj= hhhjlh}r (h]h]h]h]h]uhNhhh{]r h)r }r (hj hj hhhhh}r (h]h]h]h]h]uhMh{]r (hXWhen using the r r }r (hXWhen using the hj ubh)r }r (hX<:ref:`Doctrine database adapter `r hj hhhhh}r (UreftypeXrefhƈhXdoctrine-database-adapterU refdomainXstdr h]h]U refexplicith]h]h]hhuhMh{]r h)r }r (hj h}r (h]h]r (hj Xstd-refr eh]h]h]uhj h{]r hXDoctrine database adapterr r }r (hUhj ubahhubaubhX , metadata keys can not contain r r }r (hX , metadata keys can not contain hj ubj/)r }r (hX``::``h}r (h]h]h]h]h]uhj h{]r hX::r r }r (hUhj ubahj7ubhX.r }r (hX.hj ubeubaubh)r }r (hX**Typical response codes:**r hj= hhhhh}r (h]h]h]h]h]uhMhhh{]r jN)r }r (hj h}r (h]h]h]h]h]uhj h{]r hXTypical response codes:r r }r (hUhj ubahjVubaubj)r }r (hUhj= hhhjh}r (jZX*h]h]h]h]h]uhMhhh{]r (j)r }r (hX200 OKr hj hhhj8h}r (h]h]h]h]h]uhNhhh{]r h)r }r (hj hj hhhhh}r (h]h]h]h]h]uhMh{]r hX200 OKr r }r (hj hj ubaubaubj)r }r (hX400 Bad requestr hj hhhj8h}r (h]h]h]h]h]uhNhhh{]r h)r }r (hj hj hhhhh}r (h]h]h]h]h]uhMh{]r hX400 Bad requestr r }r (hj hj ubaubaubj)r }r (hXr400 Invalid metadata (when using the :ref:`Doctrine ` adapter, and keys contain ``::``)r hj hhhj8h}r (h]h]h]h]h]uhNhhh{]r h)r }r (hj hj hhhhh}r (h]h]h]h]h]uhMh{]r (hX%400 Invalid metadata (when using the r r }r (hX%400 Invalid metadata (when using the hj ubh)r }r (hX+:ref:`Doctrine `r hj hhhhh}r (UreftypeXrefhƈhXdoctrine-database-adapterU refdomainXstdr h]h]U refexplicith]h]h]hhuhMh{]r h)r }r (hj h}r (h]h]r (hj Xstd-refr eh]h]h]uhj h{]r hXDoctriner r }r (hUhj ubahhubaubhX adapter, and keys contain r r }r (hX adapter, and keys contain hj ubj/)r }r (hX``::``h}r (h]h]h]h]h]uhj h{]r hX::r r }r (hUhj ubahj7ubhX)r }r (hX)hj ubeubaubj)r }r (hX404 Image not found hj hhhj8h}r (h]h]h]h]h]uhNhhh{]r h)r }r (hX404 Image not foundr hj hhhhh}r (h]h]h]h]h]uhMh{]r hX404 Image not foundr r }r (hj hj ubaubaubeubeubh})r }r (hUhj hhhhh}r (h]h]h]h]r hLah]r h auhMhhh{]r (h)r }r (hXPartially updating metadatar hj hhhhh}r (h]h]h]h]h]uhMhhh{]r hXPartially updating metadatar r }r (hj hj ubaubh)r }r (hXYPartial updates to metadata attached to an image is done by making a request with ``HTTP POST`` and attaching metadata to the request body as a JSON object. If the object contains keys that already exists in the metadata on the server the old values will be replaced by the ones found in the request body. New keys will be added to the metadata.r hj hhhhh}r (h]h]h]h]h]uhMhhh{]r (hXRPartial updates to metadata attached to an image is done by making a request with r r }r (hXRPartial updates to metadata attached to an image is done by making a request with hj ubj/)r }r (hX ``HTTP POST``h}r (h]h]h]h]h]uhj h{]r hX HTTP POSTr! r" }r# (hUhj ubahj7ubhX and attaching metadata to the request body as a JSON object. If the object contains keys that already exists in the metadata on the server the old values will be replaced by the ones found in the request body. New keys will be added to the metadata.r$ r% }r& (hX and attaching metadata to the request body as a JSON object. If the object contains keys that already exists in the metadata on the server the old values will be replaced by the ones found in the request body. New keys will be added to the metadata.hj ubeubj)r' }r( (hXmcurl -XPOST http://imbo/users//images//metadata.json -d '{ "ABV":"16%", "score":"100/100" }'hj hhhjh}r) (jjXbashjjh]h]h]h]h]uhMhhh{]r* hXmcurl -XPOST http://imbo/users//images//metadata.json -d '{ "ABV":"16%", "score":"100/100" }'r+ r, }r- (hUhj' ubaubh)r. }r/ (hX results in:r0 hj hhhhh}r1 (h]h]h]h]h]uhMhhh{]r2 hX results in:r3 r4 }r5 (hj0 hj. ubaubj)r6 }r7 (hX"{ "imageIdentifier": "" }hj hhhjh}r8 (jjX javascriptjjh]h]h]h]h]uhMhhh{]r9 hX"{ "imageIdentifier": "" }r: r; }r< (hUhj6 ubaubh)r= }r> (hX5where ```` is the image that just got updated.r? hj hhhhh}r@ (h]h]h]h]h]uhMhhh{]rA (hXwhere rB rC }rD (hXwhere hj= ubj/)rE }rF (hX ````h}rG (h]h]h]h]h]uhj= h{]rH hXrI rJ }rK (hUhjE ubahj7ubhX$ is the image that just got updated.rL rM }rN (hX$ is the image that just got updated.hj= ubeubjh)rO }rP (hXrWhen using the :ref:`Doctrine database adapter `, metadata keys can not contain ``::``.rQ hj hhhjlh}rR (h]h]h]h]h]uhNhhh{]rS h)rT }rU (hjQ hjO hhhhh}rV (h]h]h]h]h]uhMh{]rW (hXWhen using the rX rY }rZ (hXWhen using the hjT ubh)r[ }r\ (hX<:ref:`Doctrine database adapter `r] hjT hhhhh}r^ (UreftypeXrefhƈhXdoctrine-database-adapterU refdomainXstdr_ h]h]U refexplicith]h]h]hhuhMh{]r` h)ra }rb (hj] h}rc (h]h]rd (hj_ Xstd-refre eh]h]h]uhj[ h{]rf hXDoctrine database adapterrg rh }ri (hUhja ubahhubaubhX , metadata keys can not contain rj rk }rl (hX , metadata keys can not contain hjT ubj/)rm }rn (hX``::``h}ro (h]h]h]h]h]uhjT h{]rp hX::rq rr }rs (hUhjm ubahj7ubhX.rt }ru (hX.hjT ubeubaubh)rv }rw (hX**Typical response codes:**rx hj hhhhh}ry (h]h]h]h]h]uhMhhh{]rz jN)r{ }r| (hjx h}r} (h]h]h]h]h]uhjv h{]r~ hXTypical response codes:r r }r (hUhj{ ubahjVubaubj)r }r (hUhj hhhjh}r (jZX*h]h]h]h]h]uhMhhh{]r (j)r }r (hX200 OKr hj hhhj8h}r (h]h]h]h]h]uhNhhh{]r h)r }r (hj hj hhhhh}r (h]h]h]h]h]uhMh{]r hX200 OKr r }r (hj hj ubaubaubj)r }r (hX400 Bad requestr hj hhhj8h}r (h]h]h]h]h]uhNhhh{]r h)r }r (hj hj hhhhh}r (h]h]h]h]h]uhMh{]r hX400 Bad requestr r }r (hj hj ubaubaubj)r }r (hXr400 Invalid metadata (when using the :ref:`Doctrine ` adapter, and keys contain ``::``)r hj hhhj8h}r (h]h]h]h]h]uhNhhh{]r h)r }r (hj hj hhhhh}r (h]h]h]h]h]uhMh{]r (hX%400 Invalid metadata (when using the r r }r (hX%400 Invalid metadata (when using the hj ubh)r }r (hX+:ref:`Doctrine `r hj hhhhh}r (UreftypeXrefhƈhXdoctrine-database-adapterU refdomainXstdr h]h]U refexplicith]h]h]hhuhMh{]r h)r }r (hj h}r (h]h]r (hj Xstd-refr eh]h]h]uhj h{]r hXDoctriner r }r (hUhj ubahhubaubhX adapter, and keys contain r r }r (hX adapter, and keys contain hj ubj/)r }r (hX``::``h}r (h]h]h]h]h]uhj h{]r hX::r r }r (hUhj ubahj7ubhX)r }r (hX)hj ubeubaubj)r }r (hX404 Image not found hj hhhj8h}r (h]h]h]h]h]uhNhhh{]r h)r }r (hX404 Image not foundr hj hhhhh}r (h]h]h]h]h]uhMh{]r hX404 Image not foundr r }r (hj hj ubaubaubeubeubh})r }r (hUhj hhhhh}r (h]h]h]h]r hNah]r hauhM hhh{]r (h)r }r (hXFetch metadatar hj hhhhh}r (h]h]h]h]h]uhM hhh{]r hXFetch metadatar r }r (hj hj ubaubh)r }r (hXWRequests using ``HTTP GET`` on this resource returns all metadata attached to an image.r hj hhhhh}r (h]h]h]h]h]uhM hhh{]r (hXRequests using r r }r (hXRequests using hj ubj/)r }r (hX ``HTTP GET``h}r (h]h]h]h]h]uhj h{]r hXHTTP GETr r }r (hUhj ubahj7ubhX< on this resource returns all metadata attached to an image.r r }r (hX< on this resource returns all metadata attached to an image.hj ubeubj)r }r (hX:curl http://imbo/users//images//metadata.jsonhj hhhjh}r (jjXbashjjh]h]h]h]h]uhM hhh{]r hX:curl http://imbo/users//images//metadata.jsonr r }r (hUhj ubaubh)r }r (hX results in:r hj hhhhh}r (h]h]h]h]h]uhMhhh{]r hX results in:r r }r (hj hj ubaubj)r }r (hX{}hj hhhjh}r (jjX javascriptjjh]h]h]h]h]uhMhhh{]r hX{}r r }r (hUhj ubaubh)r }r (hX0when there is no metadata stored, or for exampler hj hhhhh}r (h]h]h]h]h]uhMhhh{]r hX0when there is no metadata stored, or for exampler r }r (hj hj ubaubj)r }r (hXa{ "category": "Music", "band": "Koldbrann", "genre": "Black metal", "country": "Norway" }hj hhhjh}r (jjX javascriptjjh]h]h]h]h]uhMhhh{]r hXa{ "category": "Music", "band": "Koldbrann", "genre": "Black metal", "country": "Norway" }r r }r (hUhj ubaubh)r }r (hX)if the image has metadata attached to it.r hj hhhhh}r (h]h]h]h]h]uhM"hhh{]r hX)if the image has metadata attached to it.r r }r (hj hj ubaubh)r }r (hX**Typical response codes:**r hj hhhhh}r! (h]h]h]h]h]uhM$hhh{]r" jN)r# }r$ (hj h}r% (h]h]h]h]h]uhj h{]r& hXTypical response codes:r' r( }r) (hUhj# ubahjVubaubj)r* }r+ (hUhj hhhjh}r, (jZX*h]h]h]h]h]uhM&hhh{]r- (j)r. }r/ (hX200 OKr0 hj* hhhj8h}r1 (h]h]h]h]h]uhNhhh{]r2 h)r3 }r4 (hj0 hj. hhhhh}r5 (h]h]h]h]h]uhM&h{]r6 hX200 OKr7 r8 }r9 (hj0 hj3 ubaubaubj)r: }r; (hX304 Not modifiedr< hj* hhhj8h}r= (h]h]h]h]h]uhNhhh{]r> h)r? }r@ (hj< hj: hhhhh}rA (h]h]h]h]h]uhM'h{]rB hX304 Not modifiedrC rD }rE (hj< hj? ubaubaubj)rF }rG (hX404 Image not found hj* hhhj8h}rH (h]h]h]h]h]uhNhhh{]rI h)rJ }rK (hX404 Image not foundrL hjF hhhhh}rM (h]h]h]h]h]uhM(h{]rN hX404 Image not foundrO rP }rQ (hjL hjJ ubaubaubeubeubh})rR }rS (hUhj hhhhh}rT (h]h]h]h]rU hqah]rV h2auhM+hhh{]rW (h)rX }rY (hXRemove metadatarZ hjR hhhhh}r[ (h]h]h]h]h]uhM+hhh{]r\ hXRemove metadatar] r^ }r_ (hjZ hjX ubaubh)r` }ra (hXTTo remove metadata attached to an image a request using ``HTTP DELETE`` can be made.rb hjR hhhhh}rc (h]h]h]h]h]uhM-hhh{]rd (hX8To remove metadata attached to an image a request using re rf }rg (hX8To remove metadata attached to an image a request using hj` ubj/)rh }ri (hX``HTTP DELETE``h}rj (h]h]h]h]h]uhj` h{]rk hX HTTP DELETErl rm }rn (hUhjh ubahj7ubhX can be made.ro rp }rq (hX can be made.hj` ubeubj)rr }rs (hXCcurl -XDELETE http://imbo/users//images//metadata.jsonhjR hhhjh}rt (jjXbashjjh]h]h]h]h]uhM/hhh{]ru hXCcurl -XDELETE http://imbo/users//images//metadata.jsonrv rw }rx (hUhjr ubaubh)ry }rz (hX results in:r{ hjR hhhhh}r| (h]h]h]h]h]uhM3hhh{]r} hX results in:r~ r }r (hj{ hjy ubaubj)r }r (hX!{ "imageIdentifier":"" }hjR hhhjh}r (jjX javascriptjjh]h]h]h]h]uhM5hhh{]r hX!{ "imageIdentifier":"" }r r }r (hUhj ubaubh)r }r (hX^where ```` is the image identifier of the image that just got all its metadata deleted.r hjR hhhhh}r (h]h]h]h]h]uhM;hhh{]r (hXwhere r r }r (hXwhere hj ubj/)r }r (hX ````h}r (h]h]h]h]h]uhj h{]r hXr r }r (hUhj ubahj7ubhXM is the image identifier of the image that just got all its metadata deleted.r r }r (hXM is the image identifier of the image that just got all its metadata deleted.hj ubeubh)r }r (hX**Typical response codes:**r hjR hhhhh}r (h]h]h]h]h]uhM=hhh{]r jN)r }r (hj h}r (h]h]h]h]h]uhj h{]r hXTypical response codes:r r }r (hUhj ubahjVubaubj)r }r (hUhjR hhhjh}r (jZX*h]h]h]h]h]uhM?hhh{]r (j)r }r (hX200 OKr hj hhhj8h}r (h]h]h]h]h]uhNhhh{]r h)r }r (hj hj hhhhh}r (h]h]h]h]h]uhM?h{]r hX200 OKr r }r (hj hj ubaubaubj)r }r (hX400 Bad requestr hj hhhj8h}r (h]h]h]h]h]uhNhhh{]r h)r }r (hj hj hhhhh}r (h]h]h]h]h]uhM@h{]r hX400 Bad requestr r }r (hj hj ubaubaubj)r }r (hX404 Image not found hj hhhj8h}r (h]h]h]h]h]uhNhhh{]r h)r }r (hX404 Image not foundr hj hhhhh}r (h]h]h]h]h]uhMAh{]r hX404 Image not foundr r }r (hj hj ubaubaubeubh)r }r (hX.. _access-tokens:hjR hhhhh}r (h]h]h]h]h]jhOuhMChhh{]ubeubeubeubh})r }r (hUhh~hhj}r hj shhh}r (h]h]h]h]r (hOhaeh]r (h"heuhMFhhj}r hOj sh{]r (h)r }r (hX Access tokensr hj hhhhh}r (h]h]h]h]h]uhMFhhh{]r hX Access tokensr r }r (hj hj ubaubh)r }r (hXAccess tokens are enforced by an event listener that is enabled in the default configuration file. The access tokens are used to prevent `DoS `_ attacks so think twice before you disable the event listener.r hj hhhhh}r (h]h]h]h]h]uhMHhhh{]r (hXAccess tokens are enforced by an event listener that is enabled in the default configuration file. The access tokens are used to prevent r r }r (hXAccess tokens are enforced by an event listener that is enabled in the default configuration file. The access tokens are used to prevent hj ubh)r }r (hX>`DoS `_h}r (UnameXDoShX5http://en.wikipedia.org/wiki/Denial-of-service_attackr h]h]h]h]h]uhj h{]r hXDoSr r }r (hUhj ubahhubh)r }r (hX8 hKhj hhh}r (Urefurij h]r hlah]h]h]h]r h-auh{]ubhX> attacks so think twice before you disable the event listener.r r }r (hX> attacks so think twice before you disable the event listener.hj ubeubh)r }r (hXAn access token, when enforced by the event listener, must be supplied in the URI using the ``accessToken`` query parameter and without it, most ``GET`` and ``HEAD`` requests will result in a ``400 Bad request`` response. The value of the ``accessToken`` parameter is a `Hash-based Message Authentication Code `_ (HMAC). The code is a `SHA-256 `_ hash of the URI itself using the private key of the user as the secret key. It is very important that the URI is **not** URL-encoded when generating the hash. Below is an example on how to generate a valid access token for a specific image using PHP:r hj hhhhh}r (h]h]h]h]h]uhMJhhh{]r (hX\An access token, when enforced by the event listener, must be supplied in the URI using the r r }r(hX\An access token, when enforced by the event listener, must be supplied in the URI using the hj ubj/)r}r(hX``accessToken``h}r(h]h]h]h]h]uhj h{]rhX accessTokenrr}r(hUhjubahj7ubhX& query parameter and without it, most rr }r (hX& query parameter and without it, most hj ubj/)r }r (hX``GET``h}r (h]h]h]h]h]uhj h{]rhXGETrr}r(hUhj ubahj7ubhX and rr}r(hX and hj ubj/)r}r(hX``HEAD``h}r(h]h]h]h]h]uhj h{]rhXHEADrr}r(hUhjubahj7ubhX requests will result in a rr}r(hX requests will result in a hj ubj/)r}r (hX``400 Bad request``h}r!(h]h]h]h]h]uhj h{]r"hX400 Bad requestr#r$}r%(hUhjubahj7ubhX response. The value of the r&r'}r((hX response. The value of the hj ubj/)r)}r*(hX``accessToken``h}r+(h]h]h]h]h]uhj h{]r,hX accessTokenr-r.}r/(hUhj)ubahj7ubhX parameter is a r0r1}r2(hX parameter is a hj ubh)r3}r4(hXM`Hash-based Message Authentication Code `_h}r5(UnameX&Hash-based Message Authentication CodehX!http://en.wikipedia.org/wiki/HMACr6h]h]h]h]h]uhj h{]r7hX&Hash-based Message Authentication Coder8r9}r:(hUhj3ubahhubh)r;}r<(hX$ hKhj hhh}r=(Urefurij6h]r>h[ah]h]h]h]r?hauh{]ubhX (HMAC). The code is a r@rA}rB(hX (HMAC). The code is a hj ubh)rC}rD(hX/`SHA-256 `_h}rE(UnameXSHA-256hX"http://en.wikipedia.org/wiki/SHA-2rFh]h]h]h]h]uhj h{]rGhXSHA-256rHrI}rJ(hUhjCubahhubh)rK}rL(hX% hKhj hhh}rM(UrefurijFh]rNhRah]h]h]h]rOhauh{]ubhXr hash of the URI itself using the private key of the user as the secret key. It is very important that the URI is rPrQ}rR(hXr hash of the URI itself using the private key of the user as the secret key. It is very important that the URI is hj ubjN)rS}rT(hX**not**h}rU(h]h]h]h]h]uhj h{]rVhXnotrWrX}rY(hUhjSubahjVubhX URL-encoded when generating the hash. Below is an example on how to generate a valid access token for a specific image using PHP:rZr[}r\(hX URL-encoded when generating the hash. Below is an example on how to generate a valid access token for a specific image using PHP:hj ubeubj)r]}r^(hX"; // The public key of the user $privateKey = ""; // The private key of the user $image = ""; // The image identifier // Image transformations $query = implode("&", array( "t[]=thumbnail:width=40,height=40,fit=outbound", "t[]=border:width=3,height=3,color=000", "t[]=canvas:width=100,height=100,mode=center" )); // The URI $uri = sprintf("http://imbo/users/%s/images/%s?%s", $publicKey, $image, $query); // Generate the token $accessToken = hash_hmac("sha256", $uri, $privateKey); // Output the URI with the access token echo sprintf("%s&accessToken=%s", $uri, $accessToken); hj hhhjh}r_(jjhXphpr`ra}rbbh]jjh]h]UsourceXQ/var/build/user_builds/imbo/checkouts/1.1.1/docs/examples/generateAccessToken.phph]h]uhMLhhh{]rchX"; // The public key of the user $privateKey = ""; // The private key of the user $image = ""; // The image identifier // Image transformations $query = implode("&", array( "t[]=thumbnail:width=40,height=40,fit=outbound", "t[]=border:width=3,height=3,color=000", "t[]=canvas:width=100,height=100,mode=center" )); // The URI $uri = sprintf("http://imbo/users/%s/images/%s?%s", $publicKey, $image, $query); // Generate the token $accessToken = hash_hmac("sha256", $uri, $privateKey); // Output the URI with the access token echo sprintf("%s&accessToken=%s", $uri, $accessToken); rdre}rf(hUhj]ubaubh)rg}rh(hX and Python:rihj hhhhh}rj(h]h]h]h]h]uhMPhhh{]rkhX and Python:rlrm}rn(hjihjgubaubj)ro}rp(hXfrom hashlib import sha256 import hmac publicKey = "" # The public key of the user privateKey = "" # The private key of the user image = "" # The image identifier # Image transformations query = "&".join([ "t[]=thumbnail:width=40,height=40,fit=outbound", "t[]=border:width=3,height=3,color=000", "t[]=canvas:width=100,height=100,mode=center" ]) # The URI uri = "http://imbo/users/%s/images/%s?%s" % (publicKey, image, query) # Generate the token accessToken = hmac.new(privateKey, uri, sha256) # Output the URI with the access token print "%s&accessToken=%s" % (uri, accessToken.hexdigest()) hj hhhjh}rq(jjhXpythonrrrs}rtbh]jjh]h]UsourceXP/var/build/user_builds/imbo/checkouts/1.1.1/docs/examples/generateAccessToken.pyh]h]uhMRhhh{]ruhXfrom hashlib import sha256 import hmac publicKey = "" # The public key of the user privateKey = "" # The private key of the user image = "" # The image identifier # Image transformations query = "&".join([ "t[]=thumbnail:width=40,height=40,fit=outbound", "t[]=border:width=3,height=3,color=000", "t[]=canvas:width=100,height=100,mode=center" ]) # The URI uri = "http://imbo/users/%s/images/%s?%s" % (publicKey, image, query) # Generate the token accessToken = hmac.new(privateKey, uri, sha256) # Output the URI with the access token print "%s&accessToken=%s" % (uri, accessToken.hexdigest()) rvrw}rx(hUhjoubaubh)ry}rz(hX and Ruby:r{hj hhhhh}r|(h]h]h]h]h]uhMVhhh{]r}hX and Ruby:r~r}r(hj{hjyubaubj)r}r(hXyrequire "digest" publicKey = "" # The public key of the user privateKey = "" # The private key of the user image = "" # The image identifier # Image transformations query = [ "t[]=thumbnail:width=40,height=40,fit=outbound", "t[]=border:width=3,height=3,color=000", "t[]=canvas:width=100,height=100,mode=center" ].join("&") # The URI uri = "http://imbo/users/#{publicKey}/images/#{image}?#{query}" # Generate the token accessToken = Digest::HMAC.hexdigest(uri, privateKey, Digest::SHA256) # Output the URI with the access token puts "#{uri}&accessToken=#{accessToken}" hj hhhjh}r(jjhXrubyrr}rbh]jjh]h]UsourceXP/var/build/user_builds/imbo/checkouts/1.1.1/docs/examples/generateAccessToken.rbh]h]uhMXhhh{]rhXyrequire "digest" publicKey = "" # The public key of the user privateKey = "" # The private key of the user image = "" # The image identifier # Image transformations query = [ "t[]=thumbnail:width=40,height=40,fit=outbound", "t[]=border:width=3,height=3,color=000", "t[]=canvas:width=100,height=100,mode=center" ].join("&") # The URI uri = "http://imbo/users/#{publicKey}/images/#{image}?#{query}" # Generate the token accessToken = Digest::HMAC.hexdigest(uri, privateKey, Digest::SHA256) # Output the URI with the access token puts "#{uri}&accessToken=#{accessToken}" rr}r(hUhjubaubh)r}r(hX2If the event listener enforcing the access token check is removed, Imbo will ignore the ``accessToken`` query parameter completely. If you wish to implement your own form of access token you can do this by implementing an event listener of your own (see :ref:`custom-event-listeners` for more information).rhj hhhhh}r(h]h]h]h]h]uhM\hhh{]r(hXXIf the event listener enforcing the access token check is removed, Imbo will ignore the rr}r(hXXIf the event listener enforcing the access token check is removed, Imbo will ignore the hjubj/)r}r(hX``accessToken``h}r(h]h]h]h]h]uhjh{]rhX accessTokenrr}r(hUhjubahj7ubhX query parameter completely. If you wish to implement your own form of access token you can do this by implementing an event listener of your own (see rr}r(hX query parameter completely. If you wish to implement your own form of access token you can do this by implementing an event listener of your own (see hjubh)r}r(hX:ref:`custom-event-listeners`rhjhhhhh}r(UreftypeXrefhƈhXcustom-event-listenersU refdomainXstdrh]h]U refexplicith]h]h]hhuhM\h{]rh)r}r(hjh}r(h]h]r(hjXstd-refreh]h]h]uhjh{]rhXcustom-event-listenersrr}r(hUhjubahhubaubhX for more information).rr}r(hX for more information).hjubeubh)r}r(hX.. _signing-write-requests:hj hhhhh}r(h]h]h]h]h]jhguhM^hhh{]ubeubh})r}r(hUhh~hhj}rh(jshhh}r(h]h]h]h]r(hghoeh]r(h0h(euhMahhj}rhgjsh{]r(h)r}r(hXSigning write requestsrhjhhhhh}r(h]h]h]h]h]uhMahhh{]rhXSigning write requestsrr}r(hjhjubaubh)r}r(hXTo be able to write to Imbo the user agent will have to specify two request headers: ``X-Imbo-Authenticate-Signature`` and ``X-Imbo-Authenticate-Timestamp``.rhjhhhhh}r(h]h]h]h]h]uhMchhh{]r(hXUTo be able to write to Imbo the user agent will have to specify two request headers: rr}r(hXUTo be able to write to Imbo the user agent will have to specify two request headers: hjubj/)r}r(hX!``X-Imbo-Authenticate-Signature``h}r(h]h]h]h]h]uhjh{]rhXX-Imbo-Authenticate-Signaturerr}r(hUhjubahj7ubhX and rr}r(hX and hjubj/)r}r(hX!``X-Imbo-Authenticate-Timestamp``h}r(h]h]h]h]h]uhjh{]rhXX-Imbo-Authenticate-Timestamprr}r(hUhjubahj7ubhX.r}r(hX.hjubeubh)r}r(hXz``X-Imbo-Authenticate-Signature`` is, like the access token, an HMAC (also using SHA-256 and the private key of the user).rhjhhhhh}r(h]h]h]h]h]uhMehhh{]r(j/)r}r(hX!``X-Imbo-Authenticate-Signature``h}r(h]h]h]h]h]uhjh{]rhXX-Imbo-Authenticate-Signaturerr}r(hUhjubahj7ubhXY is, like the access token, an HMAC (also using SHA-256 and the private key of the user).rr}r(hXY is, like the access token, an HMAC (also using SHA-256 and the private key of the user).hjubeubh)r}r(hX@The data for the hash is generated using the following elements:rhjhhhhh}r(h]h]h]h]h]uhMghhh{]rhX@The data for the hash is generated using the following elements:rr}r(hjhjubaubj)r}r(hUhjhhhjh}r(jZX*h]h]h]h]h]uhMihhh{]r(j)r}r(hX-HTTP method (``PUT``, ``POST`` or ``DELETE``)rhjhhhj8h}r(h]h]h]h]h]uhNhhh{]rh)r}r(hjhjhhhhh}r(h]h]h]h]h]uhMih{]r(hX HTTP method (rr}r(hX HTTP method (hjubj/)r}r(hX``PUT``h}r(h]h]h]h]h]uhjh{]rhXPUTrr }r (hUhjubahj7ubhX, r r }r (hX, hjubj/)r}r(hX``POST``h}r(h]h]h]h]h]uhjh{]rhXPOSTrr}r(hUhjubahj7ubhX or rr}r(hX or hjubj/)r}r(hX ``DELETE``h}r(h]h]h]h]h]uhjh{]rhXDELETErr}r(hUhjubahj7ubhX)r}r (hX)hjubeubaubj)r!}r"(hXThe URIr#hjhhhj8h}r$(h]h]h]h]h]uhNhhh{]r%h)r&}r'(hj#hj!hhhhh}r((h]h]h]h]h]uhMjh{]r)hXThe URIr*r+}r,(hj#hj&ubaubaubj)r-}r.(hXPublic key of the userr/hjhhhj8h}r0(h]h]h]h]h]uhNhhh{]r1h)r2}r3(hj/hj-hhhhh}r4(h]h]h]h]h]uhMkh{]r5hXPublic key of the userr6r7}r8(hj/hj2ubaubaubj)r9}r:(hXQGMT timestamp (``YYYY-MM-DDTHH:MM:SSZ``, for instance: ``2011-02-01T14:33:03Z``) hjhhhj8h}r;(h]h]h]h]h]uhNhhh{]r<h)r=}r>(hXPGMT timestamp (``YYYY-MM-DDTHH:MM:SSZ``, for instance: ``2011-02-01T14:33:03Z``)hj9hhhhh}r?(h]h]h]h]h]uhMlh{]r@(hXGMT timestamp (rArB}rC(hXGMT timestamp (hj=ubj/)rD}rE(hX``YYYY-MM-DDTHH:MM:SSZ``h}rF(h]h]h]h]h]uhj=h{]rGhXYYYY-MM-DDTHH:MM:SSZrHrI}rJ(hUhjDubahj7ubhX, for instance: rKrL}rM(hX, for instance: hj=ubj/)rN}rO(hX``2011-02-01T14:33:03Z``h}rP(h]h]h]h]h]uhj=h{]rQhX2011-02-01T14:33:03ZrRrS}rT(hUhjNubahj7ubhX)rU}rV(hX)hj=ubeubaubeubh)rW}rX(hXThese elements are concatenated in the above order with ``|`` as a delimiter character, and a hash is generated using the private key of the user. The following snippet shows how this can be accomplished in PHP when deleting an image:rYhjhhhhh}rZ(h]h]h]h]h]uhMnhhh{]r[(hX8These elements are concatenated in the above order with r\r]}r^(hX8These elements are concatenated in the above order with hjWubj/)r_}r`(hX``|``h}ra(h]h]h]h]h]uhjWh{]rbhX|rc}rd(hUhj_ubahj7ubhX as a delimiter character, and a hash is generated using the private key of the user. The following snippet shows how this can be accomplished in PHP when deleting an image:rerf}rg(hX as a delimiter character, and a hash is generated using the private key of the user. The following snippet shows how this can be accomplished in PHP when deleting an image:hjWubeubj)rh}ri(hX"; // The public key of the user $privateKey = ""; // The private key of the user $timestamp = gmdate("Y-m-d\TH:i:s\Z"); // Current timestamp (UTC) $image = ""; // The image identifier $method = "DELETE"; // HTTP method to use // The URI $uri = sprintf("http://imbo/users/%s/images/%s", $publicKey, $image); // Data for the hash $data = implode("|", array($method, $uri, $publicKey, $timestamp)); // Generate the token $signature = hash_hmac("sha256", $data, $privateKey); // Request the URI $response = file_get_contents($uri, false, stream_context_create(array( "http" => array( "method" => $method, "header" => array( "X-Imbo-Authenticate-Signature: " . $signature, "X-Imbo-Authenticate-Timestamp: " . $timestamp, ), ), ))); hjhhhjh}rj(jjhXphprkrl}rmbh]jjh]h]UsourceXX/var/build/user_builds/imbo/checkouts/1.1.1/docs/examples/generateSignatureForDelete.phph]h]uhMphhh{]rnhX"; // The public key of the user $privateKey = ""; // The private key of the user $timestamp = gmdate("Y-m-d\TH:i:s\Z"); // Current timestamp (UTC) $image = ""; // The image identifier $method = "DELETE"; // HTTP method to use // The URI $uri = sprintf("http://imbo/users/%s/images/%s", $publicKey, $image); // Data for the hash $data = implode("|", array($method, $uri, $publicKey, $timestamp)); // Generate the token $signature = hash_hmac("sha256", $data, $privateKey); // Request the URI $response = file_get_contents($uri, false, stream_context_create(array( "http" => array( "method" => $method, "header" => array( "X-Imbo-Authenticate-Signature: " . $signature, "X-Imbo-Authenticate-Timestamp: " . $timestamp, ), ), ))); rorp}rq(hUhjhubaubh)rr}rs(hXMand Python (using the `Requests `_ library):rthjhhhhh}ru(h]h]h]h]h]uhMthhh{]rv(hXand Python (using the rwrx}ry(hXand Python (using the hjrubh)rz}r{(hX-`Requests `_h}r|(UnameXRequestshXhttp://docs.python-requests.orgr}h]h]h]h]h]uhjrh{]r~hXRequestsrr}r(hUhjzubahhubh)r}r(hX" hKhjrhhh}r(Urefurij}h]rhxah]h]h]h]rh9auh{]ubhX library):rr}r(hX library):hjrubeubj)r}r(hXimport hmac, requests from hashlib import sha256 from datetime import datetime publicKey = "" # The public key of the user privateKey = "" # The private key of the user timestamp = datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ") # Current timestamp (UTC) image = "" # The image identifier method = "DELETE" # HTTP method to use # The URI uri = "http://imbo/users/%s/images/%s" % (publicKey, image) # Data for the hash data = "|".join([method, uri, publicKey, timestamp]) # Generate the token signature = hmac.new(privateKey, data, sha256).hexdigest() # Request the URI response = requests.delete(uri, headers = { "X-Imbo-Authenticate-Signature": signature, "X-Imbo-Authenticate-Timestamp": timestamp }) hjhhhjh}r(jjhXpythonrr}rbh]jjh]h]UsourceXW/var/build/user_builds/imbo/checkouts/1.1.1/docs/examples/generateSignatureForDelete.pyh]h]uhMvhhh{]rhXimport hmac, requests from hashlib import sha256 from datetime import datetime publicKey = "" # The public key of the user privateKey = "" # The private key of the user timestamp = datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ") # Current timestamp (UTC) image = "" # The image identifier method = "DELETE" # HTTP method to use # The URI uri = "http://imbo/users/%s/images/%s" % (publicKey, image) # Data for the hash data = "|".join([method, uri, publicKey, timestamp]) # Generate the token signature = hmac.new(privateKey, data, sha256).hexdigest() # Request the URI response = requests.delete(uri, headers = { "X-Imbo-Authenticate-Signature": signature, "X-Imbo-Authenticate-Timestamp": timestamp }) rr}r(hUhjubaubh)r}r(hXNand Ruby (using the `httpclient `_ gem):rhjhhhhh}r(h]h]h]h]h]uhMzhhh{]r(hXand Ruby (using the rr}r(hXand Ruby (using the hjubh)r}r(hX4`httpclient `_h}r(Unameh#hX$https://rubygems.org/gems/httpclientrh]h]h]h]h]uhjh{]rhX httpclientrr}r(hUhjubahhubh)r}r(hX' hKhjhhh}r(Urefurijh]rhbah]h]h]h]rh#auh{]ubhX gem):rr}r(hX gem):hjubeubj)r}r(hXarequire "digest" require "httpclient" publicKey = "" # The public key of the user privateKey = "" # The private key of the user timestamp = Time.now.utc.strftime("%Y-%m-%dT%H:%M:%SZ") # Current timestamp (UTC) image = "" # The image identifier method = "DELETE" # HTTP method to use # The URI uri = "http://imbo/users/#{publicKey}/images/#{image}" # Data for the hash data = [method, uri, publicKey, timestamp].join("|") # Generate the token signature = Digest::HMAC.hexdigest(data, privateKey, Digest::SHA256) # Request the URI client = HTTPClient.new response = client.delete(uri, {}, { "X-Imbo-Authenticate-Signature" => signature, "X-Imbo-Authenticate-Timestamp" => timestamp }) hjhhhjh}r(jjhXrubyrr}rbh]jjh]h]UsourceXW/var/build/user_builds/imbo/checkouts/1.1.1/docs/examples/generateSignatureForDelete.rbh]h]uhM|hhh{]rhXarequire "digest" require "httpclient" publicKey = "" # The public key of the user privateKey = "" # The private key of the user timestamp = Time.now.utc.strftime("%Y-%m-%dT%H:%M:%SZ") # Current timestamp (UTC) image = "" # The image identifier method = "DELETE" # HTTP method to use # The URI uri = "http://imbo/users/#{publicKey}/images/#{image}" # Data for the hash data = [method, uri, publicKey, timestamp].join("|") # Generate the token signature = Digest::HMAC.hexdigest(data, privateKey, Digest::SHA256) # Request the URI client = HTTPClient.new response = client.delete(uri, {}, { "X-Imbo-Authenticate-Signature" => signature, "X-Imbo-Authenticate-Timestamp" => timestamp }) rr}r(hUhjubaubh)r}r(hXpImbo requires that ``X-Imbo-Authenticate-Timestamp`` is within ± 120 seconds of the current time on the server.rhjhhhhh}r(h]h]h]h]h]uhMhhh{]r(hXImbo requires that rr}r(hXImbo requires that hjubj/)r}r(hX!``X-Imbo-Authenticate-Timestamp``h}r(h]h]h]h]h]uhjh{]rhXX-Imbo-Authenticate-Timestamprr}r(hUhjubahj7ubhX< is within ± 120 seconds of the current time on the server.rr}r(hX< is within ± 120 seconds of the current time on the server.hjubeubh)r}r(hXAs with the access token the signature check is enforced by an event listener that can also be disabled. If you disable this event listener you effectively open up for writing from anybody, which you probably don't want to do.rhjhhhhh}r(h]h]h]h]h]uhMhhh{]rhXAs with the access token the signature check is enforced by an event listener that can also be disabled. If you disable this event listener you effectively open up for writing from anybody, which you probably don't want to do.rr}r(hjhjubaubh)r}r(hXnIf you want to implement your own authentication paradigm you can do this by creating a custom event listener.rhjhhhhh}r(h]h]h]h]h]uhMhhh{]rhXnIf you want to implement your own authentication paradigm you can do this by creating a custom event listener.rr}r(hjhjubaubeubh})r}r(hUhh~hhhhh}r(h]h]h]h]rhJah]rh auhMhhh{]r(h)r}r(hXSupported content typesrhjhhhhh}r(h]h]h]h]h]uhMhhh{]rhXSupported content typesrr}r(hjhjubaubh)r}r(hXImbo currently responds with images (jpg, gif and png), `JSON `_ and `XML `_, but only accepts images (jpg, gif and png) and JSON as input.rhjhhhhh}r(h]h]h]h]h]uhMhhh{]r(hX8Imbo currently responds with images (jpg, gif and png), rr}r(hX8Imbo currently responds with images (jpg, gif and png), hjubh)r}r(hX+`JSON `_h}r(UnameXJSONhX!http://en.wikipedia.org/wiki/JSONrh]h]h]h]h]uhjh{]rhXJSONrr}r(hUhjubahhubh)r}r(hX$ hKhjhhh}r(Urefurijh]rh\ah]h]h]h]rhauh{]ubhX and rr}r(hX and hjubh)r}r(hX)`XML `_h}r(UnameXXMLhX http://en.wikipedia.org/wiki/XMLrh]h]h]h]h]uhjh{]rhXXMLrr}r(hUhjubahhubh)r}r(hX# hKhjhhh}r(Urefurijh]r hSah]h]h]h]r hauh{]ubhX?, but only accepts images (jpg, gif and png) and JSON as input.r r }r (hX?, but only accepts images (jpg, gif and png) and JSON as input.hjubeubh)r}r(hX Imbo will do content negotiation using the `Accept `_ header found in the request, unless you specify a file extension, in which case Imbo will deliver the type requested without looking at the ``Accept`` header.rhjhhhhh}r(h]h]h]h]h]uhMhhh{]r(hX+Imbo will do content negotiation using the rr}r(hX+Imbo will do content negotiation using the hjubh)r}r(hXB`Accept `_h}r(UnameXAccepthX6http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.htmlrh]h]h]h]h]uhjh{]rhXAcceptrr}r(hUhjubahhubh)r}r(hX9 hKhjhhh}r (Urefurijh]r!hIah]h]h]h]r"h auh{]ubhX header found in the request, unless you specify a file extension, in which case Imbo will deliver the type requested without looking at the r#r$}r%(hX header found in the request, unless you specify a file extension, in which case Imbo will deliver the type requested without looking at the hjubj/)r&}r'(hX ``Accept``h}r((h]h]h]h]h]uhjh{]r)hXAcceptr*r+}r,(hUhj&ubahj7ubhX header.r-r.}r/(hX header.hjubeubh)r0}r1(hX The default content type for non-image responses is JSON. Examples in this chapter uses the ``.json`` extension. Change it to ``.xml`` to get the XML representation instead. You can also skip the extension and force a specific content type using the ``Accept`` header:r2hjhhhhh}r3(h]h]h]h]h]uhMhhh{]r4(hX\The default content type for non-image responses is JSON. Examples in this chapter uses the r5r6}r7(hX\The default content type for non-image responses is JSON. Examples in this chapter uses the hj0ubj/)r8}r9(hX ``.json``h}r:(h]h]h]h]h]uhj0h{]r;hX.jsonr<r=}r>(hUhj8ubahj7ubhX extension. Change it to r?r@}rA(hX extension. Change it to hj0ubj/)rB}rC(hX``.xml``h}rD(h]h]h]h]h]uhj0h{]rEhX.xmlrFrG}rH(hUhjBubahj7ubhXt to get the XML representation instead. You can also skip the extension and force a specific content type using the rIrJ}rK(hXt to get the XML representation instead. You can also skip the extension and force a specific content type using the hj0ubj/)rL}rM(hX ``Accept``h}rN(h]h]h]h]h]uhj0h{]rOhXAcceptrPrQ}rR(hUhjLubahj7ubhX header:rSrT}rU(hX header:hj0ubeubj)rV}rW(hXcurl http://imbo/status.jsonhjhhhjh}rX(jjXbashjjh]h]h]h]h]uhMhhh{]rYhXcurl http://imbo/status.jsonrZr[}r\(hUhjVubaubh)r]}r^(hXandr_hjhhhhh}r`(h]h]h]h]h]uhMhhh{]rahXandrbrc}rd(hj_hj]ubaubj)re}rf(hX5curl -H "Accept: application/json" http://imbo/statushjhhhjh}rg(jjXbashjjh]h]h]h]h]uhMhhh{]rhhX5curl -H "Accept: application/json" http://imbo/statusrirj}rk(hUhjeubaubh)rl}rm(hXHwill end up with the same content type. Use ``application/xml`` for XML.rnhjhhhhh}ro(h]h]h]h]h]uhMhhh{]rp(hX,will end up with the same content type. Use rqrr}rs(hX,will end up with the same content type. Use hjlubj/)rt}ru(hX``application/xml``h}rv(h]h]h]h]h]uhjlh{]rwhXapplication/xmlrxry}rz(hUhjtubahj7ubhX for XML.r{r|}r}(hX for XML.hjlubeubh)r~}r(hXIf you use JSON you can wrap the content in a function (`JSONP `_) by using one of the following query parameters:rhjhhhhh}r(h]h]h]h]h]uhMhhh{]r(hX8If you use JSON you can wrap the content in a function (rr}r(hX8If you use JSON you can wrap the content in a function (hj~ubh)r}r(hX-`JSONP `_h}r(UnameXJSONPhX"http://en.wikipedia.org/wiki/JSONPrh]h]h]h]h]uhj~h{]rhXJSONPrr}r(hUhjubahhubh)r}r(hX% hKhj~hhh}r(Urefurijh]rh`ah]h]h]h]rh!auh{]ubhX1) by using one of the following query parameters:rr}r(hX1) by using one of the following query parameters:hj~ubeubj)r}r(hUhjhhhjh}r(jZX*h]h]h]h]h]uhMhhh{]r(j)r}r(hX ``callback``rhjhhhj8h}r(h]h]h]h]h]uhNhhh{]rh)r}r(hjhjhhhhh}r(h]h]h]h]h]uhMh{]rj/)r}r(hjh}r(h]h]h]h]h]uhjh{]rhXcallbackrr}r(hUhjubahj7ubaubaubj)r}r(hX ``jsonp``rhjhhhj8h}r(h]h]h]h]h]uhNhhh{]rh)r}r(hjhjhhhhh}r(h]h]h]h]h]uhMh{]rj/)r}r(hjh}r(h]h]h]h]h]uhjh{]rhXjsonprr}r(hUhjubahj7ubaubaubj)r}r(hX ``json`` hjhhhj8h}r(h]h]h]h]h]uhNhhh{]rh)r}r(hX``json``rhjhhhhh}r(h]h]h]h]h]uhMh{]rj/)r}r(hjh}r(h]h]h]h]h]uhjh{]rhXjsonrr}r(hUhjubahj7ubaubaubeubj)r}r(hX*curl http://imbo/status.json?callback=funchjhhhjh}r(jjXbashjjh]h]h]h]h]uhMhhh{]rhX*curl http://imbo/status.json?callback=funcrr}r(hUhjubaubh)r}r(hXwill result in:rhjhhhhh}r(h]h]h]h]h]uhMhhh{]rhXwill result in:rr}r(hjhjubaubj)r}r(hXffunc( { "date": "Mon, 05 Nov 2012 19:18:40 GMT", "database": true, "storage": true } )hjhhhjh}r(jjX javascriptjjh]h]h]h]h]uhMhhh{]rhXffunc( { "date": "Mon, 05 Nov 2012 19:18:40 GMT", "database": true, "storage": true } )rr}r(hUhjubaubh)r}r(hX|For images the default mime-type is the original mime-type of the image. If you add an ``image/gif`` image and fetch that image with ``Accept: */*`` or ``Accept: image/*`` the mime-type of the image returned will be ``image/gif``. To choose a different mime type either change the ``Accept`` header, or use ``.jpg`` or ``.png`` (for ``image/jpeg`` and ``image/png`` respectively).rhjhhhhh}r(h]h]h]h]h]uhMhhh{]r(hXWFor images the default mime-type is the original mime-type of the image. If you add an rr}r(hXWFor images the default mime-type is the original mime-type of the image. If you add an hjubj/)r}r(hX ``image/gif``h}r(h]h]h]h]h]uhjh{]rhX image/gifrr}r(hUhjubahj7ubhX! image and fetch that image with rr}r(hX! image and fetch that image with hjubj/)r}r(hX``Accept: */*``h}r(h]h]h]h]h]uhjh{]rhX Accept: */*rr}r(hUhjubahj7ubhX or rr}r(hX or hjubj/)r}r(hX``Accept: image/*``h}r(h]h]h]h]h]uhjh{]rhXAccept: image/*rr}r(hUhjubahj7ubhX- the mime-type of the image returned will be rr}r(hX- the mime-type of the image returned will be hjubj/)r}r(hX ``image/gif``h}r(h]h]h]h]h]uhjh{]r hX image/gifr r }r (hUhjubahj7ubhX4. To choose a different mime type either change the r r}r(hX4. To choose a different mime type either change the hjubj/)r}r(hX ``Accept``h}r(h]h]h]h]h]uhjh{]rhXAcceptrr}r(hUhjubahj7ubhX header, or use rr}r(hX header, or use hjubj/)r}r(hX``.jpg``h}r(h]h]h]h]h]uhjh{]rhX.jpgrr}r (hUhjubahj7ubhX or r!r"}r#(hX or hjubj/)r$}r%(hX``.png``h}r&(h]h]h]h]h]uhjh{]r'hX.pngr(r)}r*(hUhj$ubahj7ubhX (for r+r,}r-(hX (for hjubj/)r.}r/(hX``image/jpeg``h}r0(h]h]h]h]h]uhjh{]r1hX image/jpegr2r3}r4(hUhj.ubahj7ubhX and r5r6}r7(hX and hjubj/)r8}r9(hX ``image/png``h}r:(h]h]h]h]h]uhjh{]r;hX image/pngr<r=}r>(hUhj8ubahj7ubhX respectively).r?r@}rA(hX respectively).hjubeubeubh})rB}rC(hUhh~hhhhh}rD(h]h]h]h]rEhTah]rFhauhMhhh{]rG(h)rH}rI(hX Cache headersrJhjBhhhhh}rK(h]h]h]h]h]uhMhhh{]rLhX Cache headersrMrN}rO(hjJhjHubaubh)rP}rQ(hX}Most responses from Imbo includes a set of cache-related headers that enables shared caches and user agents to cache content.rRhjBhhhhh}rS(h]h]h]h]h]uhMhhh{]rThX}Most responses from Imbo includes a set of cache-related headers that enables shared caches and user agents to cache content.rUrV}rW(hjRhjPubaubh})rX}rY(hUhjBhhhhh}rZ(h]h]h]h]r[h^ah]r\hauhMhhh{]r](h)r^}r_(hX Cache-Controlr`hjXhhhhh}ra(h]h]h]h]h]uhMhhh{]rbhX Cache-Controlrcrd}re(hj`hj^ubaubh)rf}rg(hXSome responses from Imbo are not cache-able. These will typically include ``Cache-Control: max-age=0, no-store, private``. The following resources are not cache-able:rhhjXhhhhh}ri(h]h]h]h]h]uhMhhh{]rj(hXJSome responses from Imbo are not cache-able. These will typically include rkrl}rm(hXJSome responses from Imbo are not cache-able. These will typically include hjfubj/)rn}ro(hX/``Cache-Control: max-age=0, no-store, private``h}rp(h]h]h]h]h]uhjfh{]rqhX+Cache-Control: max-age=0, no-store, privaterrrs}rt(hUhjnubahj7ubhX-. The following resources are not cache-able:rurv}rw(hX-. The following resources are not cache-able:hjfubeubj)rx}ry(hUhjXhhhjh}rz(jZX*h]h]h]h]h]uhMhhh{]r{(j)r|}r}(hX:ref:`index-resource`r~hjxhhhj8h}r(h]h]h]h]h]uhNhhh{]rh)r}r(hj~hj|hhhhh}r(h]h]h]h]h]uhMh{]rh)r}r(hj~hjhhhhh}r(UreftypeXrefhƈhXindex-resourceU refdomainXstdrh]h]U refexplicith]h]h]hhuhMh{]rh)r}r(hj~h}r(h]h]r(hjXstd-refreh]h]h]uhjh{]rhXindex-resourcerr}r(hUhjubahhubaubaubaubj)r}r(hX:ref:`stats-resource`rhjxhhhj8h}r(h]h]h]h]h]uhNhhh{]rh)r}r(hjhjhhhhh}r(h]h]h]h]h]uhMh{]rh)r}r(hjhjhhhhh}r(UreftypeXrefhƈhXstats-resourceU refdomainXstdrh]h]U refexplicith]h]h]hhuhMh{]rh)r}r(hjh}r(h]h]r(hjXstd-refreh]h]h]uhjh{]rhXstats-resourcerr}r(hUhjubahhubaubaubaubj)r}r(hX:ref:`status-resource` hjxhhhj8h}r(h]h]h]h]h]uhNhhh{]rh)r}r(hX:ref:`status-resource`rhjhhhhh}r(h]h]h]h]h]uhMh{]rh)r}r(hjhjhhhhh}r(UreftypeXrefhƈhXstatus-resourceU refdomainXstdrh]h]U refexplicith]h]h]hhuhMh{]rh)r}r(hjh}r(h]h]r(hjXstd-refreh]h]h]uhjh{]rhXstatus-resourcerr}r(hUhjubahhubaubaubaubeubh)r}r(hXAll other resources will include ``Cache-Control: public``. The :ref:`image ` and :ref:`short url ` resources will also set a ``max-age``, resulting in the following header: ``Cache-Control: max-age=31536000, public``.rhjXhhhhh}r(h]h]h]h]h]uhMhhh{]r(hX!All other resources will include rr}r(hX!All other resources will include hjubj/)r}r(hX``Cache-Control: public``h}r(h]h]h]h]h]uhjh{]rhXCache-Control: publicrr}r(hUhjubahj7ubhX. The rr}r(hX. The hjubh)r}r(hX:ref:`image `rhjhhhhh}r(UreftypeXrefhƈhXimage-resourceU refdomainXstdrh]h]U refexplicith]h]h]hhuhMh{]rh)r}r(hjh}r(h]h]r(hjXstd-refreh]h]h]uhjh{]rhXimagerr}r(hUhjubahhubaubhX and rr}r(hX and hjubh)r}r(hX$:ref:`short url `rhjhhhhh}r(UreftypeXrefhƈhXshorturl-resourceU refdomainXstdrh]h]U refexplicith]h]h]hhuhMh{]rh)r}r(hjh}r(h]h]r(hjXstd-refreh]h]h]uhjh{]rhX short urlrr}r(hUhjubahhubaubhX resources will also set a rr}r(hX resources will also set a hjubj/)r}r(hX ``max-age``h}r(h]h]h]h]h]uhjh{]rhXmax-agerr}r(hUhjubahj7ubhX%, resulting in the following header: rr}r(hX%, resulting in the following header: hjubj/)r}r(hX+``Cache-Control: max-age=31536000, public``h}r(h]h]h]h]h]uhjh{]rhX'Cache-Control: max-age=31536000, publicrr}r(hUhjubahj7ubhX.r}r (hX.hjubeubeubh})r }r (hUhjBhhhhh}r (h]h]h]h]r hrah]rh3auhMhhh{]r(h)r}r(hXETagrhj hhhhh}r(h]h]h]h]h]uhMhhh{]rhXETagrr}r(hjhjubaubh)r}r(hXImbo provides `entity tags `_ for cache validation mechanisms. User agents can use the ``ETag`` response header to do conditional requests further down the road (by specifying the original ``ETag`` value in the ``If-None-Match`` request header). This results in saved bandwidth as web caches and Imbo servers no longer need to send the response body, as the one cached by the user agent can be re-used. This is achieved by sending ``304 Not Modified`` back to the user agent, instead of ``200 OK``.rhj hhhhh}r(h]h]h]h]h]uhMhhh{]r(hXImbo provides rr}r(hXImbo provides hjubh)r }r!(hX7`entity tags `_h}r"(UnameX entity tagshX&http://en.wikipedia.org/wiki/HTTP_ETagr#h]h]h]h]h]uhjh{]r$hX entity tagsr%r&}r'(hUhj ubahhubh)r(}r)(hX) hKhjhhh}r*(Urefurij#h]r+hnah]h]h]h]r,h/auh{]ubhX: for cache validation mechanisms. User agents can use the r-r.}r/(hX: for cache validation mechanisms. User agents can use the hjubj/)r0}r1(hX``ETag``h}r2(h]h]h]h]h]uhjh{]r3hXETagr4r5}r6(hUhj0ubahj7ubhX^ response header to do conditional requests further down the road (by specifying the original r7r8}r9(hX^ response header to do conditional requests further down the road (by specifying the original hjubj/)r:}r;(hX``ETag``h}r<(h]h]h]h]h]uhjh{]r=hXETagr>r?}r@(hUhj:ubahj7ubhX value in the rArB}rC(hX value in the hjubj/)rD}rE(hX``If-None-Match``h}rF(h]h]h]h]h]uhjh{]rGhX If-None-MatchrHrI}rJ(hUhjDubahj7ubhX request header). This results in saved bandwidth as web caches and Imbo servers no longer need to send the response body, as the one cached by the user agent can be re-used. This is achieved by sending rKrL}rM(hX request header). This results in saved bandwidth as web caches and Imbo servers no longer need to send the response body, as the one cached by the user agent can be re-used. This is achieved by sending hjubj/)rN}rO(hX``304 Not Modified``h}rP(h]h]h]h]h]uhjh{]rQhX304 Not ModifiedrRrS}rT(hUhjNubahj7ubhX$ back to the user agent, instead of rUrV}rW(hX$ back to the user agent, instead of hjubj/)rX}rY(hX ``200 OK``h}rZ(h]h]h]h]h]uhjh{]r[hX200 OKr\r]}r^(hUhjXubahj7ubhX.r_}r`(hX.hjubeubh)ra}rb(hX5The following resources in Imbo will include an ETag:rchj hhhhh}rd(h]h]h]h]h]uhMhhh{]rehX5The following resources in Imbo will include an ETag:rfrg}rh(hjchjaubaubj)ri}rj(hUhj hhhjh}rk(jZX*h]h]h]h]h]uhMhhh{]rl(j)rm}rn(hX:ref:`user-resource`rohjihhhj8h}rp(h]h]h]h]h]uhNhhh{]rqh)rr}rs(hjohjmhhhhh}rt(h]h]h]h]h]uhMh{]ruh)rv}rw(hjohjrhhhhh}rx(UreftypeXrefhƈhX user-resourceU refdomainXstdryh]h]U refexplicith]h]h]hhuhMh{]rzh)r{}r|(hjoh}r}(h]h]r~(hjyXstd-refreh]h]h]uhjvh{]rhX user-resourcerr}r(hUhj{ubahhubaubaubaubj)r}r(hX:ref:`images-resource`rhjihhhj8h}r(h]h]h]h]h]uhNhhh{]rh)r}r(hjhjhhhhh}r(h]h]h]h]h]uhMh{]rh)r}r(hjhjhhhhh}r(UreftypeXrefhƈhXimages-resourceU refdomainXstdrh]h]U refexplicith]h]h]hhuhMh{]rh)r}r(hjh}r(h]h]r(hjXstd-refreh]h]h]uhjh{]rhXimages-resourcerr}r(hUhjubahhubaubaubaubj)r}r(hX:ref:`image-resource`rhjihhhj8h}r(h]h]h]h]h]uhNhhh{]rh)r}r(hjhjhhhhh}r(h]h]h]h]h]uhMh{]rh)r}r(hjhjhhhhh}r(UreftypeXrefhƈhXimage-resourceU refdomainXstdrh]h]U refexplicith]h]h]hhuhMh{]rh)r}r(hjh}r(h]h]r(hjXstd-refreh]h]h]uhjh{]rhXimage-resourcerr}r(hUhjubahhubaubaubaubj)r}r(hX:ref:`metadata-resource`rhjihhhj8h}r(h]h]h]h]h]uhNhhh{]rh)r}r(hjhjhhhhh}r(h]h]h]h]h]uhMh{]rh)r}r(hjhjhhhhh}r(UreftypeXrefhƈhXmetadata-resourceU refdomainXstdrh]h]U refexplicith]h]h]hhuhMh{]rh)r}r(hjh}r(h]h]r(hjXstd-refreh]h]h]uhjh{]rhXmetadata-resourcerr}r(hUhjubahhubaubaubaubj)r}r(hX:ref:`shorturl-resource` hjihhhj8h}r(h]h]h]h]h]uhNhhh{]rh)r}r(hX:ref:`shorturl-resource`rhjhhhhh}r(h]h]h]h]h]uhMh{]rh)r}r(hjhjhhhhh}r(UreftypeXrefhƈhXshorturl-resourceU refdomainXstdrh]h]U refexplicith]h]h]hhuhMh{]rh)r}r(hjh}r(h]h]r(hjXstd-refreh]h]h]uhjh{]rhXshorturl-resourcerr}r(hUhjubahhubaubaubaubeubh)r}r(hXThe value of the ``ETag`` header is simply the MD5 sum of the content in the response body, enclosed in quotes. For instance ``ETag: "fd2fd87a2f5288be31c289e70e916123"``.rhj hhhhh}r(h]h]h]h]h]uhMhhh{]r(hXThe value of the rr}r(hXThe value of the hjubj/)r}r(hX``ETag``h}r(h]h]h]h]h]uhjh{]rhXETagrr}r(hUhjubahj7ubhXd header is simply the MD5 sum of the content in the response body, enclosed in quotes. For instance rr}r(hXd header is simply the MD5 sum of the content in the response body, enclosed in quotes. For instance hjubj/)r}r(hX,``ETag: "fd2fd87a2f5288be31c289e70e916123"``h}r(h]h]h]h]h]uhjh{]rhX(ETag: "fd2fd87a2f5288be31c289e70e916123"rr}r(hUhjubahj7ubhX.r}r(hX.hjubeubeubh})r}r(hUhjBhhhhh}r(h]h]h]h]rh_ah]rh auhMhhh{]r(h)r}r(hX Last-Modifiedrhjhhhhh}r(h]h]h]h]h]uhMhhh{]rhX Last-Modifiedrr}r(hjhjubaubh)r }r (hXImbo also includes a ``Last-Modified`` response header for resources that has a know last modification date, and these resources are:r hjhhhhh}r (h]h]h]h]h]uhMhhh{]r (hXImbo also includes a rr}r(hXImbo also includes a hj ubj/)r}r(hX``Last-Modified``h}r(h]h]h]h]h]uhj h{]rhX Last-Modifiedrr}r(hUhjubahj7ubhX_ response header for resources that has a know last modification date, and these resources are:rr}r(hX_ response header for resources that has a know last modification date, and these resources are:hj ubeubj)r}r(hUhjhhhjh}r(jZX*h]h]h]h]h]uhMhhh{]r(j)r}r (hX:ref:`user-resource`: The date of when the user last added or deleted an image, or manipulated the metadata of an image. If the user don't have any images yet, the value of this date will be the current timestamp.r!hjhhhj8h}r"(h]h]h]h]h]uhNhhh{]r#h)r$}r%(hj!hjhhhhh}r&(h]h]h]h]h]uhMh{]r'(h)r(}r)(hX:ref:`user-resource`r*hj$hhhhh}r+(UreftypeXrefhƈhX user-resourceU refdomainXstdr,h]h]U refexplicith]h]h]hhuhMh{]r-h)r.}r/(hj*h}r0(h]h]r1(hj,Xstd-refr2eh]h]h]uhj(h{]r3hX user-resourcer4r5}r6(hUhj.ubahhubaubhX: The date of when the user last added or deleted an image, or manipulated the metadata of an image. If the user don't have any images yet, the value of this date will be the current timestamp.r7r8}r9(hX: The date of when the user last added or deleted an image, or manipulated the metadata of an image. If the user don't have any images yet, the value of this date will be the current timestamp.hj$ubeubaubj)r:}r;(hX:ref:`images-resource`: The date of when the user last modified an image in the collection (either the image itself, or metadata attached to the image).r<hjhhhj8h}r=(h]h]h]h]h]uhNhhh{]r>h)r?}r@(hj<hj:hhhhh}rA(h]h]h]h]h]uhMh{]rB(h)rC}rD(hX:ref:`images-resource`rEhj?hhhhh}rF(UreftypeXrefhƈhXimages-resourceU refdomainXstdrGh]h]U refexplicith]h]h]hhuhMh{]rHh)rI}rJ(hjEh}rK(h]h]rL(hjGXstd-refrMeh]h]h]uhjCh{]rNhXimages-resourcerOrP}rQ(hUhjIubahhubaubhX: The date of when the user last modified an image in the collection (either the image itself, or metadata attached to the image).rRrS}rT(hX: The date of when the user last modified an image in the collection (either the image itself, or metadata attached to the image).hj?ubeubaubj)rU}rV(hX:ref:`image-resource`: The date of when the image was added (or replaced), or when the metadata of the image was last modified.rWhjhhhj8h}rX(h]h]h]h]h]uhNhhh{]rYh)rZ}r[(hjWhjUhhhhh}r\(h]h]h]h]h]uhMh{]r](h)r^}r_(hX:ref:`image-resource`r`hjZhhhhh}ra(UreftypeXrefhƈhXimage-resourceU refdomainXstdrbh]h]U refexplicith]h]h]hhuhMh{]rch)rd}re(hj`h}rf(h]h]rg(hjbXstd-refrheh]h]h]uhj^h{]rihXimage-resourcerjrk}rl(hUhjdubahhubaubhXj: The date of when the image was added (or replaced), or when the metadata of the image was last modified.rmrn}ro(hXj: The date of when the image was added (or replaced), or when the metadata of the image was last modified.hjZubeubaubj)rp}rq(hXW:ref:`metadata-resource`: The date of when the metadata of the image was last modified.rrhjhhhj8h}rs(h]h]h]h]h]uhNhhh{]rth)ru}rv(hjrhjphhhhh}rw(h]h]h]h]h]uhMh{]rx(h)ry}rz(hX:ref:`metadata-resource`r{hjuhhhhh}r|(UreftypeXrefhƈhXmetadata-resourceU refdomainXstdr}h]h]U refexplicith]h]h]hhuhMh{]r~h)r}r(hj{h}r(h]h]r(hj}Xstd-refreh]h]h]uhjyh{]rhXmetadata-resourcerr}r(hUhjubahhubaubhX?: The date of when the metadata of the image was last modified.rr}r(hX?: The date of when the metadata of the image was last modified.hjuubeubaubj)r}r(hXB:ref:`shorturl-resource`: Same as the date of the original image. hjhhhj8h}r(h]h]h]h]h]uhNhhh{]rh)r}r(hXA:ref:`shorturl-resource`: Same as the date of the original image.rhjhhhhh}r(h]h]h]h]h]uhMh{]r(h)r}r(hX:ref:`shorturl-resource`rhjhhhhh}r(UreftypeXrefhƈhXshorturl-resourceU refdomainXstdrh]h]U refexplicith]h]h]hhuhMh{]rh)r}r(hjh}r(h]h]r(hjXstd-refreh]h]h]uhjh{]rhXshorturl-resourcerr}r(hUhjubahhubaubhX): Same as the date of the original image.rr}r(hX): Same as the date of the original image.hjubeubaubeubh)r}r(hXFUser agents can use the value of the ``Last-Modified`` header in the ``If-Modified-Since`` request header to make a conditional request. The value of the ``Last-Modified`` header is an `HTTP-date `_, for instance ``Last-Modified: Wed, 12 Feb 2014 09:46:02 GMT``.rhjhhhhh}r(h]h]h]h]h]uhMhhh{]r(hX%User agents can use the value of the rr}r(hX%User agents can use the value of the hjubj/)r}r(hX``Last-Modified``h}r(h]h]h]h]h]uhjh{]rhX Last-Modifiedrr}r(hUhjubahj7ubhX header in the rr}r(hX header in the hjubj/)r}r(hX``If-Modified-Since``h}r(h]h]h]h]h]uhjh{]rhXIf-Modified-Sincerr}r(hUhjubahj7ubhX@ request header to make a conditional request. The value of the rr}r(hX@ request header to make a conditional request. The value of the hjubj/)r}r(hX``Last-Modified``h}r(h]h]h]h]h]uhjh{]rhX Last-Modifiedrr}r(hUhjubahj7ubhX header is an rr}r(hX header is an hjubh)r}r(hXM`HTTP-date `_h}r(UnameX HTTP-datehX>http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1rh]h]h]h]h]uhjh{]rhX HTTP-daterr}r(hUhjubahhubh)r}r(hXA hKhjhhh}r(Urefurijh]rhWah]h]h]h]rhauh{]ubhX, for instance rr}r(hX, for instance hjubj/)r}r(hX0``Last-Modified: Wed, 12 Feb 2014 09:46:02 GMT``h}r(h]h]h]h]h]uhjh{]rhX,Last-Modified: Wed, 12 Feb 2014 09:46:02 GMTrr}r(hUhjubahj7ubhX.r}r(hX.hjubeubeubeubh})r}r(hUhh~hhhhh}r(h]h]h]h]rhVah]rhauhMhhh{]r(h)r}r(hXErrorsrhjhhhhh}r(h]h]h]h]h]uhMhhh{]rhXErrorsrr}r(hjhjubaubh)r}r(hX}When an error occurs Imbo will respond with a fitting HTTP response code along with a JSON object explaining what went wrong.rhjhhhhh}r(h]h]h]h]h]uhMhhh{]rhX}When an error occurs Imbo will respond with a fitting HTTP response code along with a JSON object explaining what went wrong.rr}r(hjhjubaubj)r}r(hX)curl -g "http://imbo/users//foobar"hjhhhjh}r(jjXbashjjh]h]h]h]h]uhMhhh{]rhX)curl -g "http://imbo/users//foobar"rr}r(hUhjubaubh)r}r(hX results in:rhjhhhhh}r(h]h]h]h]h]uhMhhh{]rhX results in:rr}r (hjhjubaubj)r }r (hX{ "error": { "imboErrorCode": 0, "date": "Wed, 12 Dec 2012 21:15:01 GMT", "message": "Not Found", "code": 404 } }hjhhhjh}r (jjX javascriptjjh]h]h]h]h]uhMhhh{]r hX{ "error": { "imboErrorCode": 0, "date": "Wed, 12 Dec 2012 21:15:01 GMT", "message": "Not Found", "code": 404 } }rr}r(hUhj ubaubh)r}r(hX!The ``code`` is the HTTP response code, ``message`` is a human readable error message, ``date`` is when the error occurred on the server, and ``imboErrorCode`` is an internal error code that can be used by the user agent to distinguish between similar errors (such as ``400 Bad request``).rhjhhhhh}r(h]h]h]h]h]uhMhhh{]r(hXThe rr}r(hXThe hjubj/)r}r(hX``code``h}r(h]h]h]h]h]uhjh{]rhXcoderr}r(hUhjubahj7ubhX is the HTTP response code, r r!}r"(hX is the HTTP response code, hjubj/)r#}r$(hX ``message``h}r%(h]h]h]h]h]uhjh{]r&hXmessager'r(}r)(hUhj#ubahj7ubhX$ is a human readable error message, r*r+}r,(hX$ is a human readable error message, hjubj/)r-}r.(hX``date``h}r/(h]h]h]h]h]uhjh{]r0hXdater1r2}r3(hUhj-ubahj7ubhX/ is when the error occurred on the server, and r4r5}r6(hX/ is when the error occurred on the server, and hjubj/)r7}r8(hX``imboErrorCode``h}r9(h]h]h]h]h]uhjh{]r:hX imboErrorCoder;r<}r=(hUhj7ubahj7ubhXm is an internal error code that can be used by the user agent to distinguish between similar errors (such as r>r?}r@(hXm is an internal error code that can be used by the user agent to distinguish between similar errors (such as hjubj/)rA}rB(hX``400 Bad request``h}rC(h]h]h]h]h]uhjh{]rDhX400 Bad requestrErF}rG(hUhjAubahj7ubhX).rHrI}rJ(hX).hjubeubh)rK}rL(hXyThe JSON object will also include ``imageIdentifier`` if the request was made against the image or the metadata resource.rMhjhhhhh}rN(h]h]h]h]h]uhMhhh{]rO(hX"The JSON object will also include rPrQ}rR(hX"The JSON object will also include hjKubj/)rS}rT(hX``imageIdentifier``h}rU(h]h]h]h]h]uhjKh{]rVhXimageIdentifierrWrX}rY(hUhjSubahj7ubhXD if the request was made against the image or the metadata resource.rZr[}r\(hXD if the request was made against the image or the metadata resource.hjKubeubeubeubahUU transformerr]NU footnote_refsr^}r_Urefnamesr`}raUsymbol_footnotesrb]rcUautofootnote_refsrd]reUsymbol_footnote_refsrf]rgU citationsrh]rihhU current_linerjNUtransform_messagesrk]rl(cdocutils.nodes system_message rm)rn}ro(hUh}rp(h]UlevelKh]h]Usourcehh]h]UlineKUtypeUINFOrquh{]rrh)rs}rt(hUh}ru(h]h]h]h]h]uhjnh{]rvhX4Hyperlink target "index-resource" is not referenced.rwrx}ry(hUhjsubahhubahUsystem_messagerzubjm)r{}r|(hUh}r}(h]UlevelKh]h]Usourcehh]h]UlineK;Utypejquh{]r~h)r}r(hUh}r(h]h]h]h]h]uhj{h{]rhX4Hyperlink target "stats-resource" is not referenced.rr}r(hUhjubahhubahjzubjm)r}r(hUh}r(h]UlevelKh]h]Usourcehh]h]UlineKUtypejquh{]rh)r}r(hUh}r(h]h]h]h]h]uhjh{]rhX5Hyperlink target "status-resource" is not referenced.rr}r(hUhjubahhubahjzubjm)r}r(hUh}r(h]UlevelKh]h]Usourcehh]h]UlineKUtypejquh{]rh)r}r(hUh}r(h]h]h]h]h]uhjh{]rhX3Hyperlink target "user-resource" is not referenced.rr}r(hUhjubahhubahjzubjm)r}r(hUh}r(h]UlevelKh]h]Usourcehh]h]UlineKUtypejquh{]rh)r}r(hUh}r(h]h]h]h]h]uhjh{]rhX5Hyperlink target "images-resource" is not referenced.rr}r(hUhjubahhubahjzubjm)r}r(hUh}r(h]UlevelKh]h]Usourcehh]h]UlineMTUtypejquh{]rh)r}r(hUh}r(h]h]h]h]h]uhjh{]rhX4Hyperlink target "image-resource" is not referenced.rr}r(hUhjubahhubahjzubjm)r}r(hUh}r(h]UlevelKh]h]Usourcehh]h]UlineMUtypejquh{]rh)r}r(hUh}r(h]h]h]h]h]uhjh{]rhX7Hyperlink target "shorturl-resource" is not referenced.rr}r(hUhjubahhubahjzubjm)r}r(hUh}r(h]UlevelKh]h]Usourcehh]h]UlineMUtypejquh{]rh)r}r(hUh}r(h]h]h]h]h]uhjh{]rhX7Hyperlink target "metadata-resource" is not referenced.rr}r(hUhjubahhubahjzubjm)r}r(hUh}r(h]UlevelKh]h]Usourcehh]h]UlineMCUtypejquh{]rh)r}r(hUh}r(h]h]h]h]h]uhjh{]rhX3Hyperlink target "access-tokens" is not referenced.rr}r(hUhjubahhubahjzubjm)r}r(hUh}r(h]UlevelKh]h]Usourcehh]h]UlineM^Utypejquh{]rh)r}r(hUh}r(h]h]h]h]h]uhjh{]rhX<Hyperlink target "signing-write-requests" is not referenced.rr}r(hUhjubahhubahjzubeUreporterrNUid_startrK U autofootnotesr]rU citation_refsr}rUindirect_targetsr]rUsettingsr(cdocutils.frontend Values ror}r(Ufootnote_backlinksrKUrecord_dependenciesrNU rfc_base_urlrUhttp://tools.ietf.org/html/rU tracebackrUpep_referencesrNUstrip_commentsrNU toc_backlinksrUentryrU language_coderUenrU datestamprNU report_levelrKU _destinationrNU halt_levelrKU strip_classesrNhNUerror_encoding_error_handlerrUbackslashreplacerUdebugrNUembed_stylesheetrUoutput_encoding_error_handlerrUstrictrU sectnum_xformrKUdump_transformsrNU docinfo_xformrKUwarning_streamrNUpep_file_url_templaterUpep-%04drUexit_status_levelrKUconfigrNUstrict_visitorrNUcloak_email_addressesr Utrim_footnote_reference_spacer Uenvr NUdump_pseudo_xmlr NUexpose_internalsr NUsectsubtitle_xformrU source_linkrNUrfc_referencesrNUoutput_encodingrUutf-8rU source_urlrNUinput_encodingrU utf-8-sigrU_disable_configrNU id_prefixrUU tab_widthrKUerror_encodingrUUTF-8rU_sourcerU>/var/build/user_builds/imbo/checkouts/1.1.1/docs/usage/api.rstrUgettext_compactrU generatorrNUdump_internalsrNU smart_quotesr U pep_base_urlr!Uhttp://www.python.org/dev/peps/r"Usyntax_highlightr#Ulongr$Uinput_encoding_error_handlerr%jUauto_id_prefixr&Uidr'Udoctitle_xformr(Ustrip_elements_with_classesr)NU _config_filesr*]Ufile_insertion_enabledr+U raw_enabledr,KU dump_settingsr-NubUsymbol_footnote_startr.KUidsr/}r0(hEjSj_j[hMjyhwjh`jhIjhzjShnj(hrj hvjV h]hhPhhpjhcjhRjKhSjhUjhQjh[j;jjjjhXjyjyjuj)j%jEjAhaj hojhkjwjjhgjh\jhjj2hHjh^jXhZjhLj hTjBhbjhOj hGh~hNj hFj h_jhVjhdj hejhmjhqjR hhjhJjhfj hYjhKjD hujhtjhWjhsj= hlj hxjhyjwjjhij uUsubstitution_namesr1}r2hhh}r3(h]h]h]Usourcehh]h]uU footnotesr4]r5Urefidsr6}r7(hE]r8jPahU]r9jahy]r:jtahO]r;j ahX]r<jvahg]r=jahd]r>j ahm]r?jahQ]r@jahi]rAj auub.PKrND6imbo-1.1.1/.doctrees/installation/installation.doctreecdocutils.nodes document q)q}q(U nametypesq}q(Xdatabase-setupqXcookiesqXdatabase setupqNXsqliteq NXcomposerq Xmysqlq NX packagistq Xusing composerq NXvarnishqXusing git cloneqNX git-cloneqXusing-composerqXvclqXweb server configurationqNX mod_rewriteqXfastcgiqXlighttpdqNXnginxqXapacheqX http protocolqX installationqXnext significant releasequUsubstitution_defsq}qUparse_messagesq]q(cdocutils.nodes system_message q )q!}q"(U rawsourceq#UUparentq$cdocutils.nodes section q%)q&}q'(h#UU referencedq(Kh$hUsourceq)cdocutils.nodes reprunicode q*XN/var/build/user_builds/imbo/checkouts/1.1.1/docs/installation/installation.rstq+q,}q-bUexpect_referenced_by_nameq.}q/hcdocutils.nodes target q0)q1}q2(h#X.. _installation:h$hh)h,Utagnameq3Utargetq4U attributesq5}q6(Uidsq7]Ubackrefsq8]Udupnamesq9]Uclassesq:]Unamesq;]UrefidqKUdocumentq?hUchildrenq@]ubsh3UsectionqAh5}qB(h9]qCX installationqDah:]h8]h7]qE(h=Uid1qFeh;]qGhauh>Kh?hUexpect_referenced_by_idqH}qIh=h1sh@]qJ(cdocutils.nodes title qK)qL}qM(h#X InstallationqNh$h&h)h,h3UtitleqOh5}qP(h9]h:]h8]h7]h;]uh>Kh?hh@]qQcdocutils.nodes Text qRX InstallationqSqT}qU(h#hNh$hLubaubcdocutils.nodes paragraph qV)qW}qX(h#XTo install Imbo on the server you can choose between two different methods, :ref:`Composer ` (recommended) or :ref:`git clone `.qYh$h&h)h,h3U paragraphqZh5}q[(h9]h:]h8]h7]h;]uh>Kh?hh@]q\(hRXLTo install Imbo on the server you can choose between two different methods, q]q^}q_(h#XLTo install Imbo on the server you can choose between two different methods, h$hWubcsphinx.addnodes pending_xref q`)qa}qb(h#X :ref:`Composer `qch$hWh)h,h3U pending_xrefqdh5}qe(UreftypeXrefUrefwarnqfU reftargetqgXusing-composerU refdomainXstdqhh7]h8]U refexplicith9]h:]h;]UrefdocqiXinstallation/installationqjuh>Kh@]qkcdocutils.nodes emphasis ql)qm}qn(h#hch5}qo(h9]h:]qp(UxrefqqhhXstd-refqreh8]h7]h;]uh$hah@]qshRXComposerqtqu}qv(h#Uh$hmubah3UemphasisqwubaubhRX (recommended) or qxqy}qz(h#X (recommended) or h$hWubh`)q{}q|(h#X:ref:`git clone `q}h$hWh)h,h3hdh5}q~(UreftypeXrefhfhgX git-cloneU refdomainXstdqh7]h8]U refexplicith9]h:]h;]hihjuh>Kh@]qhl)q}q(h#h}h5}q(h9]h:]q(hqhXstd-refqeh8]h7]h;]uh$h{h@]qhRX git cloneqq}q(h#Uh$hubah3hwubaubhRX.q}q(h#X.h$hWubeubh0)q}q(h#X.. _using-composer:h$h&h)h,h3h4h5}q(h7]h8]h9]h:]h;]hKh?hh@]ubh%)q}q(h#Uh$h&h)h,h.}qhhsh3hAh5}q(h9]h:]h8]h7]q(hUid2qeh;]q(h heuh>K h?hhH}qhhsh@]q(hK)q}q(h#XUsing composerqh$hh)h,h3hOh5}q(h9]h:]h8]h7]h;]uh>K h?hh@]qhRXUsing composerqq}q(h#hh$hubaubhV)q}q(h#XThe recommended way of installing Imbo is by creating a ``composer.json`` file for your installation, and then install Imbo and optional 3rd party plug-ins via `Composer `_. You will need the following directory structure for this method to work::qh$hh)h,h3hZh5}q(h9]h:]h8]h7]h;]uh>K h?hh@]q(hRX8The recommended way of installing Imbo is by creating a qq}q(h#X8The recommended way of installing Imbo is by creating a h$hubcdocutils.nodes literal q)q}q(h#X``composer.json``h5}q(h9]h:]h8]h7]h;]uh$hh@]qhRX composer.jsonqq}q(h#Uh$hubah3UliteralqubhRXW file for your installation, and then install Imbo and optional 3rd party plug-ins via qq}q(h#XW file for your installation, and then install Imbo and optional 3rd party plug-ins via h$hubcdocutils.nodes reference q)q}q(h#X%`Composer `_h5}q(UnameXComposerUrefuriqXhttps://getcomposer.orgqh7]h8]h9]h:]h;]uh$hh@]qhRXComposerqq}q(h#Uh$hubah3U referencequbh0)q}q(h#X h(Kh$hh3h4h5}q(Urefurihh7]qUcomposerqah8]h9]h:]h;]qh auh@]ubhRXJ. You will need the following directory structure for this method to work:qƅq}q(h#XJ. You will need the following directory structure for this method to work:h$hubeubcdocutils.nodes literal_block q)q}q(h#X7/path/to/install/composer.json /path/to/install/config/h$hh)h,h3U literal_blockqh5}q(U xml:spaceqUpreserveqh7]h8]h9]h:]h;]uh>Kh?hh@]qhRX7/path/to/install/composer.json /path/to/install/config/qхq}q(h#Uh$hubaubhV)q}q(h#X-where the ``composer.json`` file can contain:qh$hh)h,h3hZh5}q(h9]h:]h8]h7]h;]uh>Kh?hh@]q(hRX where the qمq}q(h#X where the h$hubh)q}q(h#X``composer.json``h5}q(h9]h:]h8]h7]h;]uh$hh@]qhRX composer.jsonqq}q(h#Uh$hubah3hubhRX file can contain:qㅁq}q(h#X file can contain:h$hubeubh)q}q(h#XO{ "name": "yourname/imbo", "require": { "imbo/imbo": "dev-master" } }h$hh)h,h3hh5}q(UlinenosqUlanguageqXjsonhhh7]h8]h9]h:]h;]uh>Kh?hh@]qhRXO{ "name": "yourname/imbo", "require": { "imbo/imbo": "dev-master" } }q셁q}q(h#Uh$hubaubhV)q}q(h#X and the ``config/`` directory contains one or more configuration files that will be merged with the :ref:`default configuration `. Imbo will load **all** ``.php`` files in this directory, and the ones returning an array will be used as configuration.qh$hh)h,h3hZh5}q(h9]h:]h8]h7]h;]uh>Kh?hh@]q(hRXand the qq}q(h#Xand the h$hubh)q}q(h#X ``config/``h5}q(h9]h:]h8]h7]h;]uh$hh@]qhRXconfig/qq}q(h#Uh$hubah3hubhRXQ directory contains one or more configuration files that will be merged with the qq}r(h#XQ directory contains one or more configuration files that will be merged with the h$hubh`)r}r(h#X,:ref:`default configuration `rh$hh)h,h3hdh5}r(UreftypeXrefhfhgX configurationU refdomainXstdrh7]h8]U refexplicith9]h:]h;]hihjuh>Kh@]rhl)r}r(h#jh5}r (h9]h:]r (hqjXstd-refr eh8]h7]h;]uh$jh@]r hRXdefault configurationr r}r(h#Uh$jubah3hwubaubhRX. Imbo will load rr}r(h#X. Imbo will load h$hubcdocutils.nodes strong r)r}r(h#X**all**h5}r(h9]h:]h8]h7]h;]uh$hh@]rhRXallrr}r(h#Uh$jubah3UstrongrubhRX r}r(h#X h$hubh)r}r(h#X``.php``h5}r (h9]h:]h8]h7]h;]uh$hh@]r!hRX.phpr"r#}r$(h#Uh$jubah3hubhRXX files in this directory, and the ones returning an array will be used as configuration.r%r&}r'(h#XX files in this directory, and the ones returning an array will be used as configuration.h$hubeubhV)r(}r)(h#XIf you want to install 3rd party plug-ins and/or for instance the Doctrine DBAL library simply add these to the ``require`` object in your ``composer.json``:r*h$hh)h,h3hZh5}r+(h9]h:]h8]h7]h;]uh>Kh?hh@]r,(hRXpIf you want to install 3rd party plug-ins and/or for instance the Doctrine DBAL library simply add these to the r-r.}r/(h#XpIf you want to install 3rd party plug-ins and/or for instance the Doctrine DBAL library simply add these to the h$j(ubh)r0}r1(h#X ``require``h5}r2(h9]h:]h8]h7]h;]uh$j(h@]r3hRXrequirer4r5}r6(h#Uh$j0ubah3hubhRX object in your r7r8}r9(h#X object in your h$j(ubh)r:}r;(h#X``composer.json``h5}r<(h9]h:]h8]h7]h;]uh$j(h@]r=hRX composer.jsonr>r?}r@(h#Uh$j:ubah3hubhRX:rA}rB(h#X:h$j(ubeubh)rC}rD(h#X{ "name": "yourname/imbo", "require": { "imbo/imbo": "dev-master", "rexxars/imbo-hipsta": "dev-master", "doctrine/dbal": "2.*" } }h$hh)h,h3hh5}rE(hhXjsonhhh7]h8]h9]h:]h;]uh>K!h?hh@]rFhRX{ "name": "yourname/imbo", "require": { "imbo/imbo": "dev-master", "rexxars/imbo-hipsta": "dev-master", "doctrine/dbal": "2.*" } }rGrH}rI(h#Uh$jCubaubhV)rJ}rK(h#XIf some of the 3rd party plug-ins provide configuration files, you can link to these in the ``config/`` directory to have Imbo automatically load them:rLh$hh)h,h3hZh5}rM(h9]h:]h8]h7]h;]uh>K,h?hh@]rN(hRX\If some of the 3rd party plug-ins provide configuration files, you can link to these in the rOrP}rQ(h#X\If some of the 3rd party plug-ins provide configuration files, you can link to these in the h$jJubh)rR}rS(h#X ``config/``h5}rT(h9]h:]h8]h7]h;]uh$jJh@]rUhRXconfig/rVrW}rX(h#Uh$jRubah3hubhRX0 directory to have Imbo automatically load them:rYrZ}r[(h#X0 directory to have Imbo automatically load them:h$jJubeubh)r\}r](h#Xccd /path/to/install/config ln -s ../vendor/rexxars/imbo-hipsta/config/config.php 01-imbo-hipsta.phph$hh)h,h3hh5}r^(hhXbashhhh7]h8]h9]h:]h;]uh>K.h?hh@]r_hRXccd /path/to/install/config ln -s ../vendor/rexxars/imbo-hipsta/config/config.php 01-imbo-hipsta.phpr`ra}rb(h#Uh$j\ubaubhV)rc}rd(h#X?To be able to control the order that Imbo will use when loading the configuration files you should prefix them with a number, like ``01`` in the example above. Lower numbers will be loaded first, meaning that configuration files with higher numbers will override settings set in configuration files with a lower number.reh$hh)h,h3hZh5}rf(h9]h:]h8]h7]h;]uh>K3h?hh@]rg(hRXTo be able to control the order that Imbo will use when loading the configuration files you should prefix them with a number, like rhri}rj(h#XTo be able to control the order that Imbo will use when loading the configuration files you should prefix them with a number, like h$jcubh)rk}rl(h#X``01``h5}rm(h9]h:]h8]h7]h;]uh$jch@]rnhRX01rorp}rq(h#Uh$jkubah3hubhRX in the example above. Lower numbers will be loaded first, meaning that configuration files with higher numbers will override settings set in configuration files with a lower number.rrrs}rt(h#X in the example above. Lower numbers will be loaded first, meaning that configuration files with higher numbers will override settings set in configuration files with a lower number.h$jcubeubhV)ru}rv(h#XRegarding the Imbo version you are about to install you can use ``dev-master`` for the latest released version, or you can use a specific version if you want to. Head over to `Packagist `_ to see the available versions. If you're more of a YOLO type of person you can use ``dev-develop`` for the latest development version. If you choose to use the ``dev-develop`` branch, expect things to break from time to time.rwh$hh)h,h3hZh5}rx(h9]h:]h8]h7]h;]uh>K5h?hh@]ry(hRX@Regarding the Imbo version you are about to install you can use rzr{}r|(h#X@Regarding the Imbo version you are about to install you can use h$juubh)r}}r~(h#X``dev-master``h5}r(h9]h:]h8]h7]h;]uh$juh@]rhRX dev-masterrr}r(h#Uh$j}ubah3hubhRXa for the latest released version, or you can use a specific version if you want to. Head over to rr}r(h#Xa for the latest released version, or you can use a specific version if you want to. Head over to h$juubh)r}r(h#X7`Packagist `_h5}r(UnameX PackagisthX(https://packagist.org/packages/imbo/imborh7]h8]h9]h:]h;]uh$juh@]rhRX Packagistrr}r(h#Uh$jubah3hubh0)r}r(h#X+ h(Kh$juh3h4h5}r(Urefurijh7]rU packagistrah8]h9]h:]h;]rh auh@]ubhRXT to see the available versions. If you're more of a YOLO type of person you can use rr}r(h#XT to see the available versions. If you're more of a YOLO type of person you can use h$juubh)r}r(h#X``dev-develop``h5}r(h9]h:]h8]h7]h;]uh$juh@]rhRX dev-developrr}r(h#Uh$jubah3hubhRX> for the latest development version. If you choose to use the rr}r(h#X> for the latest development version. If you choose to use the h$juubh)r}r(h#X``dev-develop``h5}r(h9]h:]h8]h7]h;]uh$juh@]rhRX dev-developrr}r(h#Uh$jubah3hubhRX2 branch, expect things to break from time to time.rr}r(h#X2 branch, expect things to break from time to time.h$juubeubhV)r}r(h#XImbo strives to keep full BC in minor and patch releases, so you should be able to use Composer's `Next Significant Release `_ feature when specifying which Imbo version you want to install. Reading the ChangeLog and other related sources of information before upgrading an installation is always recommended.rh$hh)h,h3hZh5}r(h9]h:]h8]h7]h;]uh>K7h?hh@]r(hRXbImbo strives to keep full BC in minor and patch releases, so you should be able to use Composer's rr}r(h#XbImbo strives to keep full BC in minor and patch releases, so you should be able to use Composer's h$jubh)r}r(h#Xs`Next Significant Release `_h5}r(UnameXNext Significant ReleasehXUhttp://getcomposer.org/doc/01-basic-usage.md#next-significant-release-tilde-operator-rh7]h8]h9]h:]h;]uh$jh@]rhRXNext Significant Releaserr}r(h#Uh$jubah3hubh0)r}r(h#XX h(Kh$jh3h4h5}r(Urefurijh7]rUnext-significant-releaserah8]h9]h:]h;]rhauh@]ubhRX feature when specifying which Imbo version you want to install. Reading the ChangeLog and other related sources of information before upgrading an installation is always recommended.rr}r(h#X feature when specifying which Imbo version you want to install. Reading the ChangeLog and other related sources of information before upgrading an installation is always recommended.h$jubeubhV)r}r(h#XTWhen you have created the ``composer.json`` file you can install Imbo with Composer:rh$hh)h,h3hZh5}r(h9]h:]h8]h7]h;]uh>K9h?hh@]r(hRXWhen you have created the rr}r(h#XWhen you have created the h$jubh)r}r(h#X``composer.json``h5}r(h9]h:]h8]h7]h;]uh$jh@]rhRX composer.jsonrr}r(h#Uh$jubah3hubhRX) file you can install Imbo with Composer:rr}r(h#X) file you can install Imbo with Composer:h$jubeubh)r}r(h#XUcurl -s https://getcomposer.org/installer | php php composer.phar install -o --no-devh$hh)h,h3hh5}r(hhXbashhhh7]h8]h9]h:]h;]uh>K;h?hh@]rhRXUcurl -s https://getcomposer.org/installer | php php composer.phar install -o --no-devrr}r(h#Uh$jubaubhV)r}r(h#XAfter composer has finished installing Imbo and optional dependencies the Imbo installation will reside in ``/path/to/install/vendor/imbo/imbo``. The correct web server document root in this case would be ``/path/to/install/vendor/imbo/imbo/public``.rh$hh)h,h3hZh5}r(h9]h:]h8]h7]h;]uh>K@h?hh@]r(hRXkAfter composer has finished installing Imbo and optional dependencies the Imbo installation will reside in rr}r(h#XkAfter composer has finished installing Imbo and optional dependencies the Imbo installation will reside in h$jubh)r}r(h#X%``/path/to/install/vendor/imbo/imbo``h5}r(h9]h:]h8]h7]h;]uh$jh@]rhRX!/path/to/install/vendor/imbo/imborr}r(h#Uh$jubah3hubhRX=. The correct web server document root in this case would be rr}r(h#X=. The correct web server document root in this case would be h$jubh)r}r(h#X,``/path/to/install/vendor/imbo/imbo/public``h5}r(h9]h:]h8]h7]h;]uh$jh@]rhRX(/path/to/install/vendor/imbo/imbo/publicrr}r(h#Uh$jubah3hubhRX.r}r(h#X.h$jubeubhV)r}r(h#XqIf you later want to update Imbo you can bump the version number you have specified in ``composer.json`` and run:rh$hh)h,h3hZh5}r(h9]h:]h8]h7]h;]uh>KBh?hh@]r(hRXWIf you later want to update Imbo you can bump the version number you have specified in rr}r(h#XWIf you later want to update Imbo you can bump the version number you have specified in h$jubh)r}r(h#X``composer.json``h5}r(h9]h:]h8]h7]h;]uh$jh@]rhRX composer.jsonrr}r(h#Uh$jubah3hubhRX and run:rr }r (h#X and run:h$jubeubh)r }r (h#X$php composer.phar update -o --no-devh$hh)h,h3hh5}r (hhXbashhhh7]h8]h9]h:]h;]uh>KDh?hh@]rhRX$php composer.phar update -o --no-devrr}r(h#Uh$j ubaubh0)r}r(h#X.. _git-clone:h$hh)h,h3h4h5}r(h7]h8]h9]h:]h;]hKHh?hh@]ubeubh%)r}r(h#Uh$h&h)h,h.}rhjsh3hAh5}r(h9]h:]h8]h7]r(Uusing-git-clonerjeh;]r(hheuh>KKh?hhH}rjjsh@]r(hK)r}r (h#XUsing git cloner!h$jh)h,h3hOh5}r"(h9]h:]h8]h7]h;]uh>KKh?hh@]r#hRXUsing git cloner$r%}r&(h#j!h$jubaubhV)r'}r((h#X^You can also install Imbo directly via git, and then use Composer to install the dependencies:r)h$jh)h,h3hZh5}r*(h9]h:]h8]h7]h;]uh>KMh?hh@]r+hRX^You can also install Imbo directly via git, and then use Composer to install the dependencies:r,r-}r.(h#j)h$j'ubaubh)r/}r0(h#Xmkdir /path/to/install; cd /path/to/install git clone https://github.com/imbo/imbo.git cd imbo curl -s https://getcomposer.org/installer | php php composer.phar install -o --no-devh$jh)h,h3hh5}r1(hhXbashhhh7]h8]h9]h:]h;]uh>KOh?hh@]r2hRXmkdir /path/to/install; cd /path/to/install git clone https://github.com/imbo/imbo.git cd imbo curl -s https://getcomposer.org/installer | php php composer.phar install -o --no-devr3r4}r5(h#Uh$j/ubaubhV)r6}r7(h#X5In this case the correct web server document root would be ``/path/to/install/imbo/public``. Remember to checkout the correct branch after cloning the repository to get the version you want, for instance ``git checkout master``. If you use this method of installation you will have to modify Imbo's ``composer.json`` to install 3rd party libraries. You will also have to place your own ``config.php`` configuration file in the same directory as the default Imbo configuration file, which in the above example would be the ``/path/to/install/imbo/config`` directory.r8h$jh)h,h3hZh5}r9(h9]h:]h8]h7]h;]uh>KWh?hh@]r:(hRX;In this case the correct web server document root would be r;r<}r=(h#X;In this case the correct web server document root would be h$j6ubh)r>}r?(h#X ``/path/to/install/imbo/public``h5}r@(h9]h:]h8]h7]h;]uh$j6h@]rAhRX/path/to/install/imbo/publicrBrC}rD(h#Uh$j>ubah3hubhRXq. Remember to checkout the correct branch after cloning the repository to get the version you want, for instance rErF}rG(h#Xq. Remember to checkout the correct branch after cloning the repository to get the version you want, for instance h$j6ubh)rH}rI(h#X``git checkout master``h5}rJ(h9]h:]h8]h7]h;]uh$j6h@]rKhRXgit checkout masterrLrM}rN(h#Uh$jHubah3hubhRXH. If you use this method of installation you will have to modify Imbo's rOrP}rQ(h#XH. If you use this method of installation you will have to modify Imbo's h$j6ubh)rR}rS(h#X``composer.json``h5}rT(h9]h:]h8]h7]h;]uh$j6h@]rUhRX composer.jsonrVrW}rX(h#Uh$jRubah3hubhRXF to install 3rd party libraries. You will also have to place your own rYrZ}r[(h#XF to install 3rd party libraries. You will also have to place your own h$j6ubh)r\}r](h#X``config.php``h5}r^(h9]h:]h8]h7]h;]uh$j6h@]r_hRX config.phpr`ra}rb(h#Uh$j\ubah3hubhRXz configuration file in the same directory as the default Imbo configuration file, which in the above example would be the rcrd}re(h#Xz configuration file in the same directory as the default Imbo configuration file, which in the above example would be the h$j6ubh)rf}rg(h#X ``/path/to/install/imbo/config``h5}rh(h9]h:]h8]h7]h;]uh$j6h@]rihRX/path/to/install/imbo/configrjrk}rl(h#Uh$jfubah3hubhRX directory.rmrn}ro(h#X directory.h$j6ubeubhV)rp}rq(h#XIf you want to contribute to Imbo, this is the obvious installation method. Read more about this in the :doc:`../develop/contributing` chapter.rrh$jh)h,h3hZh5}rs(h9]h:]h8]h7]h;]uh>KYh?hh@]rt(hRXhIf you want to contribute to Imbo, this is the obvious installation method. Read more about this in the rurv}rw(h#XhIf you want to contribute to Imbo, this is the obvious installation method. Read more about this in the h$jpubh`)rx}ry(h#X:doc:`../develop/contributing`rzh$jph)h,h3hdh5}r{(UreftypeXdocr|hfhgX../develop/contributingU refdomainUh7]h8]U refexplicith9]h:]h;]hihjuh>KYh@]r}h)r~}r(h#jzh5}r(h9]h:]r(hqj|eh8]h7]h;]uh$jxh@]rhRX../develop/contributingrr}r(h#Uh$j~ubah3hubaubhRX chapter.rr}r(h#X chapter.h$jpubeubeubh%)r}r(h#Uh$h&h)h,h3hAh5}r(h9]h:]h8]h7]rUweb-server-configurationrah;]rhauh>K\h?hh@]r(hK)r}r(h#XWeb server configurationrh$jh)h,h3hOh5}r(h9]h:]h8]h7]h;]uh>K\h?hh@]rhRXWeb server configurationrr}r(h#jh$jubaubhV)r}r(h#XAfter installing Imbo by using one of the methods mentioned above you will have to configure the web server you want to use. Imbo ships with sample configuration files for `Apache `_ and `Nginx `_ that can be used with a few minor adjustments. Both configuration files assume the httpd runs on port 80. If you use `Varnish `_ or some other HTTP accelerator simply change the port number to the port that your httpd listens to.rh$jh)h,h3hZh5}r(h9]h:]h8]h7]h;]uh>K^h?hh@]r(hRXAfter installing Imbo by using one of the methods mentioned above you will have to configure the web server you want to use. Imbo ships with sample configuration files for rr}r(h#XAfter installing Imbo by using one of the methods mentioned above you will have to configure the web server you want to use. Imbo ships with sample configuration files for h$jubh)r}r(h#X$`Apache `_h5}r(UnameXApachehXhttp://httpd.apache.org/rh7]h8]h9]h:]h;]uh$jh@]rhRXApacherr}r(h#Uh$jubah3hubh0)r}r(h#X h(Kh$jh3h4h5}r(Urefurijh7]rUapacherah8]h9]h:]h;]rhauh@]ubhRX and rr}r(h#X and h$jubh)r}r(h#X`Nginx `_h5}r(UnameXNginxhXhttp://nginx.org/rh7]h8]h9]h:]h;]uh$jh@]rhRXNginxrr}r(h#Uh$jubah3hubh0)r}r(h#X h(Kh$jh3h4h5}r(Urefurijh7]rUnginxrah8]h9]h:]h;]rhauh@]ubhRXv that can be used with a few minor adjustments. Both configuration files assume the httpd runs on port 80. If you use rr}r(h#Xv that can be used with a few minor adjustments. Both configuration files assume the httpd runs on port 80. If you use h$jubh)r}r(h#X+`Varnish `_h5}r(UnameXVarnishhXhttps://www.varnish-cache.org/rh7]h8]h9]h:]h;]uh$jh@]rhRXVarnishrr}r(h#Uh$jubah3hubh0)r}r(h#X! h(Kh$jh3h4h5}r(Urefurijh7]rUvarnishrah8]h9]h:]h;]rhauh@]ubhRXe or some other HTTP accelerator simply change the port number to the port that your httpd listens to.rr}r(h#Xe or some other HTTP accelerator simply change the port number to the port that your httpd listens to.h$jubeubh%)r}r(h#Uh(Kh$jh)h,h3hAh5}r(h9]rXapacherah:]h8]h7]rUid3rah;]uh>Kah?hh@]r(hK)r}r(h#XApacherh$jh)h,h3hOh5}r(h9]h:]h8]h7]h;]uh>Kah?hh@]rhRXApacherr}r(h#jh$jubaubhV)r}r(h#XYou will need to enable `mod_rewrite `_ if you want to use Imbo with Apache. Below is an example on how to configure Apache for Imbo:rh$jh)h,h3hZh5}r(h9]h:]h8]h7]h;]uh>Kch?hh@]r(hRXYou will need to enable rr}r(h#XYou will need to enable h$jubh)r}r(h#XJ`mod_rewrite `_h5}r(UnamehhX9http://httpd.apache.org/docs/current/mod/mod_rewrite.htmlrh7]h8]h9]h:]h;]uh$jh@]rhRX mod_rewriterr}r(h#Uh$jubah3hubh0)r}r(h#X< h(Kh$jh3h4h5}r(Urefurijh7]rU mod-rewriterah8]h9]h:]h;]rhauh@]ubhRX^ if you want to use Imbo with Apache. Below is an example on how to configure Apache for Imbo:rr}r(h#X^ if you want to use Imbo with Apache. Below is an example on how to configure Apache for Imbo:h$jubeubh)r}r(h#X # Servername of the virtual host ServerName imbo # Define aliases to use multiple hosts # ServerAlias imbo1 imbo2 imbo3 # Document root where the index.php file is located DocumentRoot /path/to/install/vendor/imbo/imbo/public # Logging # CustomLog /var/log/apache2/imbo.access_log combined # ErrorLog /var/log/apache2/imbo.error_log # Rewrite rules that rewrite all requests to the index.php script RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteRule .* index.php h$jh)h,h3hh5}r(h9]hhh7]h8]UsourceXH/var/build/user_builds/imbo/checkouts/1.1.1/config/imbo.apache.conf.disth:]h;]uh>Keh?hh@]rhRX # Servername of the virtual host ServerName imbo # Define aliases to use multiple hosts # ServerAlias imbo1 imbo2 imbo3 # Document root where the index.php file is located DocumentRoot /path/to/install/vendor/imbo/imbo/public # Logging # CustomLog /var/log/apache2/imbo.access_log combined # ErrorLog /var/log/apache2/imbo.error_log # Rewrite rules that rewrite all requests to the index.php script RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteRule .* index.php rr}r(h#Uh$jubaubhV)r}r(h#XYou will need to update ``ServerName`` to match the host name you will use for Imbo. If you want to use several host names you can update the ``ServerAlias`` line as well. You must also update ``DocumentRoot`` and ``Directory`` to point to the ``public`` directory in the Imbo installation. If you want to enable logging update the ``CustomLog`` and ``ErrorLog`` lines. ``RewriteCond`` and ``RewriteRule`` should be left alone.rh$jh)h,h3hZh5}r(h9]h:]h8]h7]h;]uh>Kgh?hh@]r(hRXYou will need to update rr }r (h#XYou will need to update h$jubh)r }r (h#X``ServerName``h5}r (h9]h:]h8]h7]h;]uh$jh@]rhRX ServerNamerr}r(h#Uh$j ubah3hubhRXh to match the host name you will use for Imbo. If you want to use several host names you can update the rr}r(h#Xh to match the host name you will use for Imbo. If you want to use several host names you can update the h$jubh)r}r(h#X``ServerAlias``h5}r(h9]h:]h8]h7]h;]uh$jh@]rhRX ServerAliasrr}r(h#Uh$jubah3hubhRX$ line as well. You must also update rr}r(h#X$ line as well. You must also update h$jubh)r}r (h#X``DocumentRoot``h5}r!(h9]h:]h8]h7]h;]uh$jh@]r"hRX DocumentRootr#r$}r%(h#Uh$jubah3hubhRX and r&r'}r((h#X and h$jubh)r)}r*(h#X ``Directory``h5}r+(h9]h:]h8]h7]h;]uh$jh@]r,hRX Directoryr-r.}r/(h#Uh$j)ubah3hubhRX to point to the r0r1}r2(h#X to point to the h$jubh)r3}r4(h#X ``public``h5}r5(h9]h:]h8]h7]h;]uh$jh@]r6hRXpublicr7r8}r9(h#Uh$j3ubah3hubhRXN directory in the Imbo installation. If you want to enable logging update the r:r;}r<(h#XN directory in the Imbo installation. If you want to enable logging update the h$jubh)r=}r>(h#X ``CustomLog``h5}r?(h9]h:]h8]h7]h;]uh$jh@]r@hRX CustomLogrArB}rC(h#Uh$j=ubah3hubhRX and rDrE}rF(h#X and h$jubh)rG}rH(h#X ``ErrorLog``h5}rI(h9]h:]h8]h7]h;]uh$jh@]rJhRXErrorLogrKrL}rM(h#Uh$jGubah3hubhRX lines. rNrO}rP(h#X lines. h$jubh)rQ}rR(h#X``RewriteCond``h5}rS(h9]h:]h8]h7]h;]uh$jh@]rThRX RewriteCondrUrV}rW(h#Uh$jQubah3hubhRX and rXrY}rZ(h#X and h$jubh)r[}r\(h#X``RewriteRule``h5}r](h9]h:]h8]h7]h;]uh$jh@]r^hRX RewriteRuler_r`}ra(h#Uh$j[ubah3hubhRX should be left alone.rbrc}rd(h#X should be left alone.h$jubeubeubh%)re}rf(h#Uh(Kh$jh)h,h3hAh5}rg(h9]rhXnginxriah:]h8]h7]rjUid4rkah;]uh>Kjh?hh@]rl(hK)rm}rn(h#XNginxroh$jeh)h,h3hOh5}rp(h9]h:]h8]h7]h;]uh>Kjh?hh@]rqhRXNginxrrrs}rt(h#joh$jmubaubhV)ru}rv(h#XwBelow is an example on how to configure Nginx for Imbo. This example uses PHP via `FastCGI `_:rwh$jeh)h,h3hZh5}rx(h9]h:]h8]h7]h;]uh>Klh?hh@]ry(hRXRBelow is an example on how to configure Nginx for Imbo. This example uses PHP via rzr{}r|(h#XRBelow is an example on how to configure Nginx for Imbo. This example uses PHP via h$juubh)r}}r~(h#X$`FastCGI `_h5}r(UnameXFastCGIhXhttp://www.fastcgi.com/rh7]h8]h9]h:]h;]uh$juh@]rhRXFastCGIrr}r(h#Uh$j}ubah3hubh0)r}r(h#X h(Kh$juh3h4h5}r(Urefurijh7]rUfastcgirah8]h9]h:]h;]rhauh@]ubhRX:r}r(h#X:h$juubeubh)r}r(h#X'server { # Listen on port 80 listen 80; # Define the server name server_name imbo; # Use the line below instead of the server_name above if you want to use multiple host names # server_name imbo imbo1 imbo2 imbo3; # Path to the public directory where index.php is located root /path/to/install/vendor/imbo/imbo/public; index index.php; # Logs # error_log /var/log/nginx/imbo.error_log; # access_log /var/log/nginx/imbo.access_log main; location / { try_files $uri $uri/ /index.php?$args; location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /path/to/install/vendor/imbo/imbo/public/index.php; include fastcgi_params; } } } h$jeh)h,h3hh5}r(h9]hhh7]h8]UsourceXG/var/build/user_builds/imbo/checkouts/1.1.1/config/imbo.nginx.conf.disth:]h;]uh>Knh?hh@]rhRX'server { # Listen on port 80 listen 80; # Define the server name server_name imbo; # Use the line below instead of the server_name above if you want to use multiple host names # server_name imbo imbo1 imbo2 imbo3; # Path to the public directory where index.php is located root /path/to/install/vendor/imbo/imbo/public; index index.php; # Logs # error_log /var/log/nginx/imbo.error_log; # access_log /var/log/nginx/imbo.access_log main; location / { try_files $uri $uri/ /index.php?$args; location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /path/to/install/vendor/imbo/imbo/public/index.php; include fastcgi_params; } } } rr}r(h#Uh$jubaubhV)r}r(h#XYou will need to update ``server_name`` to match the host name you will use for Imbo. If you want to use several host names simply put several host names on that line. ``root`` must point to the ``public`` directory in the Imbo installation. If you want to enable logging update the ``error_log`` and ``access_log`` lines. You must also update the ``fastcgi_param SCRIPT_FILENAME`` line to point to the ``public/index.php`` file in the Imbo installation.rh$jeh)h,h3hZh5}r(h9]h:]h8]h7]h;]uh>Kph?hh@]r(hRXYou will need to update rr}r(h#XYou will need to update h$jubh)r}r(h#X``server_name``h5}r(h9]h:]h8]h7]h;]uh$jh@]rhRX server_namerr}r(h#Uh$jubah3hubhRX to match the host name you will use for Imbo. If you want to use several host names simply put several host names on that line. rr}r(h#X to match the host name you will use for Imbo. If you want to use several host names simply put several host names on that line. h$jubh)r}r(h#X``root``h5}r(h9]h:]h8]h7]h;]uh$jh@]rhRXrootrr}r(h#Uh$jubah3hubhRX must point to the rr}r(h#X must point to the h$jubh)r}r(h#X ``public``h5}r(h9]h:]h8]h7]h;]uh$jh@]rhRXpublicrr}r(h#Uh$jubah3hubhRXN directory in the Imbo installation. If you want to enable logging update the rr}r(h#XN directory in the Imbo installation. If you want to enable logging update the h$jubh)r}r(h#X ``error_log``h5}r(h9]h:]h8]h7]h;]uh$jh@]rhRX error_logrr}r(h#Uh$jubah3hubhRX and rr}r(h#X and h$jubh)r}r(h#X``access_log``h5}r(h9]h:]h8]h7]h;]uh$jh@]rhRX access_logrr}r(h#Uh$jubah3hubhRX! lines. You must also update the rr}r(h#X! lines. You must also update the h$jubh)r}r(h#X!``fastcgi_param SCRIPT_FILENAME``h5}r(h9]h:]h8]h7]h;]uh$jh@]rhRXfastcgi_param SCRIPT_FILENAMErr}r(h#Uh$jubah3hubhRX line to point to the rr}r(h#X line to point to the h$jubh)r}r(h#X``public/index.php``h5}r(h9]h:]h8]h7]h;]uh$jh@]rhRXpublic/index.phprr}r(h#Uh$jubah3hubhRX file in the Imbo installation.rr}r(h#X file in the Imbo installation.h$jubeubeubh%)r}r(h#Uh$jh)h,h3hAh5}r(h9]h:]h8]h7]rUlighttpdrah;]rhauh>Ksh?hh@]r(hK)r}r(h#XLighttpdrh$jh)h,h3hOh5}r(h9]h:]h8]h7]h;]uh>Ksh?hh@]rhRXLighttpdrr}r(h#jh$jubaubhV)r}r(h#XyBelow is an example on how to configure Lighttpd for Imbo. Running PHP through FastCGI is recommended (not covered here).rh$jh)h,h3hZh5}r(h9]h:]h8]h7]h;]uh>Kuh?hh@]rhRXyBelow is an example on how to configure Lighttpd for Imbo. Running PHP through FastCGI is recommended (not covered here).rr}r(h#jh$jubaubh)r}r(h#X@# Use the line below instead of the next one if you want to use multiple host names # $HTTP["host"] =~ "^(imbo|imbo1|imbo2|imbo3)$" { $HTTP["host"] == "imbo" { # Listen on port 80 server.port = 80 # Path to the public directory where index.php is located server.document-root = "/path/to/install/vendor/imbo/imbo/public" # Logs # server.errorlog = "/var/log/lighttpd/imbo.error_log" # accesslog.filename = "/var/log/lighttpd/imbo.access_log" # Rewrite all to index.php url.rewrite-if-not-file = ("^/[^\?]*(\?.*)?$" => "index.php/$1") } h$jh)h,h3hh5}r(h9]hhh7]h8]UsourceXJ/var/build/user_builds/imbo/checkouts/1.1.1/config/imbo.lighttpd.conf.disth:]h;]uh>Kwh?hh@]rhRX@# Use the line below instead of the next one if you want to use multiple host names # $HTTP["host"] =~ "^(imbo|imbo1|imbo2|imbo3)$" { $HTTP["host"] == "imbo" { # Listen on port 80 server.port = 80 # Path to the public directory where index.php is located server.document-root = "/path/to/install/vendor/imbo/imbo/public" # Logs # server.errorlog = "/var/log/lighttpd/imbo.error_log" # accesslog.filename = "/var/log/lighttpd/imbo.access_log" # Rewrite all to index.php url.rewrite-if-not-file = ("^/[^\?]*(\?.*)?$" => "index.php/$1") } rr}r(h#Uh$jubaubhV)r}r(h#XYou will need to set the correct host name(s) used with ``$HTTP["host"]`` and update the ``server.document-root`` to point to the correct path. If you want to enable logging remove the comments on the lines with ``server.errorlog`` and ``accesslog.filename`` and set the correct paths. If you want to specify a custom access log path you will need to enable the ``mod_accesslog`` module.rh$jh)h,h3hZh5}r(h9]h:]h8]h7]h;]uh>Kyh?hh@]r(hRX8You will need to set the correct host name(s) used with rr}r(h#X8You will need to set the correct host name(s) used with h$jubh)r}r (h#X``$HTTP["host"]``h5}r (h9]h:]h8]h7]h;]uh$jh@]r hRX $HTTP["host"]r r }r(h#Uh$jubah3hubhRX and update the rr}r(h#X and update the h$jubh)r}r(h#X``server.document-root``h5}r(h9]h:]h8]h7]h;]uh$jh@]rhRXserver.document-rootrr}r(h#Uh$jubah3hubhRXc to point to the correct path. If you want to enable logging remove the comments on the lines with rr}r(h#Xc to point to the correct path. If you want to enable logging remove the comments on the lines with h$jubh)r}r(h#X``server.errorlog``h5}r(h9]h:]h8]h7]h;]uh$jh@]rhRXserver.errorlogr r!}r"(h#Uh$jubah3hubhRX and r#r$}r%(h#X and h$jubh)r&}r'(h#X``accesslog.filename``h5}r((h9]h:]h8]h7]h;]uh$jh@]r)hRXaccesslog.filenamer*r+}r,(h#Uh$j&ubah3hubhRXh and set the correct paths. If you want to specify a custom access log path you will need to enable the r-r.}r/(h#Xh and set the correct paths. If you want to specify a custom access log path you will need to enable the h$jubh)r0}r1(h#X``mod_accesslog``h5}r2(h9]h:]h8]h7]h;]uh$jh@]r3hRX mod_accesslogr4r5}r6(h#Uh$j0ubah3hubhRX module.r7r8}r9(h#X module.h$jubeubhV)r:}r;(h#X>This example requires the ``mod_rewrite`` module to be loaded.r<h$jh)h,h3hZh5}r=(h9]h:]h8]h7]h;]uh>K{h?hh@]r>(hRXThis example requires the r?r@}rA(h#XThis example requires the h$j:ubh)rB}rC(h#X``mod_rewrite``h5}rD(h9]h:]h8]h7]h;]uh$j:h@]rEhRX mod_rewriterFrG}rH(h#Uh$jBubah3hubhRX module to be loaded.rIrJ}rK(h#X module to be loaded.h$j:ubeubeubh%)rL}rM(h#Uh(Kh$jh)h,h3hAh5}rN(h9]rOXvarnishrPah:]h8]h7]rQUid5rRah;]uh>K~h?hh@]rS(hK)rT}rU(h#XVarnishrVh$jLh)h,h3hOh5}rW(h9]h:]h8]h7]h;]uh>K~h?hh@]rXhRXVarnishrYrZ}r[(h#jVh$jTubaubhV)r\}r](h#XImbo strives to follow the `HTTP Protocol `_, and can because of this easily leverage `Varnish `_.r^h$jLh)h,h3hZh5}r_(h9]h:]h8]h7]h;]uh>Kh?hh@]r`(hRXImbo strives to follow the rarb}rc(h#XImbo strives to follow the h$j\ubh)rd}re(h#X6`HTTP Protocol `_h5}rf(UnameX HTTP ProtocolhX#http://www.ietf.org/rfc/rfc2616.txtrgh7]h8]h9]h:]h;]uh$j\h@]rhhRX HTTP Protocolrirj}rk(h#Uh$jdubah3hubh0)rl}rm(h#X& h(Kh$j\h3h4h5}rn(Urefurijgh7]roU http-protocolrpah8]h9]h:]h;]rqhauh@]ubhRX*, and can because of this easily leverage rrrs}rt(h#X*, and can because of this easily leverage h$j\ubh)ru}rv(h#X+`Varnish `_h5}rw(UnameXVarnishhXhttps://www.varnish-cache.org/rxh7]h8]h9]h:]h;]uh$j\h@]ryhRXVarnishrzr{}r|(h#Uh$juubah3hubh0)r}}r~(h#X! h(Kh$j\h3h4h5}r(Urefurijxh7]rUid6rah8]h9]rXvarnishrah:]h;]uh@]ubhRX.r}r(h#X.h$j\ubeubhV)r}r(h#XThe only required configuration you need in your `VCL `_ is a default backend:rh$jLh)h,h3hZh5}r(h9]h:]h8]h7]h;]uh>Kh?hh@]r(hRX1The only required configuration you need in your rr}r(h#X1The only required configuration you need in your h$jubh)r}r(h#XB`VCL `_h5}r(UnameXVCLhX9https://www.varnish-cache.org/docs/3.0/reference/vcl.htmlrh7]h8]h9]h:]h;]uh$jh@]rhRXVCLrr}r(h#Uh$jubah3hubh0)r}r(h#X< h(Kh$jh3h4h5}r(Urefurijh7]rUvclrah8]h9]h:]h;]rhauh@]ubhRX is a default backend:rr}r(h#X is a default backend:h$jubeubh)r}r(h#X>backend default { .host = "127.0.0.1"; .port = "81"; }h$jLh)h,h3hh5}r(hhXconsolehhh7]h8]h9]h:]h;]uh>Kh?hh@]rhRX>backend default { .host = "127.0.0.1"; .port = "81"; }rr}r(h#Uh$jubaubhV)r}r(h#XIwhere ``.host`` and ``.port`` is where Varnish can reach your web server.rh$jLh)h,h3hZh5}r(h9]h:]h8]h7]h;]uh>Kh?hh@]r(hRXwhere rr}r(h#Xwhere h$jubh)r}r(h#X ``.host``h5}r(h9]h:]h8]h7]h;]uh$jh@]rhRX.hostrr}r(h#Uh$jubah3hubhRX and rr}r(h#X and h$jubh)r}r(h#X ``.port``h5}r(h9]h:]h8]h7]h;]uh$jh@]rhRX.portrr}r(h#Uh$jubah3hubhRX, is where Varnish can reach your web server.rr}r(h#X, is where Varnish can reach your web server.h$jubeubhV)r}r(h#XIf you use the same host name (or a sub-domain) for your Imbo installation as other services, that in turn uses `Cookies `_, you might want the VCL to ignore these Cookies for the requests made against your Imbo installation (unless you have implemented event listeners for Imbo that uses Cookies). To achieve this you can put the following snippet into your VCL file:rh$jLh)h,h3hZh5}r(h9]h:]h8]h7]h;]uh>Kh?hh@]r(hRXpIf you use the same host name (or a sub-domain) for your Imbo installation as other services, that in turn uses rr}r(h#XpIf you use the same host name (or a sub-domain) for your Imbo installation as other services, that in turn uses h$jubh)r}r(h#X5`Cookies `_h5}r(UnameXCookieshX(http://en.wikipedia.org/wiki/HTTP_cookierh7]h8]h9]h:]h;]uh$jh@]rhRXCookiesrr}r(h#Uh$jubah3hubh0)r}r(h#X+ h(Kh$jh3h4h5}r(Urefurijh7]rUcookiesrah8]h9]h:]h;]rhauh@]ubhRX, you might want the VCL to ignore these Cookies for the requests made against your Imbo installation (unless you have implemented event listeners for Imbo that uses Cookies). To achieve this you can put the following snippet into your VCL file:rr}r(h#X, you might want the VCL to ignore these Cookies for the requests made against your Imbo installation (unless you have implemented event listeners for Imbo that uses Cookies). To achieve this you can put the following snippet into your VCL file:h$jubeubh)r}r(h#Xdsub vcl_recv { if (req.http.host == "imbo.example.com") { unset req.http.Cookie; } }h$jLh)h,h3hh5}r(hhXconsolehhh7]h8]h9]h:]h;]uh>Kh?hh@]rhRXdsub vcl_recv { if (req.http.host == "imbo.example.com") { unset req.http.Cookie; } }rr}r(h#Uh$jubaubhV)r}r(h#X,or, if you have Imbo installed in some path:rh$jLh)h,h3hZh5}r(h9]h:]h8]h7]h;]uh>Kh?hh@]rhRX,or, if you have Imbo installed in some path:rr}r(h#jh$jubaubh)r}r(h#X~sub vcl_recv { if (req.http.host ~ "^(www.)?example.com$" && req.url ~ "^/imbo/") { unset req.http.Cookie; } }h$jLh)h,h3hh5}r(hhXconsolehhh7]h8]h9]h:]h;]uh>Kh?hh@]rhRX~sub vcl_recv { if (req.http.host ~ "^(www.)?example.com$" && req.url ~ "^/imbo/") { unset req.http.Cookie; } }rr}r(h#Uh$jubaubhV)r}r(h#XEif your Imbo installation is available on ``[www.]example.com/imbo``.rh$jLh)h,h3hZh5}r(h9]h:]h8]h7]h;]uh>Kh?hh@]r(hRX*if your Imbo installation is available on rr}r(h#X*if your Imbo installation is available on h$jubh)r}r(h#X``[www.]example.com/imbo``h5}r(h9]h:]h8]h7]h;]uh$jh@]rhRX[www.]example.com/imborr}r(h#Uh$jubah3hubhRX.r}r(h#X.h$jubeubh0)r}r(h#X.. _database-setup:h$jLh)h,h3h4h5}r(h7]h8]h9]h:]h;]hKh?hh@]ubeubeubh%)r}r(h#Uh$h&h)h,h.}rhjsh3hAh5}r (h9]h:]h8]h7]r (jUid7r eh;]r (hheuh>Kh?hhH}r jjsh@]r(hK)r}r(h#XDatabase setuprh$jh)h,h3hOh5}r(h9]h:]h8]h7]h;]uh>Kh?hh@]rhRXDatabase setuprr}r(h#jh$jubaubhV)r}r(h#X:If you choose to use a RDBMS to store data in, you will need to manually create a database, a user and the tables Imbo stores information in. Below you will find schemas for different RDBMSs. You will find information regarding how to authenticate against the RDBMS of you choice in the :ref:`configuration` topic.rh$jh)h,h3hZh5}r(h9]h:]h8]h7]h;]uh>Kh?hh@]r(hRXIf you choose to use a RDBMS to store data in, you will need to manually create a database, a user and the tables Imbo stores information in. Below you will find schemas for different RDBMSs. You will find information regarding how to authenticate against the RDBMS of you choice in the rr}r(h#XIf you choose to use a RDBMS to store data in, you will need to manually create a database, a user and the tables Imbo stores information in. Below you will find schemas for different RDBMSs. You will find information regarding how to authenticate against the RDBMS of you choice in the h$jubh`)r}r (h#X:ref:`configuration`r!h$jh)h,h3hdh5}r"(UreftypeXrefhfhgX configurationU refdomainXstdr#h7]h8]U refexplicith9]h:]h;]hihjuh>Kh@]r$hl)r%}r&(h#j!h5}r'(h9]h:]r((hqj#Xstd-refr)eh8]h7]h;]uh$jh@]r*hRX configurationr+r,}r-(h#Uh$j%ubah3hwubaubhRX topic.r.r/}r0(h#X topic.h$jubeubh%)r1}r2(h#Uh$jh)h,h3hAh5}r3(h9]h:]h8]h7]r4Umysqlr5ah;]r6h auh>Kh?hh@]r7(hK)r8}r9(h#XMySQLr:h$j1h)h,h3hOh5}r;(h9]h:]h8]h7]h;]uh>Kh?hh@]r<hRXMySQLr=r>}r?(h#j:h$j8ubaubh)r@}rA(h#XCREATE TABLE IF NOT EXISTS `imageinfo` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `publicKey` varchar(255) COLLATE utf8_danish_ci NOT NULL, `imageIdentifier` char(32) COLLATE utf8_danish_ci NOT NULL, `size` int(10) unsigned NOT NULL, `extension` varchar(5) COLLATE utf8_danish_ci NOT NULL, `mime` varchar(20) COLLATE utf8_danish_ci NOT NULL, `added` int(10) unsigned NOT NULL, `updated` int(10) unsigned NOT NULL, `width` int(10) unsigned NOT NULL, `height` int(10) unsigned NOT NULL, `checksum` char(32) COLLATE utf8_danish_ci NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `image` (`publicKey`,`imageIdentifier`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_danish_ci AUTO_INCREMENT=1 ; CREATE TABLE IF NOT EXISTS `metadata` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `imageId` int(10) unsigned NOT NULL, `tagName` varchar(255) COLLATE utf8_danish_ci NOT NULL, `tagValue` varchar(255) COLLATE utf8_danish_ci NOT NULL, PRIMARY KEY (`id`), KEY `imageId` (`imageId`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_danish_ci AUTO_INCREMENT=1 ; CREATE TABLE IF NOT EXISTS `shorturl` ( `shortUrlId` char(7) COLLATE utf8_danish_ci NOT NULL, `publicKey` varchar(255) COLLATE utf8_danish_ci NOT NULL, `imageIdentifier` char(32) COLLATE utf8_danish_ci NOT NULL, `extension` char(3) COLLATE utf8_danish_ci DEFAULT NULL, `query` text COLLATE utf8_danish_ci NOT NULL, PRIMARY KEY (`shortUrlId`), KEY `params` (`publicKey`,`imageIdentifier`,`extension`,`query`(255)) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_danish_ci; CREATE TABLE IF NOT EXISTS `storage_images` ( `publicKey` varchar(255) COLLATE utf8_danish_ci NOT NULL, `imageIdentifier` char(32) COLLATE utf8_danish_ci NOT NULL, `data` blob NOT NULL, `updated` int(10) unsigned NOT NULL, PRIMARY KEY (`publicKey`,`imageIdentifier`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_danish_ci; h$j1h)h,h3hh5}rB(hh*XsqlrCrD}rEbh9]hhh7]h8]UsourceXD/var/build/user_builds/imbo/checkouts/1.1.1/setup/doctrine.mysql.sqlh:]h;]uh>Kh?hh@]rFhRXCREATE TABLE IF NOT EXISTS `imageinfo` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `publicKey` varchar(255) COLLATE utf8_danish_ci NOT NULL, `imageIdentifier` char(32) COLLATE utf8_danish_ci NOT NULL, `size` int(10) unsigned NOT NULL, `extension` varchar(5) COLLATE utf8_danish_ci NOT NULL, `mime` varchar(20) COLLATE utf8_danish_ci NOT NULL, `added` int(10) unsigned NOT NULL, `updated` int(10) unsigned NOT NULL, `width` int(10) unsigned NOT NULL, `height` int(10) unsigned NOT NULL, `checksum` char(32) COLLATE utf8_danish_ci NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `image` (`publicKey`,`imageIdentifier`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_danish_ci AUTO_INCREMENT=1 ; CREATE TABLE IF NOT EXISTS `metadata` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `imageId` int(10) unsigned NOT NULL, `tagName` varchar(255) COLLATE utf8_danish_ci NOT NULL, `tagValue` varchar(255) COLLATE utf8_danish_ci NOT NULL, PRIMARY KEY (`id`), KEY `imageId` (`imageId`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_danish_ci AUTO_INCREMENT=1 ; CREATE TABLE IF NOT EXISTS `shorturl` ( `shortUrlId` char(7) COLLATE utf8_danish_ci NOT NULL, `publicKey` varchar(255) COLLATE utf8_danish_ci NOT NULL, `imageIdentifier` char(32) COLLATE utf8_danish_ci NOT NULL, `extension` char(3) COLLATE utf8_danish_ci DEFAULT NULL, `query` text COLLATE utf8_danish_ci NOT NULL, PRIMARY KEY (`shortUrlId`), KEY `params` (`publicKey`,`imageIdentifier`,`extension`,`query`(255)) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_danish_ci; CREATE TABLE IF NOT EXISTS `storage_images` ( `publicKey` varchar(255) COLLATE utf8_danish_ci NOT NULL, `imageIdentifier` char(32) COLLATE utf8_danish_ci NOT NULL, `data` blob NOT NULL, `updated` int(10) unsigned NOT NULL, PRIMARY KEY (`publicKey`,`imageIdentifier`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_danish_ci; rGrH}rI(h#Uh$j@ubaubhV)rJ}rK(h#XmThe ``storage_images`` table is only needed if you plan on storing the actual images in the database as well.rLh$j1h)h,h3hZh5}rM(h9]h:]h8]h7]h;]uh>Kh?hh@]rN(hRXThe rOrP}rQ(h#XThe h$jJubh)rR}rS(h#X``storage_images``h5}rT(h9]h:]h8]h7]h;]uh$jJh@]rUhRXstorage_imagesrVrW}rX(h#Uh$jRubah3hubhRXW table is only needed if you plan on storing the actual images in the database as well.rYrZ}r[(h#XW table is only needed if you plan on storing the actual images in the database as well.h$jJubeubeubh%)r\}r](h#Uh$jh)h,h3hAh5}r^(h9]h:]h8]h7]r_Usqliter`ah;]rah auh>Kh?hh@]rb(hK)rc}rd(h#XSQLitereh$j\h)h,h3hOh5}rf(h9]h:]h8]h7]h;]uh>Kh?hh@]rghRXSQLiterhri}rj(h#jeh$jcubaubh)rk}rl(h#X9CREATE TABLE IF NOT EXISTS imageinfo ( id INTEGER PRIMARY KEY NOT NULL, publicKey TEXT NOT NULL, imageIdentifier TEXT NOT NULL, size INTEGER NOT NULL, extension TEXT NOT NULL, mime TEXT NOT NULL, added INTEGER NOT NULL, updated INTEGER NOT NULL, width INTEGER NOT NULL, height INTEGER NOT NULL, checksum TEXT NOT NULL, UNIQUE (publicKey,imageIdentifier) ); CREATE TABLE IF NOT EXISTS metadata ( id INTEGER PRIMARY KEY NOT NULL, imageId KEY INTEGER NOT NULL, tagName TEXT NOT NULL, tagValue TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS shorturl ( shortUrlId TEXT PRIMARY KEY NOT NULL, publicKey TEXT NOT NULL, imageIdentifier TEXT NOT NULL, extension TEXT, query TEXT NOT NULL ); CREATE INDEX shorturlparams ON shorturl ( publicKey, imageIdentifier, extension, query ); CREATE TABLE IF NOT EXISTS storage_images ( publicKey TEXT NOT NULL, imageIdentifier TEXT NOT NULL, data BLOB NOT NULL, updated INTEGER NOT NULL, PRIMARY KEY (publicKey,imageIdentifier) ); h$j\h)h,h3hh5}rm(hh*Xsqlrnro}rpbh9]hhh7]h8]UsourceXE/var/build/user_builds/imbo/checkouts/1.1.1/setup/doctrine.sqlite.sqlh:]h;]uh>Kh?hh@]rqhRX9CREATE TABLE IF NOT EXISTS imageinfo ( id INTEGER PRIMARY KEY NOT NULL, publicKey TEXT NOT NULL, imageIdentifier TEXT NOT NULL, size INTEGER NOT NULL, extension TEXT NOT NULL, mime TEXT NOT NULL, added INTEGER NOT NULL, updated INTEGER NOT NULL, width INTEGER NOT NULL, height INTEGER NOT NULL, checksum TEXT NOT NULL, UNIQUE (publicKey,imageIdentifier) ); CREATE TABLE IF NOT EXISTS metadata ( id INTEGER PRIMARY KEY NOT NULL, imageId KEY INTEGER NOT NULL, tagName TEXT NOT NULL, tagValue TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS shorturl ( shortUrlId TEXT PRIMARY KEY NOT NULL, publicKey TEXT NOT NULL, imageIdentifier TEXT NOT NULL, extension TEXT, query TEXT NOT NULL ); CREATE INDEX shorturlparams ON shorturl ( publicKey, imageIdentifier, extension, query ); CREATE TABLE IF NOT EXISTS storage_images ( publicKey TEXT NOT NULL, imageIdentifier TEXT NOT NULL, data BLOB NOT NULL, updated INTEGER NOT NULL, PRIMARY KEY (publicKey,imageIdentifier) ); rrrs}rt(h#Uh$jkubaubhV)ru}rv(h#XmThe ``storage_images`` table is only needed if you plan on storing the actual images in the database as well.rwh$j\h)h,h3hZh5}rx(h9]h:]h8]h7]h;]uh>Kh?hh@]ry(hRXThe rzr{}r|(h#XThe h$juubh)r}}r~(h#X``storage_images``h5}r(h9]h:]h8]h7]h;]uh$juh@]rhRXstorage_imagesrr}r(h#Uh$j}ubah3hubhRXW table is only needed if you plan on storing the actual images in the database as well.rr}r(h#XW table is only needed if you plan on storing the actual images in the database as well.h$juubeubeubeubeubh)h,h3Usystem_messagerh5}r(h9]UlevelKh7]h8]rhFaUsourceh,h:]h;]UlineKUtypeUINFOruh>Kh?hh@]rhV)r}r(h#Uh5}r(h9]h:]h8]h7]h;]uh$h!h@]rhRX/Duplicate implicit target name: "installation".rr}r(h#Uh$jubah3hZubaubh )r}r(h#Uh$jh)h,h3jh5}r(h9]UlevelKh7]h8]rjaUsourceh,h:]h;]UlineKaUtypejuh>Kah?hh@]rhV)r}r(h#Uh5}r(h9]h:]h8]h7]h;]uh$jh@]rhRX)Duplicate implicit target name: "apache".rr}r(h#Uh$jubah3hZubaubh )r}r(h#Uh$jeh)h,h3jh5}r(h9]UlevelKh7]h8]rjkaUsourceh,h:]h;]UlineKjUtypejuh>Kjh?hh@]rhV)r}r(h#Uh5}r(h9]h:]h8]h7]h;]uh$jh@]rhRX(Duplicate implicit target name: "nginx".rr}r(h#Uh$jubah3hZubaubh )r}r(h#Uh$jLh)h,h3jh5}r(h9]UlevelKh7]h8]rjRaUsourceh,h:]h;]UlineK~Utypejuh>K~h?hh@]rhV)r}r(h#Uh5}r(h9]h:]h8]h7]h;]uh$jh@]rhRX*Duplicate implicit target name: "varnish".rr}r(h#Uh$jubah3hZubaubh )r}r(h#Uh$jLh)h,h3jh5}r(h9]UlevelKh7]h8]rjaUsourceh,h:]h;]UlineKUtypejuh>Kh?hh@]rhV)r}r(h#Uh5}r(h9]h:]h8]h7]h;]uh$jh@]rhRX*Duplicate explicit target name: "varnish".rr}r(h#Uh$jubah3hZubaubeUcurrent_sourcerNU decorationrNUautofootnote_startrKUnameidsr}r(hjhjhj h j`h hh j5h jh hhjhjhjhhhjhjhjhjhjhjhjhjphh=hjuh@]r(h1h&eh#UU transformerrNU footnote_refsr}rUrefnamesr}rUsymbol_footnotesr]rUautofootnote_refsr]rUsymbol_footnote_refsr]rU citationsr]rh?hU current_linerNUtransform_messagesr]r(h )r}r(h#Uh5}r(h9]UlevelKh7]h8]Usourceh,h:]h;]UlineKUtypejuh@]rhV)r}r(h#Uh5}r(h9]h:]h8]h7]h;]uh$jh@]rhRX2Hyperlink target "installation" is not referenced.rr}r(h#Uh$jubah3hZubah3jubh )r}r(h#Uh5}r(h9]UlevelKh7]h8]Usourceh,h:]h;]UlineKUtypejuh@]rhV)r}r(h#Uh5}r(h9]h:]h8]h7]h;]uh$jh@]rhRX4Hyperlink target "using-composer" is not referenced.rr}r(h#Uh$jubah3hZubah3jubh )r}r(h#Uh5}r(h9]UlevelKh7]h8]Usourceh,h:]h;]UlineKHUtypejuh@]rhV)r}r(h#Uh5}r(h9]h:]h8]h7]h;]uh$jh@]rhRX/Hyperlink target "git-clone" is not referenced.rr}r(h#Uh$jubah3hZubah3jubh )r}r(h#Uh5}r(h9]UlevelKh7]h8]Usourceh,h:]h;]UlineKUtypejuh@]rhV)r}r(h#Uh5}r(h9]h:]h8]h7]h;]uh$jh@]rhRX4Hyperlink target "database-setup" is not referenced.rr}r(h#Uh$jubah3hZubah3jubeUreporterrNUid_startrKU autofootnotesr]rU citation_refsr }r Uindirect_targetsr ]r Usettingsr (cdocutils.frontend Values ror}r(Ufootnote_backlinksrKUrecord_dependenciesrNU rfc_base_urlrUhttp://tools.ietf.org/html/rU tracebackrUpep_referencesrNUstrip_commentsrNU toc_backlinksrUentryrU language_coderUenrU datestamprNU report_levelrKU _destinationrNU halt_levelrKU strip_classesr NhONUerror_encoding_error_handlerr!Ubackslashreplacer"Udebugr#NUembed_stylesheetr$Uoutput_encoding_error_handlerr%Ustrictr&U sectnum_xformr'KUdump_transformsr(NU docinfo_xformr)KUwarning_streamr*NUpep_file_url_templater+Upep-%04dr,Uexit_status_levelr-KUconfigr.NUstrict_visitorr/NUcloak_email_addressesr0Utrim_footnote_reference_spacer1Uenvr2NUdump_pseudo_xmlr3NUexpose_internalsr4NUsectsubtitle_xformr5U source_linkr6NUrfc_referencesr7NUoutput_encodingr8Uutf-8r9U source_urlr:NUinput_encodingr;U utf-8-sigr<U_disable_configr=NU id_prefixr>UU tab_widthr?KUerror_encodingr@UUTF-8rAU_sourcerBUN/var/build/user_builds/imbo/checkouts/1.1.1/docs/installation/installation.rstrCUgettext_compactrDU generatorrENUdump_internalsrFNU smart_quotesrGU pep_base_urlrHUhttp://www.python.org/dev/peps/rIUsyntax_highlightrJUlongrKUinput_encoding_error_handlerrLj&Uauto_id_prefixrMUidrNUdoctitle_xformrOUstrip_elements_with_classesrPNU _config_filesrQ]Ufile_insertion_enabledrRU raw_enabledrSKU dump_settingsrTNubUsymbol_footnote_startrUKUidsrV}rW(jjjjhhj`j\hhj5j1jjjpjljjjjjj}hhjkjejRjLjjjjhFh&jjjjjjjjjjjjjjh=h&j jjjuUsubstitution_namesrX}rYh3h?h5}rZ(h9]h7]h8]Usourceh,h:]h;]uU footnotesr[]r\Urefidsr]}r^(h]r_hah=]r`h1aj]rajaj]rbjauub.PKrND>FF9imbo-1.1.1/.doctrees/installation/event_listeners.doctreecdocutils.nodes document q)q}q(U nametypesq}q(X stats accessqNX auto-rotate-image-event-listenerqX access tokenqNXcrontabq Ximagickq NXcidr-notationsq X$cors (cross-origin resource sharing)q NUcontentsq NX5customize your imbo installation with event listenersqNXvarnish hashtwoqNXvarnishqX authenticateqNXimagick-event-listenerqXexifqXauto rotate imageqNXcors-event-listenerqXmax-image-size-event-listenerqX exif metadataqNXauthenticate-event-listenerqXmetadata cacheqNXimage transformation cacheqNXcorsqXhashtwo headersqXstats-access-event-listenerqXmax image sizeqNXaccess-token-event-listenerqXdosq uUsubstitution_defsq!}q"Uparse_messagesq#]q$Ucurrent_sourceq%NU decorationq&NUautofootnote_startq'KUnameidsq(}q)(hU stats-accessq*hU auto-rotate-image-event-listenerq+hU access-tokenq,h Ucrontabq-h Uimagickq.h Ucidr-notationsq/h U"cors-cross-origin-resource-sharingq0h Ucontentsq1hU5customize-your-imbo-installation-with-event-listenersq2hUvarnish-hashtwoq3hUvarnishq4hU authenticateq5hUimagick-event-listenerq6hUexifq7hUauto-rotate-imageq8hUcors-event-listenerq9hUmax-image-size-event-listenerq:hU exif-metadataq;hUauthenticate-event-listenerqhUcorsq?hUhashtwo-headersq@hUstats-access-event-listenerqAhUmax-image-sizeqBhUaccess-token-event-listenerqCh UdosqDuUchildrenqE]qFcdocutils.nodes section qG)qH}qI(U rawsourceqJUUparentqKhUsourceqLcdocutils.nodes reprunicode qMXQ/var/build/user_builds/imbo/checkouts/1.1.1/docs/installation/event_listeners.rstqNqO}qPbUtagnameqQUsectionqRU attributesqS}qT(UdupnamesqU]UclassesqV]UbackrefsqW]UidsqX]qYh2aUnamesqZ]q[hauUlineq\KUdocumentq]hhE]q^(cdocutils.nodes title q_)q`}qa(hJX5Customize your Imbo installation with event listenersqbhKhHhLhOhQUtitleqchS}qd(hU]hV]hW]hX]hZ]uh\Kh]hhE]qecdocutils.nodes Text qfX5Customize your Imbo installation with event listenersqgqh}qi(hJhbhKh`ubaubcdocutils.nodes paragraph qj)qk}ql(hJXQImbo ships with a collection of event listeners for you to use. Some of them are enabled in the default configuration file. Image transformations are also technically event listeners, but will not be covered in this chapter. Read the :doc:`../usage/image-transformations` chapter for more information regarding the image transformations.qmhKhHhLhOhQU paragraphqnhS}qo(hU]hV]hW]hX]hZ]uh\Kh]hhE]qp(hfXImbo ships with a collection of event listeners for you to use. Some of them are enabled in the default configuration file. Image transformations are also technically event listeners, but will not be covered in this chapter. Read the qqqr}qs(hJXImbo ships with a collection of event listeners for you to use. Some of them are enabled in the default configuration file. Image transformations are also technically event listeners, but will not be covered in this chapter. Read the hKhkubcsphinx.addnodes pending_xref qt)qu}qv(hJX%:doc:`../usage/image-transformations`qwhKhkhLhOhQU pending_xrefqxhS}qy(UreftypeXdocqzUrefwarnq{U reftargetq|X../usage/image-transformationsU refdomainUhX]hW]U refexplicithU]hV]hZ]Urefdocq}Xinstallation/event_listenersq~uh\KhE]qcdocutils.nodes literal q)q}q(hJhwhS}q(hU]hV]q(UxrefqhzehW]hX]hZ]uhKhuhE]qhfX../usage/image-transformationsqq}q(hJUhKhubahQUliteralqubaubhfXB chapter for more information regarding the image transformations.qq}q(hJXB chapter for more information regarding the image transformations.hKhkubeubcdocutils.nodes topic q)q}q(hJUhKhHhLhOhQUtopicqhS}q(hU]hV]q(UcontentsqUlocalqehW]hX]qh1ahZ]qh auh\Kh]hhE]qcdocutils.nodes bullet_list q)q}q(hJUhKhhLNhQU bullet_listqhS}q(hU]hV]hW]hX]hZ]uh\Nh]hhE]q(cdocutils.nodes list_item q)q}q(hJUhS}q(hU]hV]hW]hX]hZ]uhKhhE]qhj)q}q(hJUhS}q(hU]hV]hW]hX]hZ]uhKhhE]qcdocutils.nodes reference q)q}q(hJUhS}q(hX]qUid1qahW]hU]hV]hZ]Urefidh,uhKhhE]qhfX Access tokenqq}q(hJX Access tokenqhKhubahQU referencequbahQhnubahQU list_itemqubh)q}q(hJUhS}q(hU]hV]hW]hX]hZ]uhKhhE]qhj)q}q(hJUhS}q(hU]hV]hW]hX]hZ]uhKhhE]qh)q}q(hJUhS}q(hX]qUid2qahW]hU]hV]hZ]Urefidh5uhKhhE]qhfX AuthenticateqÅq}q(hJX AuthenticateqhKhubahQhubahQhnubahQhubh)q}q(hJUhS}q(hU]hV]hW]hX]hZ]uhKhhE]qhj)q}q(hJUhS}q(hU]hV]hW]hX]hZ]uhKhhE]qh)q}q(hJUhS}q(hX]qUid3qahW]hU]hV]hZ]Urefidh8uhKhhE]qhfXAuto rotate imageqՅq}q(hJXAuto rotate imageqhKhubahQhubahQhnubahQhubh)q}q(hJUhS}q(hU]hV]hW]hX]hZ]uhKhhE]qhj)q}q(hJUhS}q(hU]hV]hW]hX]hZ]uhKhhE]qh)q}q(hJUhS}q(hX]qUid4qahW]hU]hV]hZ]Urefidh0uhKhhE]qhfX$CORS (Cross-Origin Resource Sharing)q煁q}q(hJX$CORS (Cross-Origin Resource Sharing)qhKhubahQhubahQhnubahQhubh)q}q(hJUhS}q(hU]hV]hW]hX]hZ]uhKhhE]qhj)q}q(hJUhS}q(hU]hV]hW]hX]hZ]uhKhhE]qh)q}q(hJUhS}q(hX]qUid5qahW]hU]hV]hZ]Urefidh;uhKhhE]qhfX EXIF metadataqq}q(hJX EXIF metadataqhKhubahQhubahQhnubahQhubh)q}q(hJUhS}q(hU]hV]hW]hX]hZ]uhKhhE]rhj)r}r(hJUhS}r(hU]hV]hW]hX]hZ]uhKhhE]rh)r}r(hJUhS}r(hX]rUid6r ahW]hU]hV]hZ]Urefidh>uhKjhE]r hfXImage transformation cacher r }r (hJXImage transformation cacherhKjubahQhubahQhnubahQhubh)r}r(hJUhS}r(hU]hV]hW]hX]hZ]uhKhhE]rhj)r}r(hJUhS}r(hU]hV]hW]hX]hZ]uhKjhE]rh)r}r(hJUhS}r(hX]rUid7rahW]hU]hV]hZ]Urefidh.uhKjhE]rhfXImagickrr}r(hJXImagickr hKjubahQhubahQhnubahQhubh)r!}r"(hJUhS}r#(hU]hV]hW]hX]hZ]uhKhhE]r$hj)r%}r&(hJUhS}r'(hU]hV]hW]hX]hZ]uhKj!hE]r(h)r)}r*(hJUhS}r+(hX]r,Uid8r-ahW]hU]hV]hZ]UrefidhBuhKj%hE]r.hfXMax image sizer/r0}r1(hJXMax image sizer2hKj)ubahQhubahQhnubahQhubh)r3}r4(hJUhS}r5(hU]hV]hW]hX]hZ]uhKhhE]r6hj)r7}r8(hJUhS}r9(hU]hV]hW]hX]hZ]uhKj3hE]r:h)r;}r<(hJUhS}r=(hX]r>Uid9r?ahW]hU]hV]hZ]Urefidh=uhKj7hE]r@hfXMetadata cacherArB}rC(hJXMetadata cacherDhKj;ubahQhubahQhnubahQhubh)rE}rF(hJUhS}rG(hU]hV]hW]hX]hZ]uhKhhE]rHhj)rI}rJ(hJUhS}rK(hU]hV]hW]hX]hZ]uhKjEhE]rLh)rM}rN(hJUhS}rO(hX]rPUid10rQahW]hU]hV]hZ]Urefidh*uhKjIhE]rRhfX Stats accessrSrT}rU(hJX Stats accessrVhKjMubahQhubahQhnubahQhubh)rW}rX(hJUhS}rY(hU]hV]hW]hX]hZ]uhKhhE]rZhj)r[}r\(hJUhS}r](hU]hV]hW]hX]hZ]uhKjWhE]r^h)r_}r`(hJUhS}ra(hX]rbUid11rcahW]hU]hV]hZ]Urefidh3uhKj[hE]rdhfXVarnish HashTworerf}rg(hJXVarnish HashTworhhKj_ubahQhubahQhnubahQhubeubaubcdocutils.nodes target ri)rj}rk(hJX .. _access-token-event-listener:hKhHhLhOhQUtargetrlhS}rm(hX]hW]hU]hV]hZ]UrefidrnhCuh\K h]hhE]ubhG)ro}rp(hJUhKhHhLhOUexpect_referenced_by_namerq}rrhjjshQhRhS}rs(hU]hV]hW]hX]rt(h,hCehZ]ru(hheuh\K h]hUexpect_referenced_by_idrv}rwhCjjshE]rx(h_)ry}rz(hJhhKjohLhOhQhchS}r{(hX]hW]hU]hV]hZ]jnhuh\K h]hhE]r|hfX Access tokenr}r~}r(hJhhKjyubaubhj)r}r(hJXThis event listener enforces the usage of access tokens on all read requests against user-specific resources. You can read more about how the actual access tokens work in the :ref:`access-tokens` part of the :doc:`../usage/api` chapter.rhKjohLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\Kh]hhE]r(hfXThis event listener enforces the usage of access tokens on all read requests against user-specific resources. You can read more about how the actual access tokens work in the rr}r(hJXThis event listener enforces the usage of access tokens on all read requests against user-specific resources. You can read more about how the actual access tokens work in the hKjubht)r}r(hJX:ref:`access-tokens`rhKjhLhOhQhxhS}r(UreftypeXrefh{h|X access-tokensU refdomainXstdrhX]hW]U refexplicithU]hV]hZ]h}h~uh\KhE]rcdocutils.nodes emphasis r)r}r(hJjhS}r(hU]hV]r(hjXstd-refrehW]hX]hZ]uhKjhE]rhfX access-tokensrr}r(hJUhKjubahQUemphasisrubaubhfX part of the rr}r(hJX part of the hKjubht)r}r(hJX:doc:`../usage/api`rhKjhLhOhQhxhS}r(UreftypeXdocrh{h|X ../usage/apiU refdomainUhX]hW]U refexplicithU]hV]hZ]h}h~uh\KhE]rh)r}r(hJjhS}r(hU]hV]r(hjehW]hX]hZ]uhKjhE]rhfX ../usage/apirr}r(hJUhKjubahQhubaubhfX chapter.rr}r(hJX chapter.hKjubeubhj)r}r(hJXYTo enforce the access token check this event listener subscribes to the following events:rhKjohLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\Kh]hhE]rhfXYTo enforce the access token check this event listener subscribes to the following events:rr}r(hJjhKjubaubh)r}r(hJUhKjohLhOhQhhS}r(UbulletrX*hX]hW]hU]hV]hZ]uh\Kh]hhE]r(h)r}r(hJX ``user.get``rhKjhLhOhQhhS}r(hU]hV]hW]hX]hZ]uh\Nh]hhE]rhj)r}r(hJjhKjhLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\KhE]rh)r}r(hJjhS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfXuser.getrr}r(hJUhKjubahQhubaubaubh)r}r(hJX ``user.head``rhKjhLhOhQhhS}r(hU]hV]hW]hX]hZ]uh\Nh]hhE]rhj)r}r(hJjhKjhLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\KhE]rh)r}r(hJjhS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfX user.headrr}r(hJUhKjubahQhubaubaubh)r}r(hJX``images.get``rhKjhLhOhQhhS}r(hU]hV]hW]hX]hZ]uh\Nh]hhE]rhj)r}r(hJjhKjhLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\KhE]rh)r}r(hJjhS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfX images.getrr}r(hJUhKjubahQhubaubaubh)r}r(hJX``images.head``rhKjhLhOhQhhS}r(hU]hV]hW]hX]hZ]uh\Nh]hhE]rhj)r}r(hJjhKjhLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\KhE]rh)r}r(hJjhS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfX images.headrr}r(hJUhKjubahQhubaubaubh)r}r(hJX ``image.get``rhKjhLhOhQhhS}r(hU]hV]hW]hX]hZ]uh\Nh]hhE]rhj)r}r(hJjhKjhLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\KhE]rh)r}r(hJjhS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfX image.getrr}r (hJUhKjubahQhubaubaubh)r }r (hJX``image.head``r hKjhLhOhQhhS}r (hU]hV]hW]hX]hZ]uh\Nh]hhE]rhj)r}r(hJj hKj hLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\KhE]rh)r}r(hJj hS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfX image.headrr}r(hJUhKjubahQhubaubaubh)r}r(hJX``metadata.get``rhKjhLhOhQhhS}r(hU]hV]hW]hX]hZ]uh\Nh]hhE]rhj)r}r (hJjhKjhLhOhQhnhS}r!(hU]hV]hW]hX]hZ]uh\KhE]r"h)r#}r$(hJjhS}r%(hU]hV]hW]hX]hZ]uhKjhE]r&hfX metadata.getr'r(}r)(hJUhKj#ubahQhubaubaubh)r*}r+(hJX``metadata.head`` hKjhLhOhQhhS}r,(hU]hV]hW]hX]hZ]uh\Nh]hhE]r-hj)r.}r/(hJX``metadata.head``r0hKj*hLhOhQhnhS}r1(hU]hV]hW]hX]hZ]uh\KhE]r2h)r3}r4(hJj0hS}r5(hU]hV]hW]hX]hZ]uhKj.hE]r6hfX metadata.headr7r8}r9(hJUhKj3ubahQhubaubaubeubhj)r:}r;(hJXCThis event listener has a single parameter that can be used to whitelist and/or blacklist certain image transformations, used when the current request is against an image resource. The parameter is an array with a single key: ``transformations``. This is another array with two keys: ``whitelist`` and ``blacklist``. These two values are arrays where you specify which transformation(s) to whitelist or blacklist. The names of the transformations are the same as the ones used in the request. See :ref:`image-transformations` for a complete list of the supported transformations.r<hKjohLhOhQhnhS}r=(hU]hV]hW]hX]hZ]uh\Kh]hhE]r>(hfXThis event listener has a single parameter that can be used to whitelist and/or blacklist certain image transformations, used when the current request is against an image resource. The parameter is an array with a single key: r?r@}rA(hJXThis event listener has a single parameter that can be used to whitelist and/or blacklist certain image transformations, used when the current request is against an image resource. The parameter is an array with a single key: hKj:ubh)rB}rC(hJX``transformations``hS}rD(hU]hV]hW]hX]hZ]uhKj:hE]rEhfXtransformationsrFrG}rH(hJUhKjBubahQhubhfX'. This is another array with two keys: rIrJ}rK(hJX'. This is another array with two keys: hKj:ubh)rL}rM(hJX ``whitelist``hS}rN(hU]hV]hW]hX]hZ]uhKj:hE]rOhfX whitelistrPrQ}rR(hJUhKjLubahQhubhfX and rSrT}rU(hJX and hKj:ubh)rV}rW(hJX ``blacklist``hS}rX(hU]hV]hW]hX]hZ]uhKj:hE]rYhfX blacklistrZr[}r\(hJUhKjVubahQhubhfX. These two values are arrays where you specify which transformation(s) to whitelist or blacklist. The names of the transformations are the same as the ones used in the request. See r]r^}r_(hJX. These two values are arrays where you specify which transformation(s) to whitelist or blacklist. The names of the transformations are the same as the ones used in the request. See hKj:ubht)r`}ra(hJX:ref:`image-transformations`rbhKj:hLhOhQhxhS}rc(UreftypeXrefh{h|Ximage-transformationsU refdomainXstdrdhX]hW]U refexplicithU]hV]hZ]h}h~uh\KhE]rej)rf}rg(hJjbhS}rh(hU]hV]ri(hjdXstd-refrjehW]hX]hZ]uhKj`hE]rkhfXimage-transformationsrlrm}rn(hJUhKjfubahQjubaubhfX6 for a complete list of the supported transformations.rorp}rq(hJX6 for a complete list of the supported transformations.hKj:ubeubhj)rr}rs(hJXUse ``whitelist`` if you want the listener to skip the access token check for certain transformations, and ``blacklist`` if you want it to only check certain transformations:rthKjohLhOhQhnhS}ru(hU]hV]hW]hX]hZ]uh\Kh]hhE]rv(hfXUse rwrx}ry(hJXUse hKjrubh)rz}r{(hJX ``whitelist``hS}r|(hU]hV]hW]hX]hZ]uhKjrhE]r}hfX whitelistr~r}r(hJUhKjzubahQhubhfXZ if you want the listener to skip the access token check for certain transformations, and rr}r(hJXZ if you want the listener to skip the access token check for certain transformations, and hKjrubh)r}r(hJX ``blacklist``hS}r(hU]hV]hW]hX]hZ]uhKjrhE]rhfX blacklistrr}r(hJUhKjubahQhubhfX6 if you want it to only check certain transformations:rr}r(hJX6 if you want it to only check certain transformations:hKjrubeubcdocutils.nodes literal_block r)r}r(hJXnarray( 'transformations' => array( 'whitelist' => array( 'border', ), ), )hKjohLhOhQU literal_blockrhS}r(UlinenosrUlanguagerXphpU xml:spacerUpreserverhX]hW]hU]hV]hZ]uh\K h]hhE]rhfXnarray( 'transformations' => array( 'whitelist' => array( 'border', ), ), )rr}r(hJUhKjubaubhj)r}r(hJXrmeans that the access token will **not** be enforced for the :ref:`border ` transformation.rhKjohLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\K*h]hhE]r(hfX!means that the access token will rr}r(hJX!means that the access token will hKjubcdocutils.nodes strong r)r}r(hJX**not**hS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfXnotrr}r(hJUhKjubahQUstrongrubhfX be enforced for the rr}r(hJX be enforced for the hKjubht)r}r(hJX%:ref:`border `rhKjhLhOhQhxhS}r(UreftypeXrefh{h|Xborder-transformationU refdomainXstdrhX]hW]U refexplicithU]hV]hZ]h}h~uh\K*hE]rj)r}r(hJjhS}r(hU]hV]r(hjXstd-refrehW]hX]hZ]uhKjhE]rhfXborderrr}r(hJUhKjubahQjubaubhfX transformation.rr}r(hJX transformation.hKjubeubj)r}r(hJXnarray( 'transformations' => array( 'blacklist' => array( 'border', ), ), )hKjohLhOhQjhS}r(jjXphpjjhX]hW]hU]hV]hZ]uh\K,h]hhE]rhfXnarray( 'transformations' => array( 'blacklist' => array( 'border', ), ), )rr}r(hJUhKjubaubhj)r}r(hJXsmeans that the access token will be enforced **only** for the :ref:`border ` transformation.rhKjohLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\K6h]hhE]r(hfX-means that the access token will be enforced rr}r(hJX-means that the access token will be enforced hKjubj)r}r(hJX**only**hS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfXonlyrr}r(hJUhKjubahQjubhfX for the rr}r(hJX for the hKjubht)r}r(hJX%:ref:`border `rhKjhLhOhQhxhS}r(UreftypeXrefh{h|Xborder-transformationU refdomainXstdrhX]hW]U refexplicithU]hV]hZ]h}h~uh\K6hE]rj)r}r(hJjhS}r(hU]hV]r(hjXstd-refrehW]hX]hZ]uhKjhE]rhfXborderrr}r(hJUhKjubahQjubaubhfX transformation.rr}r(hJX transformation.hKjubeubhj)r}r(hJXIf both ``whitelist`` and ``blacklist`` are specified all transformations will require an access token unless it's included in ``whitelist``.rhKjohLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\K8h]hhE]r(hfXIf both rr}r(hJXIf both hKjubh)r}r(hJX ``whitelist``hS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfX whitelistrr}r(hJUhKjubahQhubhfX and rr}r(hJX and hKjubh)r}r(hJX ``blacklist``hS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfX blacklistrr}r(hJUhKjubahQhubhfXX are specified all transformations will require an access token unless it's included in rr}r(hJXX are specified all transformations will require an access token unless it's included in hKjubh)r}r (hJX ``whitelist``hS}r (hU]hV]hW]hX]hZ]uhKjhE]r hfX whitelistr r }r(hJUhKjubahQhubhfX.r}r(hJX.hKjubeubhj)r}r(hJXpThis event listener is included in the default configuration file without specifying any transformation filters:rhKjohLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\K:h]hhE]rhfXpThis event listener is included in the default configuration file without specifying any transformation filters:rr}r(hJjhKjubaubj)r}r(hJX array( 'accessToken' => 'Imbo\EventListener\AccessToken', ), // ... );hKjohLhOhQjhS}r(jjXphpjjhX]hW]hU]hV]hZ]uh\K array( 'accessToken' => 'Imbo\EventListener\AccessToken', ), // ... );rr}r(hJUhKjubaubhj)r }r!(hJXDisable this event listener with care. Installations with no access token check is open for `DoS `_ attacks.r"hKjohLhOhQhnhS}r#(hU]hV]hW]hX]hZ]uh\KIh]hhE]r$(hfX\Disable this event listener with care. Installations with no access token check is open for r%r&}r'(hJX\Disable this event listener with care. Installations with no access token check is open for hKj ubh)r(}r)(hJX>`DoS `_hS}r*(UnameXDoSUrefurir+X5http://en.wikipedia.org/wiki/Denial-of-service_attackr,hX]hW]hU]hV]hZ]uhKj hE]r-hfXDoSr.r/}r0(hJUhKj(ubahQhubji)r1}r2(hJX8 U referencedr3KhKj hQjlhS}r4(Urefurij,hX]r5hDahW]hU]hV]hZ]r6h auhE]ubhfX attacks.r7r8}r9(hJX attacks.hKj ubeubji)r:}r;(hJX .. _authenticate-event-listener:hKjohLhOhQjlhS}r<(hX]hW]hU]hV]hZ]jnh(hJUhKhHhLhOjq}r?hj:shQhRhS}r@(hU]hV]hW]hX]rA(h5h array( 'authenticate' => 'Imbo\EventListener\Authenticate', ), // ... );hKj=hLhOhQjhS}r(jjXphpjjhX]hW]hU]hV]hZ]uh\K\h]hhE]rhfX array( 'authenticate' => 'Imbo\EventListener\Authenticate', ), // ... );rr}r(hJUhKjubaubhj)r}r(hJXxDisable this event listener with care. User agents can delete all your images and metadata if this listener is disabled.rhKj=hLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\Kih]hhE]rhfXxDisable this event listener with care. User agents can delete all your images and metadata if this listener is disabled.rr}r(hJjhKjubaubji)r}r(hJX%.. _auto-rotate-image-event-listener:hKj=hLhOhQjlhS}r(hX]hW]hU]hV]hZ]jnh+uh\Kkh]hhE]ubeubhG)r}r(hJUhKhHhLhOjq}rhjshQhRhS}r(hU]hV]hW]hX]r(h8h+ehZ]r(hheuh\Knh]hjv}rh+jshE]r(h_)r}r(hJhhKjhLhOhQhchS}r(hX]hW]hU]hV]hZ]jnhuh\Knh]hhE]rhfXAuto rotate imagerr}r(hJhhKjubaubhj)r}r(hJXThis event listener will auto rotate new images based on metadata embedded in the image itself (`EXIF `_).rhKjhLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\Kph]hhE]r(hfX`This event listener will auto rotate new images based on metadata embedded in the image itself (rr}r(hJX`This event listener will auto rotate new images based on metadata embedded in the image itself (hKjubh)r}r(hJXE`EXIF `_hS}r(UnameXEXIFj+X;http://en.wikipedia.org/wiki/Exchangeable_image_file_formatrhX]hW]hU]hV]hZ]uhKjhE]rhfXEXIFr r }r (hJUhKjubahQhubji)r }r (hJX> j3KhKjhQjlhS}r(UrefurijhX]rh7ahW]hU]hV]hZ]rhauhE]ubhfX).rr}r(hJX).hKjubeubhj)r}r(hJXJThe listener does not support any parameters and can be enabled like this:rhKjhLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\Krh]hhE]rhfXJThe listener does not support any parameters and can be enabled like this:rr}r(hJjhKjubaubj)r}r(hJX array( 'autoRotateListener' => 'Imbo\EventListener\AutoRotateImage', ), // ... );hKjhLhOhQjhS}r(jjXphpjjhX]hW]hU]hV]hZ]uh\Kth]hhE]rhfX array( 'autoRotateListener' => 'Imbo\EventListener\AutoRotateImage', ), // ... );r r!}r"(hJUhKjubaubhj)r#}r$(hJXJIf you enable this listener all new images added to Imbo will be auto rotated based on the EXIF data. This might also cause the image identifier sent in the response to be different from the one used in the URI when storing the image. This can happen with all event listeners which can possibly modify the image before storing it.r%hKjhLhOhQhnhS}r&(hU]hV]hW]hX]hZ]uh\Kh]hhE]r'hfXJIf you enable this listener all new images added to Imbo will be auto rotated based on the EXIF data. This might also cause the image identifier sent in the response to be different from the one used in the URI when storing the image. This can happen with all event listeners which can possibly modify the image before storing it.r(r)}r*(hJj%hKj#ubaubji)r+}r,(hJX.. _cors-event-listener:hKjhLhOhQjlhS}r-(hX]hW]hU]hV]hZ]jnh9uh\Kh]hhE]ubeubhG)r.}r/(hJUhKhHhLhOjq}r0hj+shQhRhS}r1(hU]hV]hW]hX]r2(h0h9ehZ]r3(h heuh\Kh]hjv}r4h9j+shE]r5(h_)r6}r7(hJhhKj.hLhOhQhchS}r8(hX]hW]hU]hV]hZ]jnhuh\Kh]hhE]r9hfX$CORS (Cross-Origin Resource Sharing)r:r;}r<(hJhhKj6ubaubhj)r=}r>(hJXgThis event listener can be used to allow clients such as web browsers to use Imbo when the client is located on a different origin/domain than the Imbo server is. This is implemented by sending a set of `CORS `_-headers on specific requests, if the origin of the request matches a configured domain.r?hKj.hLhOhQhnhS}r@(hU]hV]hW]hX]hZ]uh\Kh]hhE]rA(hfXThis event listener can be used to allow clients such as web browsers to use Imbo when the client is located on a different origin/domain than the Imbo server is. This is implemented by sending a set of rBrC}rD(hJXThis event listener can be used to allow clients such as web browsers to use Imbo when the client is located on a different origin/domain than the Imbo server is. This is implemented by sending a set of hKj=ubh)rE}rF(hJXD`CORS `_hS}rG(UnameXCORSj+X:http://en.wikipedia.org/wiki/Cross-origin_resource_sharingrHhX]hW]hU]hV]hZ]uhKj=hE]rIhfXCORSrJrK}rL(hJUhKjEubahQhubji)rM}rN(hJX= j3KhKj=hQjlhS}rO(UrefurijHhX]rPh?ahW]hU]hV]hZ]rQhauhE]ubhfXX-headers on specific requests, if the origin of the request matches a configured domain.rRrS}rT(hJXX-headers on specific requests, if the origin of the request matches a configured domain.hKj=ubeubhj)rU}rV(hJXThe event listener can be configured on a per-resource and per-method basis, and will therefore listen to any related events. If enabled without any specific configuration, the listener will allow and respond to the **GET**, **HEAD** and **OPTIONS** methods on all resources. Note however that no origins are allowed by default and that a client will still need to provide a valid access token, unless the :ref:`Access token listener ` is disabled.rWhKj.hLhOhQhnhS}rX(hU]hV]hW]hX]hZ]uh\Kh]hhE]rY(hfXThe event listener can be configured on a per-resource and per-method basis, and will therefore listen to any related events. If enabled without any specific configuration, the listener will allow and respond to the rZr[}r\(hJXThe event listener can be configured on a per-resource and per-method basis, and will therefore listen to any related events. If enabled without any specific configuration, the listener will allow and respond to the hKjUubj)r]}r^(hJX**GET**hS}r_(hU]hV]hW]hX]hZ]uhKjUhE]r`hfXGETrarb}rc(hJUhKj]ubahQjubhfX, rdre}rf(hJX, hKjUubj)rg}rh(hJX**HEAD**hS}ri(hU]hV]hW]hX]hZ]uhKjUhE]rjhfXHEADrkrl}rm(hJUhKjgubahQjubhfX and rnro}rp(hJX and hKjUubj)rq}rr(hJX **OPTIONS**hS}rs(hU]hV]hW]hX]hZ]uhKjUhE]rthfXOPTIONSrurv}rw(hJUhKjqubahQjubhfX methods on all resources. Note however that no origins are allowed by default and that a client will still need to provide a valid access token, unless the rxry}rz(hJX methods on all resources. Note however that no origins are allowed by default and that a client will still need to provide a valid access token, unless the hKjUubht)r{}r|(hJX::ref:`Access token listener `r}hKjUhLhOhQhxhS}r~(UreftypeXrefh{h|Xaccess-token-event-listenerU refdomainXstdrhX]hW]U refexplicithU]hV]hZ]h}h~uh\KhE]rj)r}r(hJj}hS}r(hU]hV]r(hjXstd-refrehW]hX]hZ]uhKj{hE]rhfXAccess token listenerrr}r(hJUhKjubahQjubaubhfX is disabled.rr}r(hJX is disabled.hKjUubeubhj)r}r(hJX6Here is an example on how to enable the CORS listener:rhKj.hLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\Kh]hhE]rhfX6Here is an example on how to enable the CORS listener:rr}r(hJjhKjubaubj)r}r(hJX array( 'cors' => array( 'listener' => 'Imbo\EventListener\Cors', 'params' => array( 'allowedOrigins' => array('http://some.origin'), 'allowedMethods' => array( 'image' => array('GET', 'HEAD'), 'images' => array('GET', 'HEAD', 'POST'), ), 'maxAge' => 3600, ), ), ), // ... );hKj.hLhOhQjhS}r(jjXphpjjhX]hW]hU]hV]hZ]uh\Kh]hhE]rhfX array( 'cors' => array( 'listener' => 'Imbo\EventListener\Cors', 'params' => array( 'allowedOrigins' => array('http://some.origin'), 'allowedMethods' => array( 'image' => array('GET', 'HEAD'), 'images' => array('GET', 'HEAD', 'POST'), ), 'maxAge' => 3600, ), ), ), // ... );rr}r(hJUhKjubaubhj)r}r(hJX*Below all supported parameters are listed:rhKj.hLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\Kh]hhE]rhfX*Below all supported parameters are listed:rr}r(hJjhKjubaubcdocutils.nodes definition_list r)r}r(hJUhKj.hLhOhQUdefinition_listrhS}r(hU]hV]hW]hX]hZ]uh\Nh]hhE]r(cdocutils.nodes definition_list_item r)r}r(hJXs``allowedOrigins`` is an array of allowed origins. Specifying ``*`` as a value in the array will allow any origin. hKjhLhOhQUdefinition_list_itemrhS}r(hU]hV]hW]hX]hZ]uh\KhE]r(cdocutils.nodes term r)r}r(hJX``allowedOrigins``rhKjhLhOhQUtermrhS}r(hU]hV]hW]hX]hZ]uh\KhE]rh)r}r(hJjhS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfXallowedOriginsrr}r(hJUhKjubahQhubaubcdocutils.nodes definition r)r}r(hJUhS}r(hU]hV]hW]hX]hZ]uhKjhE]rhj)r}r(hJX_is an array of allowed origins. Specifying ``*`` as a value in the array will allow any origin.hKjhLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\KhE]r(hfX+is an array of allowed origins. Specifying rr}r(hJX+is an array of allowed origins. Specifying hKjubh)r}r(hJX``*``hS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfX*r}r(hJUhKjubahQhubhfX/ as a value in the array will allow any origin.rr}r(hJX/ as a value in the array will allow any origin.hKjubeubahQU definitionrubeubj)r}r(hJX``allowedMethods`` is an associative array where the keys represent the resource (``shorturl``, ``status``, ``stats``, ``user``, ``images``, ``image`` and ``metadata``) and the values are arrays of HTTP methods you wish to open up. hKjhLhOhQjhS}r(hU]hV]hW]hX]hZ]uh\Kh]hhE]r(j)r}r(hJX``allowedMethods``rhKjhLhOhQjhS}r(hU]hV]hW]hX]hZ]uh\KhE]rh)r}r(hJjhS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfXallowedMethodsrr}r(hJUhKjubahQhubaubj)r}r(hJUhS}r(hU]hV]hW]hX]hZ]uhKjhE]rhj)r}r(hJXis an associative array where the keys represent the resource (``shorturl``, ``status``, ``stats``, ``user``, ``images``, ``image`` and ``metadata``) and the values are arrays of HTTP methods you wish to open up.hKjhLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\KhE]r(hfX?is an associative array where the keys represent the resource (rr}r(hJX?is an associative array where the keys represent the resource (hKjubh)r}r(hJX ``shorturl``hS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfXshorturlrr}r(hJUhKjubahQhubhfX, rr}r(hJX, hKjubh)r}r(hJX ``status``hS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfXstatusrr}r(hJUhKjubahQhubhfX, rr}r(hJX, hKjubh)r}r(hJX ``stats``hS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfXstatsrr}r (hJUhKjubahQhubhfX, r r }r (hJX, hKjubh)r }r(hJX``user``hS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfXuserrr}r(hJUhKj ubahQhubhfX, rr}r(hJX, hKjubh)r}r(hJX ``images``hS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfXimagesrr}r(hJUhKjubahQhubhfX, rr}r (hJX, hKjubh)r!}r"(hJX ``image``hS}r#(hU]hV]hW]hX]hZ]uhKjhE]r$hfXimager%r&}r'(hJUhKj!ubahQhubhfX and r(r)}r*(hJX and hKjubh)r+}r,(hJX ``metadata``hS}r-(hU]hV]hW]hX]hZ]uhKjhE]r.hfXmetadatar/r0}r1(hJUhKj+ubahQhubhfX@) and the values are arrays of HTTP methods you wish to open up.r2r3}r4(hJX@) and the values are arrays of HTTP methods you wish to open up.hKjubeubahQjubeubj)r5}r6(hJX}``maxAge`` specifies how long the response of an OPTIONS-request can be cached for, in seconds. Defaults to 3600 (one hour). hKjhLhOhQjhS}r7(hU]hV]hW]hX]hZ]uh\Kh]hhE]r8(j)r9}r:(hJX ``maxAge``r;hKj5hLhOhQjhS}r<(hU]hV]hW]hX]hZ]uh\KhE]r=h)r>}r?(hJj;hS}r@(hU]hV]hW]hX]hZ]uhKj9hE]rAhfXmaxAgerBrC}rD(hJUhKj>ubahQhubaubj)rE}rF(hJUhS}rG(hU]hV]hW]hX]hZ]uhKj5hE]rHhj)rI}rJ(hJXqspecifies how long the response of an OPTIONS-request can be cached for, in seconds. Defaults to 3600 (one hour).rKhKjEhLhOhQhnhS}rL(hU]hV]hW]hX]hZ]uh\KhE]rMhfXqspecifies how long the response of an OPTIONS-request can be cached for, in seconds. Defaults to 3600 (one hour).rNrO}rP(hJjKhKjIubaubahQjubeubeubeubhG)rQ}rR(hJUhKhHhLhOhQhRhS}rS(hU]hV]hW]hX]rTh;ahZ]rUhauh\Kh]hhE]rV(h_)rW}rX(hJhhKjQhLhOhQhchS}rY(hX]hW]hU]hV]hZ]jnhuh\Kh]hhE]rZhfX EXIF metadatar[r\}r](hJhhKjWubaubhj)r^}r_(hJXThis event listener can be used to fetch the EXIF-tags from uploaded images and adding them as metadata. Enabling this event listener will not populate metadata for images already added to Imbo.r`hKjQhLhOhQhnhS}ra(hU]hV]hW]hX]hZ]uh\Kh]hhE]rbhfXThis event listener can be used to fetch the EXIF-tags from uploaded images and adding them as metadata. Enabling this event listener will not populate metadata for images already added to Imbo.rcrd}re(hJj`hKj^ubaubhj)rf}rg(hJX6The event listener subscribes to the following events:rhhKjQhLhOhQhnhS}ri(hU]hV]hW]hX]hZ]uh\Kh]hhE]rjhfX6The event listener subscribes to the following events:rkrl}rm(hJjhhKjfubaubh)rn}ro(hJUhKjQhLhOhQhhS}rp(jX*hX]hW]hU]hV]hZ]uh\Kh]hhE]rq(h)rr}rs(hJX``images.post``rthKjnhLhOhQhhS}ru(hU]hV]hW]hX]hZ]uh\Nh]hhE]rvhj)rw}rx(hJjthKjrhLhOhQhnhS}ry(hU]hV]hW]hX]hZ]uh\KhE]rzh)r{}r|(hJjthS}r}(hU]hV]hW]hX]hZ]uhKjwhE]r~hfX images.postrr}r(hJUhKj{ubahQhubaubaubh)r}r(hJX``db.image.insert`` hKjnhLhOhQhhS}r(hU]hV]hW]hX]hZ]uh\Nh]hhE]rhj)r}r(hJX``db.image.insert``rhKjhLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\KhE]rh)r}r(hJjhS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfXdb.image.insertrr}r(hJUhKjubahQhubaubaubeubhj)r}r(hJXIand the parameters given to the event listener supports a single element:rhKjQhLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\Kh]hhE]rhfXIand the parameters given to the event listener supports a single element:rr}r(hJjhKjubaubj)r}r(hJUhKjQhLhOhQjhS}r(hU]hV]hW]hX]hZ]uh\Nh]hhE]rj)r}r(hJX``allowedTags`` The tags you want to be populated as metadata. Defaults to ``exif:*``. When specified it will override the default value, so if you want to register all ``exif`` and ``date`` tags for example, you will need to specify them both. hKjhLhOhQjhS}r(hU]hV]hW]hX]hZ]uh\KhE]r(j)r}r(hJX``allowedTags``rhKjhLhOhQjhS}r(hU]hV]hW]hX]hZ]uh\KhE]rh)r}r(hJjhS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfX allowedTagsrr}r(hJUhKjubahQhubaubj)r}r(hJUhS}r(hU]hV]hW]hX]hZ]uhKjhE]rhj)r}r(hJXThe tags you want to be populated as metadata. Defaults to ``exif:*``. When specified it will override the default value, so if you want to register all ``exif`` and ``date`` tags for example, you will need to specify them both.hKjhLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\KhE]r(hfX;The tags you want to be populated as metadata. Defaults to rr}r(hJX;The tags you want to be populated as metadata. Defaults to hKjubh)r}r(hJX ``exif:*``hS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfXexif:*rr}r(hJUhKjubahQhubhfXT. When specified it will override the default value, so if you want to register all rr}r(hJXT. When specified it will override the default value, so if you want to register all hKjubh)r}r(hJX``exif``hS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfXexifrr}r(hJUhKjubahQhubhfX and rr}r(hJX and hKjubh)r}r(hJX``date``hS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfXdaterr}r(hJUhKjubahQhubhfX6 tags for example, you will need to specify them both.rr}r(hJX6 tags for example, you will need to specify them both.hKjubeubahQjubeubaubhj)r}r(hJXand is enabled like this:rhKjQhLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\Kh]hhE]rhfXand is enabled like this:rr}r(hJjhKjubaubj)r}r(hJX3 array( 'exifMetadata' => array( 'listener' => 'Imbo\EventListener\ExifMetadata', 'params' => array( 'allowedTags' => array('exif:*', 'date:*', 'png:gAMA'), ), ), ), // ... );hKjQhLhOhQjhS}r(jjXphpjjhX]hW]hU]hV]hZ]uh\Kh]hhE]rhfX3 array( 'exifMetadata' => array( 'listener' => 'Imbo\EventListener\ExifMetadata', 'params' => array( 'allowedTags' => array('exif:*', 'date:*', 'png:gAMA'), ), ), ), // ... );rr}r(hJUhKjubaubhj)r}r(hJXwhich would allow all ``exif`` and ``date`` properties as well as the ``png:gAMA`` property. If you want to store **all** tags as metadata, use ``array('*')`` as filter.rhKjQhLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\Kh]hhE]r(hfXwhich would allow all rr}r(hJXwhich would allow all hKjubh)r}r(hJX``exif``hS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfXexifrr}r(hJUhKjubahQhubhfX and rr}r(hJX and hKjubh)r}r(hJX``date``hS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfXdaterr}r(hJUhKjubahQhubhfX properties as well as the rr}r(hJX properties as well as the hKjubh)r}r(hJX ``png:gAMA``hS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfXpng:gAMArr}r(hJUhKjubahQhubhfX property. If you want to store r r }r (hJX property. If you want to store hKjubj)r }r (hJX**all**hS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfXallrr}r(hJUhKj ubahQjubhfX tags as metadata, use rr}r(hJX tags as metadata, use hKjubh)r}r(hJX``array('*')``hS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfX array('*')rr}r(hJUhKjubahQhubhfX as filter.rr}r(hJX as filter.hKjubeubeubhG)r }r!(hJUhKhHhLhOhQhRhS}r"(hU]hV]hW]hX]r#h>ahZ]r$hauh\Kh]hhE]r%(h_)r&}r'(hJjhKj hLhOhQhchS}r((hX]hW]hU]hV]hZ]jnj uh\Kh]hhE]r)hfXImage transformation cacher*r+}r,(hJjhKj&ubaubhj)r-}r.(hJXThis event listener enables caching of image transformations. Read more about image transformations in the :ref:`image-transformations` section.r/hKj hLhOhQhnhS}r0(hU]hV]hW]hX]hZ]uh\Kh]hhE]r1(hfXkThis event listener enables caching of image transformations. Read more about image transformations in the r2r3}r4(hJXkThis event listener enables caching of image transformations. Read more about image transformations in the hKj-ubht)r5}r6(hJX:ref:`image-transformations`r7hKj-hLhOhQhxhS}r8(UreftypeXrefh{h|Ximage-transformationsU refdomainXstdr9hX]hW]U refexplicithU]hV]hZ]h}h~uh\KhE]r:j)r;}r<(hJj7hS}r=(hU]hV]r>(hj9Xstd-refr?ehW]hX]hZ]uhKj5hE]r@hfXimage-transformationsrArB}rC(hJUhKj;ubahQjubaubhfX section.rDrE}rF(hJX section.hKj-ubeubhj)rG}rH(hJX@To achieve this the listener subscribes to the following events:rIhKj hLhOhQhnhS}rJ(hU]hV]hW]hX]hZ]uh\Kh]hhE]rKhfX@To achieve this the listener subscribes to the following events:rLrM}rN(hJjIhKjGubaubh)rO}rP(hJUhKj hLhOhQhhS}rQ(jX*hX]hW]hU]hV]hZ]uh\Kh]hhE]rR(h)rS}rT(hJX ``image.get``rUhKjOhLhOhQhhS}rV(hU]hV]hW]hX]hZ]uh\Nh]hhE]rWhj)rX}rY(hJjUhKjShLhOhQhnhS}rZ(hU]hV]hW]hX]hZ]uh\KhE]r[h)r\}r](hJjUhS}r^(hU]hV]hW]hX]hZ]uhKjXhE]r_hfX image.getr`ra}rb(hJUhKj\ubahQhubaubaubh)rc}rd(hJX``response.send``rehKjOhLhOhQhhS}rf(hU]hV]hW]hX]hZ]uh\Nh]hhE]rghj)rh}ri(hJjehKjchLhOhQhnhS}rj(hU]hV]hW]hX]hZ]uh\KhE]rkh)rl}rm(hJjehS}rn(hU]hV]hW]hX]hZ]uhKjhhE]rohfX response.sendrprq}rr(hJUhKjlubahQhubaubaubh)rs}rt(hJX``image.delete`` hKjOhLhOhQhhS}ru(hU]hV]hW]hX]hZ]uh\Nh]hhE]rvhj)rw}rx(hJX``image.delete``ryhKjshLhOhQhnhS}rz(hU]hV]hW]hX]hZ]uh\KhE]r{h)r|}r}(hJjyhS}r~(hU]hV]hW]hX]hZ]uhKjwhE]rhfX image.deleterr}r(hJUhKj|ubahQhubaubaubeubhj)r}r(hJX@The parameters for the event listener supports a single element:rhKj hLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\Kh]hhE]rhfX@The parameters for the event listener supports a single element:rr}r(hJjhKjubaubj)r}r(hJUhKj hLhOhQjhS}r(hU]hV]hW]hX]hZ]uh\Nh]hhE]rj)r}r(hJX;``path`` Root path where the cached images will be stored. hKjhLhOhQjhS}r(hU]hV]hW]hX]hZ]uh\KhE]r(j)r}r(hJX``path``rhKjhLhOhQjhS}r(hU]hV]hW]hX]hZ]uh\KhE]rh)r}r(hJjhS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfXpathrr}r(hJUhKjubahQhubaubj)r}r(hJUhS}r(hU]hV]hW]hX]hZ]uhKjhE]rhj)r}r(hJX1Root path where the cached images will be stored.rhKjhLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\KhE]rhfX1Root path where the cached images will be stored.rr}r(hJjhKjubaubahQjubeubaubhj)r}r(hJXand is enabled like this:rhKj hLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\Kh]hhE]rhfXand is enabled like this:rr}r(hJjhKjubaubj)r}r(hJX/ array( 'imageTransformationCache' => array( 'listener' => 'Imbo\EventListener\ImageTransformationCache', 'params' => array( 'path' => '/path/to/cache', ), ), ), // ... );hKj hLhOhQjhS}r(jjXphpjjhX]hW]hU]hV]hZ]uh\Kh]hhE]rhfX/ array( 'imageTransformationCache' => array( 'listener' => 'Imbo\EventListener\ImageTransformationCache', 'params' => array( 'path' => '/path/to/cache', ), ), ), // ... );rr}r(hJUhKjubaubcdocutils.nodes note r)r}r(hJXThis event listener uses a similar algorithm when generating file names as the :ref:`filesystem-storage-adapter` storage adapter.rhKj hLhOhQUnoterhS}r(hU]hV]hW]hX]hZ]uh\Nh]hhE]rhj)r}r(hJjhKjhLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\KhE]r(hfXOThis event listener uses a similar algorithm when generating file names as the rr}r(hJXOThis event listener uses a similar algorithm when generating file names as the hKjubht)r}r(hJX!:ref:`filesystem-storage-adapter`rhKjhLhOhQhxhS}r(UreftypeXrefh{h|Xfilesystem-storage-adapterU refdomainXstdrhX]hW]U refexplicithU]hV]hZ]h}h~uh\KhE]rj)r}r(hJjhS}r(hU]hV]r(hjXstd-refrehW]hX]hZ]uhKjhE]rhfXfilesystem-storage-adapterrr}r(hJUhKjubahQjubaubhfX storage adapter.rr}r(hJX storage adapter.hKjubeubaubcdocutils.nodes warning r)r}r(hJXIt can be wise to purge old files from the cache from time to time. If you have a large amount of images and present many different variations of these the cache will use up quite a lot of storage. An example on how to accomplish this: .. code-block:: bash $ find /path/to/cache -ctime +7 -type f -delete The above command will delete all files in ``/path/to/cache`` older than 7 days and can be used with for instance `crontab `_.hKj hLhOhQUwarningrhS}r(hU]hV]hW]hX]hZ]uh\Nh]hhE]r(hj)r}r(hJXIt can be wise to purge old files from the cache from time to time. If you have a large amount of images and present many different variations of these the cache will use up quite a lot of storage.rhKjhLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\KhE]rhfXIt can be wise to purge old files from the cache from time to time. If you have a large amount of images and present many different variations of these the cache will use up quite a lot of storage.rr}r(hJjhKjubaubhj)r}r(hJX%An example on how to accomplish this:rhKjhLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\KhE]rhfX%An example on how to accomplish this:rr}r(hJjhKjubaubj)r}r(hJX/$ find /path/to/cache -ctime +7 -type f -deletehKjhLhOhQjhS}r(jjXbashjjhX]hW]hU]hV]hZ]uh\MhE]rhfX/$ find /path/to/cache -ctime +7 -type f -deleterr}r(hJUhKjubaubhj)r}r(hJXThe above command will delete all files in ``/path/to/cache`` older than 7 days and can be used with for instance `crontab `_.hKjhLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\MhE]r(hfX+The above command will delete all files in rr}r(hJX+The above command will delete all files in hKjubh)r}r(hJX``/path/to/cache``hS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfX/path/to/cacherr}r(hJUhKjubahQhubhfX5 older than 7 days and can be used with for instance rr}r(hJX5 older than 7 days and can be used with for instance hKjubh)r}r (hJX.`crontab `_hS}r (Unameh j+X!http://en.wikipedia.org/wiki/Cronr hX]hW]hU]hV]hZ]uhKjhE]r hfXcrontabr r}r(hJUhKjubahQhubji)r}r(hJX$ j3KhKjhQjlhS}r(Urefurij hX]rh-ahW]hU]hV]hZ]rh auhE]ubhfX.r}r(hJX.hKjubeubeubji)r}r(hJX.. _imagick-event-listener:hKj hLhOhQjlhS}r(hX]hW]hU]hV]hZ]jnh6uh\Mh]hhE]ubeubhG)r}r(hJUhKhHhLhOjq}rhjshQhRhS}r(hU]hV]hW]hX]r(h.h6ehZ]r(h heuh\M h]hjv}r h6jshE]r!(h_)r"}r#(hJj hKjhLhOhQhchS}r$(hX]hW]hU]hV]hZ]jnjuh\M h]hhE]r%hfXImagickr&r'}r((hJj hKj"ubaubhj)r)}r*(hJX-This event listener is required by the image transformations that is included in Imbo, and there is no configuration options for it. Unless you plan on exchanging all the internal image transformations with your own (for instance implemented using Gmagick or GD) you are better off leaving this as-is.r+hKjhLhOhQhnhS}r,(hU]hV]hW]hX]hZ]uh\M h]hhE]r-hfX-This event listener is required by the image transformations that is included in Imbo, and there is no configuration options for it. Unless you plan on exchanging all the internal image transformations with your own (for instance implemented using Gmagick or GD) you are better off leaving this as-is.r.r/}r0(hJj+hKj)ubaubji)r1}r2(hJX".. _max-image-size-event-listener:hKjhLhOhQjlhS}r3(hX]hW]hU]hV]hZ]jnh:uh\Mh]hhE]ubeubhG)r4}r5(hJUhKhHhLhOjq}r6hj1shQhRhS}r7(hU]hV]hW]hX]r8(hBh:ehZ]r9(hheuh\Mh]hjv}r:h:j1shE]r;(h_)r<}r=(hJj2hKj4hLhOhQhchS}r>(hX]hW]hU]hV]hZ]jnj-uh\Mh]hhE]r?hfXMax image sizer@rA}rB(hJj2hKj<ubaubhj)rC}rD(hJXThis event listener can be used to enforce a maximum size (height and width, not byte size) of **new** images. Enabling this event listener will not change images already added to Imbo.rEhKj4hLhOhQhnhS}rF(hU]hV]hW]hX]hZ]uh\Mh]hhE]rG(hfX_This event listener can be used to enforce a maximum size (height and width, not byte size) of rHrI}rJ(hJX_This event listener can be used to enforce a maximum size (height and width, not byte size) of hKjCubj)rK}rL(hJX**new**hS}rM(hU]hV]hW]hX]hZ]uhKjChE]rNhfXnewrOrP}rQ(hJUhKjKubahQjubhfXS images. Enabling this event listener will not change images already added to Imbo.rRrS}rT(hJXS images. Enabling this event listener will not change images already added to Imbo.hKjCubeubhj)rU}rV(hJX5The event listener subscribes to the following event:rWhKj4hLhOhQhnhS}rX(hU]hV]hW]hX]hZ]uh\Mh]hhE]rYhfX5The event listener subscribes to the following event:rZr[}r\(hJjWhKjUubaubh)r]}r^(hJUhKj4hLhOhQhhS}r_(jX*hX]hW]hU]hV]hZ]uh\Mh]hhE]r`h)ra}rb(hJX``images.post`` hKj]hLhOhQhhS}rc(hU]hV]hW]hX]hZ]uh\Nh]hhE]rdhj)re}rf(hJX``images.post``rghKjahLhOhQhnhS}rh(hU]hV]hW]hX]hZ]uh\MhE]rih)rj}rk(hJjghS}rl(hU]hV]hW]hX]hZ]uhKjehE]rmhfX images.postrnro}rp(hJUhKjjubahQhubaubaubaubhj)rq}rr(hJX3and the parameters includes the following elements:rshKj4hLhOhQhnhS}rt(hU]hV]hW]hX]hZ]uh\Mh]hhE]ruhfX3and the parameters includes the following elements:rvrw}rx(hJjshKjqubaubj)ry}rz(hJUhKj4hLhOhQjhS}r{(hU]hV]hW]hX]hZ]uh\Nh]hhE]r|(j)r}}r~(hJXi``width`` The max width in pixels of new images. If a new image exceeds this limit it will be downsized. hKjyhLhOhQjhS}r(hU]hV]hW]hX]hZ]uh\MhE]r(j)r}r(hJX ``width``rhKj}hLhOhQjhS}r(hU]hV]hW]hX]hZ]uh\MhE]rh)r}r(hJjhS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfXwidthrr}r(hJUhKjubahQhubaubj)r}r(hJUhS}r(hU]hV]hW]hX]hZ]uhKj}hE]rhj)r}r(hJX^The max width in pixels of new images. If a new image exceeds this limit it will be downsized.rhKjhLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\MhE]rhfX^The max width in pixels of new images. If a new image exceeds this limit it will be downsized.rr}r(hJjhKjubaubahQjubeubj)r}r(hJXk``height`` The max height in pixels of new images. If a new image exceeds this limit it will be downsized. hKjyhLhOhQjhS}r(hU]hV]hW]hX]hZ]uh\Mh]hhE]r(j)r}r(hJX ``height``rhKjhLhOhQjhS}r(hU]hV]hW]hX]hZ]uh\MhE]rh)r}r(hJjhS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfXheightrr}r(hJUhKjubahQhubaubj)r}r(hJUhS}r(hU]hV]hW]hX]hZ]uhKjhE]rhj)r}r(hJX_The max height in pixels of new images. If a new image exceeds this limit it will be downsized.rhKjhLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\MhE]rhfX_The max height in pixels of new images. If a new image exceeds this limit it will be downsized.rr}r(hJjhKjubaubahQjubeubeubhj)r}r(hJXand is enabled like this:rhKj4hLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\M!h]hhE]rhfXand is enabled like this:rr}r(hJjhKjubaubj)r}r(hJX5 array( 'maxImageSizeListener' => array( 'listener' => 'Imbo\EventListener\MaxImageSize', 'params' => array( 'width' => 1024, 'height' => 768, ), ), ), // ... );hKj4hLhOhQjhS}r(jjXphpjjhX]hW]hU]hV]hZ]uh\M#h]hhE]rhfX5 array( 'maxImageSizeListener' => array( 'listener' => 'Imbo\EventListener\MaxImageSize', 'params' => array( 'width' => 1024, 'height' => 768, ), ), ), // ... );rr}r(hJUhKjubaubhj)r}r(hJXwhich would effectively downsize all images exceeding a ``width`` of ``1024`` or a ``height`` of ``768``. The aspect ratio will be kept.rhKj4hLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\M6h]hhE]r(hfX8which would effectively downsize all images exceeding a rr}r(hJX8which would effectively downsize all images exceeding a hKjubh)r}r(hJX ``width``hS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfXwidthrr}r(hJUhKjubahQhubhfX of rr}r(hJX of hKjubh)r}r(hJX``1024``hS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfX1024rr}r(hJUhKjubahQhubhfX or a rr}r(hJX or a hKjubh)r}r(hJX ``height``hS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfXheightrr}r(hJUhKjubahQhubhfX of rr}r(hJX of hKjubh)r}r(hJX``768``hS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfX768rr}r(hJUhKjubahQhubhfX . The aspect ratio will be kept.rr}r(hJX . The aspect ratio will be kept.hKjubeubeubhG)r}r(hJUhKhHhLhOhQhRhS}r(hU]hV]hW]hX]rh=ahZ]rhauh\M9h]hhE]r(h_)r}r(hJjDhKjhLhOhQhchS}r(hX]hW]hU]hV]hZ]jnj?uh\M9h]hhE]rhfXMetadata cacherr}r(hJjDhKjubaubhj)r}r(hJXThis event listener enables caching of metadata fetched from the backend so other requests won't need to go all the way to the metadata backend to fetch it. To achieve this the listener subscribes to the following events:rhKjhLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\M;h]hhE]rhfXThis event listener enables caching of metadata fetched from the backend so other requests won't need to go all the way to the metadata backend to fetch it. To achieve this the listener subscribes to the following events:rr}r(hJjhKjubaubh)r }r (hJUhKjhLhOhQhhS}r (jX*hX]hW]hU]hV]hZ]uh\M=h]hhE]r (h)r }r(hJX``db.metadata.load``rhKj hLhOhQhhS}r(hU]hV]hW]hX]hZ]uh\Nh]hhE]rhj)r}r(hJjhKj hLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\M=hE]rh)r}r(hJjhS}r(hU]hV]hW]hX]hZ]uhKjhE]rhfXdb.metadata.loadrr}r(hJUhKjubahQhubaubaubh)r}r(hJX``db.metadata.delete``rhKj hLhOhQhhS}r (hU]hV]hW]hX]hZ]uh\Nh]hhE]r!hj)r"}r#(hJjhKjhLhOhQhnhS}r$(hU]hV]hW]hX]hZ]uh\M>hE]r%h)r&}r'(hJjhS}r((hU]hV]hW]hX]hZ]uhKj"hE]r)hfXdb.metadata.deleter*r+}r,(hJUhKj&ubahQhubaubaubh)r-}r.(hJX``db.metadata.update``r/hKj hLhOhQhhS}r0(hU]hV]hW]hX]hZ]uh\Nh]hhE]r1hj)r2}r3(hJj/hKj-hLhOhQhnhS}r4(hU]hV]hW]hX]hZ]uh\M?hE]r5h)r6}r7(hJj/hS}r8(hU]hV]hW]hX]hZ]uhKj2hE]r9hfXdb.metadata.updater:r;}r<(hJUhKj6ubahQhubaubaubh)r=}r>(hJX``db.image.delete`` hKj hLhOhQhhS}r?(hU]hV]hW]hX]hZ]uh\Nh]hhE]r@hj)rA}rB(hJX``db.image.delete``rChKj=hLhOhQhnhS}rD(hU]hV]hW]hX]hZ]uh\M@hE]rEh)rF}rG(hJjChS}rH(hU]hV]hW]hX]hZ]uhKjAhE]rIhfXdb.image.deleterJrK}rL(hJUhKjFubahQhubaubaubeubhj)rM}rN(hJX-and the parameters supports a single element:rOhKjhLhOhQhnhS}rP(hU]hV]hW]hX]hZ]uh\MBh]hhE]rQhfX-and the parameters supports a single element:rRrS}rT(hJjOhKjMubaubj)rU}rV(hJUhKjhLhOhQjhS}rW(hU]hV]hW]hX]hZ]uh\Nh]hhE]rXj)rY}rZ(hJX``cache`` An instance of a cache adapter. Imbo ships with :ref:`apc-cache` and :ref:`memcached-cache` adapters, and both can be used for this event listener. If you want to use another form of caching you can simply implement the ``Imbo\Cache\CacheInterface`` interface and pass an instance of the custom adapter to the constructor of the event listener. See the :ref:`custom-cache-adapter` section for more information regarding this. Here is an example that uses the APC adapter for caching: hKjUhLhOhQjhS}r[(hU]hV]hW]hX]hZ]uh\MEhE]r\(j)r]}r^(hJX ``cache``r_hKjYhLhOhQjhS}r`(hU]hV]hW]hX]hZ]uh\MEhE]rah)rb}rc(hJj_hS}rd(hU]hV]hW]hX]hZ]uhKj]hE]rehfXcacherfrg}rh(hJUhKjbubahQhubaubj)ri}rj(hJUhS}rk(hU]hV]hW]hX]hZ]uhKjYhE]rlhj)rm}rn(hJXAn instance of a cache adapter. Imbo ships with :ref:`apc-cache` and :ref:`memcached-cache` adapters, and both can be used for this event listener. If you want to use another form of caching you can simply implement the ``Imbo\Cache\CacheInterface`` interface and pass an instance of the custom adapter to the constructor of the event listener. See the :ref:`custom-cache-adapter` section for more information regarding this. Here is an example that uses the APC adapter for caching:hKjihLhOhQhnhS}ro(hU]hV]hW]hX]hZ]uh\MEhE]rp(hfX0An instance of a cache adapter. Imbo ships with rqrr}rs(hJX0An instance of a cache adapter. Imbo ships with hKjmubht)rt}ru(hJX:ref:`apc-cache`rvhKjmhLhOhQhxhS}rw(UreftypeXrefh{h|X apc-cacheU refdomainXstdrxhX]hW]U refexplicithU]hV]hZ]h}h~uh\MEhE]ryj)rz}r{(hJjvhS}r|(hU]hV]r}(hjxXstd-refr~ehW]hX]hZ]uhKjthE]rhfX apc-cacherr}r(hJUhKjzubahQjubaubhfX and rr}r(hJX and hKjmubht)r}r(hJX:ref:`memcached-cache`rhKjmhLhOhQhxhS}r(UreftypeXrefh{h|Xmemcached-cacheU refdomainXstdrhX]hW]U refexplicithU]hV]hZ]h}h~uh\MEhE]rj)r}r(hJjhS}r(hU]hV]r(hjXstd-refrehW]hX]hZ]uhKjhE]rhfXmemcached-cacherr}r(hJUhKjubahQjubaubhfX adapters, and both can be used for this event listener. If you want to use another form of caching you can simply implement the rr}r(hJX adapters, and both can be used for this event listener. If you want to use another form of caching you can simply implement the hKjmubh)r}r(hJX``Imbo\Cache\CacheInterface``hS}r(hU]hV]hW]hX]hZ]uhKjmhE]rhfXImbo\Cache\CacheInterfacerr}r(hJUhKjubahQhubhfXh interface and pass an instance of the custom adapter to the constructor of the event listener. See the rr}r(hJXh interface and pass an instance of the custom adapter to the constructor of the event listener. See the hKjmubht)r}r(hJX:ref:`custom-cache-adapter`rhKjmhLhOhQhxhS}r(UreftypeXrefh{h|Xcustom-cache-adapterU refdomainXstdrhX]hW]U refexplicithU]hV]hZ]h}h~uh\MEhE]rj)r}r(hJjhS}r(hU]hV]r(hjXstd-refrehW]hX]hZ]uhKjhE]rhfXcustom-cache-adapterrr}r(hJUhKjubahQjubaubhfXg section for more information regarding this. Here is an example that uses the APC adapter for caching:rr}r(hJXg section for more information regarding this. Here is an example that uses the APC adapter for caching:hKjmubeubahQjubeubaubj)r}r(hJX$ array( 'metadataCache' => array( 'listener' => 'Imbo\EventListener\MetadataCache', 'params' => array( 'cache' => new Imbo\Cache\APC('imbo'), ), ), ), // ... );hKjhLhOhQjhS}r(jjXphpjjhX]hW]hU]hV]hZ]uh\MGh]hhE]rhfX$ array( 'metadataCache' => array( 'listener' => 'Imbo\EventListener\MetadataCache', 'params' => array( 'cache' => new Imbo\Cache\APC('imbo'), ), ), ), // ... );rr}r(hJUhKjubaubji)r}r(hJX .. _stats-access-event-listener:hKjhLhOhQjlhS}r(hX]hW]hU]hV]hZ]jnhAuh\MZh]hhE]ubeubhG)r}r(hJUhKhHhLhOjq}rhjshQhRhS}r(hU]hV]hW]hX]r(h*hAehZ]r(hheuh\M]h]hjv}rhAjshE]r(h_)r}r(hJjVhKjhLhOhQhchS}r(hX]hW]hU]hV]hZ]jnjQuh\M]h]hhE]rhfX Stats accessrr}r(hJjVhKjubaubhj)r}r(hJXThis event listener controls the access to the :ref:`stats resource ` by using white listing of IPv4 and/or IPv6 addresses. `CIDR-notations `_ are also supported.rhKjhLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\M_h]hhE]r(hfX/This event listener controls the access to the rr}r(hJX/This event listener controls the access to the hKjubht)r}r(hJX&:ref:`stats resource `rhKjhLhOhQhxhS}r(UreftypeXrefh{h|Xstats-resourceU refdomainXstdrhX]hW]U refexplicithU]hV]hZ]h}h~uh\M_hE]rj)r}r(hJjhS}r(hU]hV]r(hjXstd-refrehW]hX]hZ]uhKjhE]rhfXstats resourcerr}r(hJUhKjubahQjubaubhfX7 by using white listing of IPv4 and/or IPv6 addresses. rr}r(hJX7 by using white listing of IPv4 and/or IPv6 addresses. hKjubh)r}r(hJXC`CIDR-notations `_hS}r(UnameXCIDR-notationsj+X/http://en.wikipedia.org/wiki/CIDR#CIDR_notationrhX]hW]hU]hV]hZ]uhKjhE]rhfXCIDR-notationsrr}r(hJUhKjubahQhubji)r}r(hJX2 j3KhKjhQjlhS}r(UrefurijhX]rh/ahW]hU]hV]hZ]rh auhE]ubhfX are also supported.rr}r(hJX are also supported.hKjubeubhj)r}r(hJXiThis listener is enabled per default, and only allows ``127.0.0.1`` and ``::1`` to access the statistics:rhKjhLhOhQhnhS}r(hU]hV]hW]hX]hZ]uh\Mah]hhE]r(hfX6This listener is enabled per default, and only allows rr}r(hJX6This listener is enabled per default, and only allows hKjubh)r}r (hJX ``127.0.0.1``hS}r (hU]hV]hW]hX]hZ]uhKjhE]r hfX 127.0.0.1r r }r (hJUhKjubahQhubhfX and r r }r (hJX and hKjubh)r }r (hJX``::1``hS}r (hU]hV]hW]hX]hZ]uhKjhE]r hfX::1r r }r (hJUhKj ubahQhubhfX to access the statistics:r r }r (hJX to access the statistics:hKjubeubj)r }r (hJX array( 'statsAccess' => array( 'listener' => 'Imbo\EventListener\StatsAccess', 'params' => array( 'allow' => array('127.0.0.1', '::1'), ), ), ), // ... );hKjhLhOhQjhS}r (jjXphpjjhX]hW]hU]hV]hZ]uh\Mch]hhE]r hfX array( 'statsAccess' => array( 'listener' => 'Imbo\EventListener\StatsAccess', 'params' => array( 'allow' => array('127.0.0.1', '::1'), ), ), ), // ... );r r }r (hJUhKj ubaubhj)r }r (hJXpThe event listener also supports a notation for "allowing all", simply by placing ``'*'`` somewhere in the list:r hKjhLhOhQhnhS}r (hU]hV]hW]hX]hZ]uh\Muh]hhE]r (hfXRThe event listener also supports a notation for "allowing all", simply by placing r r }r! (hJXRThe event listener also supports a notation for "allowing all", simply by placing hKj ubh)r" }r# (hJX``'*'``hS}r$ (hU]hV]hW]hX]hZ]uhKj hE]r% hfX'*'r& r' }r( (hJUhKj" ubahQhubhfX somewhere in the list:r) r* }r+ (hJX somewhere in the list:hKj ubeubj)r, }r- (hJX= array( 'statsAccess' => array( 'listener' => 'Imbo\EventListener\StatsAccess', 'params' => array( array( 'allow' => array('*'), ) ), ), ), // ... );hKjhLhOhQjhS}r. (jjXphpjjhX]hW]hU]hV]hZ]uh\Mwh]hhE]r/ hfX= array( 'statsAccess' => array( 'listener' => 'Imbo\EventListener\StatsAccess', 'params' => array( array( 'allow' => array('*'), ) ), ), ), // ... );r0 r1 }r2 (hJUhKj, ubaubhj)r3 }r4 (hJXBThe above example will allow all clients access to the statistics.r5 hKjhLhOhQhnhS}r6 (hU]hV]hW]hX]hZ]uh\Mh]hhE]r7 hfXBThe above example will allow all clients access to the statistics.r8 r9 }r: (hJj5 hKj3 ubaubcdocutils.nodes comment r; )r< }r= (hJXnote: If you choose to override the configuration, remember to add the default values if you also want them, as your configuration will override the default configuration completely.hKjhLhOhQUcommentr> hS}r? (jjhX]hW]hU]hV]hZ]uh\Mh]hhE]r@ hfXnote: If you choose to override the configuration, remember to add the default values if you also want them, as your configuration will override the default configuration completely.rA rB }rC (hJUhKj< ubaubeubhG)rD }rE (hJUhKhHhLhOhQhRhS}rF (hU]hV]hW]hX]rG h3ahZ]rH hauh\Mh]hhE]rI (h_)rJ }rK (hJjhhKjD hLhOhQhchS}rL (hX]hW]hU]hV]hZ]jnjcuh\Mh]hhE]rM hfXVarnish HashTworN rO }rP (hJjhhKjJ ubaubhj)rQ }rR (hJX~This event listener can be enabled if you want Imbo to include `HashTwo headers `_ in responses to image requests. These headers can be used by `Varnish `_ for more effective cache invalidation strategies. The listener, when enabled, subscribes to the following events:rS hKjD hLhOhQhnhS}rT (hU]hV]hW]hX]hZ]uh\Mh]hhE]rU (hfX?This event listener can be enabled if you want Imbo to include rV rW }rX (hJX?This event listener can be enabled if you want Imbo to include hKjQ ubh)rY }rZ (hJXa`HashTwo headers `_hS}r[ (UnameXHashTwo headersj+XLhttps://www.varnish-software.com/blog/advanced-cache-invalidation-strategiesr\ hX]hW]hU]hV]hZ]uhKjQ hE]r] hfXHashTwo headersr^ r_ }r` (hJUhKjY ubahQhubji)ra }rb (hJXO j3KhKjQ hQjlhS}rc (Urefurij\ hX]rd h@ahW]hU]hV]hZ]re hauhE]ubhfX> in responses to image requests. These headers can be used by rf rg }rh (hJX> in responses to image requests. These headers can be used by hKjQ ubh)ri }rj (hJX.`Varnish `_hS}rk (UnameXVarnishj+X!https://www.varnish-software.com/rl hX]hW]hU]hV]hZ]uhKjQ hE]rm hfXVarnishrn ro }rp (hJUhKji ubahQhubji)rq }rr (hJX$ j3KhKjQ hQjlhS}rs (Urefurijl hX]rt h4ahW]hU]hV]hZ]ru hauhE]ubhfXr for more effective cache invalidation strategies. The listener, when enabled, subscribes to the following events:rv rw }rx (hJXr for more effective cache invalidation strategies. The listener, when enabled, subscribes to the following events:hKjQ ubeubh)ry }rz (hJUhKjD hLhOhQhhS}r{ (jX*hX]hW]hU]hV]hZ]uh\Mh]hhE]r| (h)r} }r~ (hJX ``image.get``r hKjy hLhOhQhhS}r (hU]hV]hW]hX]hZ]uh\Nh]hhE]r hj)r }r (hJj hKj} hLhOhQhnhS}r (hU]hV]hW]hX]hZ]uh\MhE]r h)r }r (hJj hS}r (hU]hV]hW]hX]hZ]uhKj hE]r hfX image.getr r }r (hJUhKj ubahQhubaubaubh)r }r (hJX``image.head`` hKjy hLhOhQhhS}r (hU]hV]hW]hX]hZ]uh\Nh]hhE]r hj)r }r (hJX``image.head``r hKj hLhOhQhnhS}r (hU]hV]hW]hX]hZ]uh\MhE]r h)r }r (hJj hS}r (hU]hV]hW]hX]hZ]uhKj hE]r hfX image.headr r }r (hJUhKj ubahQhubaubaubeubhj)r }r (hJX)The parameters supports a single element:r hKjD hLhOhQhnhS}r (hU]hV]hW]hX]hZ]uh\Mh]hhE]r hfX)The parameters supports a single element:r r }r (hJj hKj ubaubj)r }r (hJUhKjD hLhOhQjhS}r (hU]hV]hW]hX]hZ]uh\Nh]hhE]r j)r }r (hJXF``headerName`` Set the header name to use. Defaults to ``X-HashTwo``. hKj hLhOhQjhS}r (hU]hV]hW]hX]hZ]uh\MhE]r (j)r }r (hJX``headerName``r hKj hLhOhQjhS}r (hU]hV]hW]hX]hZ]uh\MhE]r h)r }r (hJj hS}r (hU]hV]hW]hX]hZ]uhKj hE]r hfX headerNamer r }r (hJUhKj ubahQhubaubj)r }r (hJUhS}r (hU]hV]hW]hX]hZ]uhKj hE]r hj)r }r (hJX6Set the header name to use. Defaults to ``X-HashTwo``.r hKj hLhOhQhnhS}r (hU]hV]hW]hX]hZ]uh\MhE]r (hfX(Set the header name to use. Defaults to r r }r (hJX(Set the header name to use. Defaults to hKj ubh)r }r (hJX ``X-HashTwo``hS}r (hU]hV]hW]hX]hZ]uhKj hE]r hfX X-HashTwor r }r (hJUhKj ubahQhubhfX.r }r (hJX.hKj ubeubahQjubeubaubj)r }r (hJX array( 'hashTwo' => 'Imbo\EventListener\VarnishHashTwo', ), // ... );hKjD hLhOhQjhS}r (jjXphpjjhX]hW]hU]hV]hZ]uh\Mh]hhE]r hfX array( 'hashTwo' => 'Imbo\EventListener\VarnishHashTwo', ), // ... );r r }r (hJUhKj ubaubhj)r }r (hJX1or, if you want to use a non-default header name:r hKjD hLhOhQhnhS}r (hU]hV]hW]hX]hZ]uh\Mh]hhE]r hfX1or, if you want to use a non-default header name:r r }r (hJj hKj ubaubj)r }r (hJX( array( 'hashTwo' => array( 'listener' => 'Imbo\EventListener\VarnishHashTwo', 'params' => array( 'headerName' => 'X-Custom-HashTwo-Header-Name', ), ), ), // ... );hKjD hLhOhQjhS}r (jjXphpjjhX]hW]hU]hV]hZ]uh\Mh]hhE]r hfX( array( 'hashTwo' => array( 'listener' => 'Imbo\EventListener\VarnishHashTwo', 'params' => array( 'headerName' => 'X-Custom-HashTwo-Header-Name', ), ), ), // ... );r r }r (hJUhKj ubaubhj)r }r (hJXSThe header appears multiple times in the response, with slightly different values::r hKjD hLhOhQhnhS}r (hU]hV]hW]hX]hZ]uh\Mh]hhE]r hfXRThe header appears multiple times in the response, with slightly different values:r r }r (hJXRThe header appears multiple times in the response, with slightly different values:hKj ubaubj)r }r (hJXTX-HashTwo: imbo;image;; X-HashTwo: imbo;user;hKjD hLhOhQjhS}r (jjhX]hW]hU]hV]hZ]uh\Mh]hhE]r hfXTX-HashTwo: imbo;image;; X-HashTwo: imbo;user;r r }r (hJUhKj ubaubeubeubahJUU transformerr NU footnote_refsr }r Urefnamesr }r Usymbol_footnotesr ]r Uautofootnote_refsr ]r Usymbol_footnote_refsr ]r U citationsr ]r h]hU current_liner NUtransform_messagesr ]r (cdocutils.nodes system_message r )r }r (hJUhS}r (hU]UlevelKhX]hW]UsourcehOhV]hZ]UlineK UtypeUINFOr uhE]r hj)r }r (hJUhS}r (hU]hV]hW]hX]hZ]uhKj hE]r hfXAHyperlink target "access-token-event-listener" is not referenced.r r }r (hJUhKj ubahQhnubahQUsystem_messager ubj )r }r (hJUhS}r (hU]UlevelKhX]hW]UsourcehOhV]hZ]UlineKKUtypej uhE]r hj)r }r (hJUhS}r (hU]hV]hW]hX]hZ]uhKj hE]r hfXAHyperlink target "authenticate-event-listener" is not referenced.r r }r (hJUhKj ubahQhnubahQj ubj )r }r (hJUhS}r (hU]UlevelKhX]hW]UsourcehOhV]hZ]UlineKkUtypej uhE]r hj)r }r! (hJUhS}r" (hU]hV]hW]hX]hZ]uhKj hE]r# hfXFHyperlink target "auto-rotate-image-event-listener" is not referenced.r$ r% }r& (hJUhKj ubahQhnubahQj ubj )r' }r( (hJUhS}r) (hU]UlevelKhX]hW]UsourcehOhV]hZ]UlineKUtypej uhE]r* hj)r+ }r, (hJUhS}r- (hU]hV]hW]hX]hZ]uhKj' hE]r. hfX9Hyperlink target "cors-event-listener" is not referenced.r/ r0 }r1 (hJUhKj+ ubahQhnubahQj ubj )r2 }r3 (hJUhS}r4 (hU]UlevelKhX]hW]UsourcehOhV]hZ]UlineMUtypej uhE]r5 hj)r6 }r7 (hJUhS}r8 (hU]hV]hW]hX]hZ]uhKj2 hE]r9 hfX<Hyperlink target "imagick-event-listener" is not referenced.r: r; }r< (hJUhKj6 ubahQhnubahQj ubj )r= }r> (hJUhS}r? (hU]UlevelKhX]hW]UsourcehOhV]hZ]UlineMUtypej uhE]r@ hj)rA }rB (hJUhS}rC (hU]hV]hW]hX]hZ]uhKj= hE]rD hfXCHyperlink target "max-image-size-event-listener" is not referenced.rE rF }rG (hJUhKjA ubahQhnubahQj ubj )rH }rI (hJUhS}rJ (hU]UlevelKhX]hW]UsourcehOhV]hZ]UlineMZUtypej uhE]rK hj)rL }rM (hJUhS}rN (hU]hV]hW]hX]hZ]uhKjH hE]rO hfXAHyperlink target "stats-access-event-listener" is not referenced.rP rQ }rR (hJUhKjL ubahQhnubahQj ubeUreporterrS NUid_startrT K U autofootnotesrU ]rV U citation_refsrW }rX Uindirect_targetsrY ]rZ Usettingsr[ (cdocutils.frontend Values r\ or] }r^ (Ufootnote_backlinksr_ KUrecord_dependenciesr` NU rfc_base_urlra Uhttp://tools.ietf.org/html/rb U tracebackrc Upep_referencesrd NUstrip_commentsre NU toc_backlinksrf Uentryrg U language_coderh Uenri U datestamprj NU report_levelrk KU _destinationrl NU halt_levelrm KU strip_classesrn NhcNUerror_encoding_error_handlerro Ubackslashreplacerp Udebugrq NUembed_stylesheetrr Uoutput_encoding_error_handlerrs Ustrictrt U sectnum_xformru KUdump_transformsrv NU docinfo_xformrw KUwarning_streamrx NUpep_file_url_templatery Upep-%04drz Uexit_status_levelr{ KUconfigr| NUstrict_visitorr} NUcloak_email_addressesr~ Utrim_footnote_reference_spacer Uenvr NUdump_pseudo_xmlr NUexpose_internalsr NUsectsubtitle_xformr U source_linkr NUrfc_referencesr NUoutput_encodingr Uutf-8r U source_urlr NUinput_encodingr U utf-8-sigr U_disable_configr NU id_prefixr UU tab_widthr KUerror_encodingr UUTF-8r U_sourcer UQ/var/build/user_builds/imbo/checkouts/1.1.1/docs/installation/event_listeners.rstr Ugettext_compactr U generatorr NUdump_internalsr NU smart_quotesr U pep_base_urlr Uhttp://www.python.org/dev/peps/r Usyntax_highlightr Ulongr Uinput_encoding_error_handlerr jt Uauto_id_prefixr Uidr Udoctitle_xformr Ustrip_elements_with_classesr NU _config_filesr ]Ufile_insertion_enabledr U raw_enabledr KU dump_settingsr NubUsymbol_footnote_startr KUidsr }r (hhh+jh-jh2hHh;jQh.jhBj4h1hh4jq h5j=h6jh7j j?j;j jjjhhhhhhh,johhjQjMjcj_h9j.h:j4h3jD h*jh0j.hj h8jj-j)hAjh/jhCjohDj1h@ja uUsubstitution_namesr }r hQh]hS}r (hU]hX]hW]UsourcehOhV]hZ]uU footnotesr ]r Urefidsr }r (h6]r jahA]r jah9]r j+ah:]r j1ah+]r jah<]r j:ahC]r jjauub.PKrNDZ!!6imbo-1.1.1/.doctrees/installation/requirements.doctreecdocutils.nodes document q)q}q(U nametypesq}q(X requirementsqNXmongoqXmongodbqXgridfsq Xlighttpdq Xnginxq Ximagickq X#doctrine database abstraction layerq X php >= 5.4qXmysqlqXapachequUsubstitution_defsq}qUparse_messagesq]qUcurrent_sourceqNU decorationqNUautofootnote_startqKUnameidsq}q(hU requirementsqhUmongoqhUmongodbqh Ugridfsqh Ulighttpdqh Unginxqh Uimagickq h U#doctrine-database-abstraction-layerq!hUphp-5-4q"hUmysqlq#hUapacheq$uUchildrenq%]q&cdocutils.nodes section q')q(}q)(U rawsourceq*UUparentq+hUsourceq,cdocutils.nodes reprunicode q-XN/var/build/user_builds/imbo/checkouts/1.1.1/docs/installation/requirements.rstq.q/}q0bUtagnameq1Usectionq2U attributesq3}q4(Udupnamesq5]Uclassesq6]Ubackrefsq7]Uidsq8]q9haUnamesq:]q;hauUlineq(cdocutils.nodes title q?)q@}qA(h*X RequirementsqBh+h(h,h/h1UtitleqCh3}qD(h5]h6]h7]h8]h:]uh`_, `Nginx `_ or `Lighttpd `_) running `PHP >= 5.4 `_ and the `Imagick `_ extension for PHP.qMh+h(h,h/h1U paragraphqNh3}qO(h5]h6]h7]h8]h:]uh`_h3}qW(UnameXApacheUrefuriqXXhttp://httpd.apache.org/qYh8]h7]h5]h6]h:]uh+hKh%]qZhFXApacheq[q\}q](h*Uh+hUubah1U referenceq^ubcdocutils.nodes target q_)q`}qa(h*X U referencedqbKh+hKh1Utargetqch3}qd(UrefurihYh8]qeh$ah7]h5]h6]h:]qfhauh%]ubhFX, qgqh}qi(h*X, h+hKubhT)qj}qk(h*X`Nginx `_h3}ql(UnameXNginxhXXhttp://nginx.org/en/qmh8]h7]h5]h6]h:]uh+hKh%]qnhFXNginxqoqp}qq(h*Uh+hjubah1h^ubh_)qr}qs(h*X hbKh+hKh1hch3}qt(Urefurihmh8]quhah7]h5]h6]h:]qvh auh%]ubhFX or qwqx}qy(h*X or h+hKubhT)qz}q{(h*X&`Lighttpd `_h3}q|(UnameXLighttpdhXXhttp://www.lighttpd.net/q}h8]h7]h5]h6]h:]uh+hKh%]q~hFXLighttpdqq}q(h*Uh+hzubah1h^ubh_)q}q(h*X hbKh+hKh1hch3}q(Urefurih}h8]qhah7]h5]h6]h:]qh auh%]ubhFX ) running qq}q(h*X ) running h+hKubhT)q}q(h*X`PHP >= 5.4 `_h3}q(UnameX PHP >= 5.4hXXhttp://php.netqh8]h7]h5]h6]h:]uh+hKh%]qhFX PHP >= 5.4qq}q(h*Uh+hubah1h^ubh_)q}q(h*X hbKh+hKh1hch3}q(Urefurihh8]qh"ah7]h5]h6]h:]qhauh%]ubhFX and the qq}q(h*X and the h+hKubhT)q}q(h*X0`Imagick `_h3}q(UnameXImagickhXX#http://pecl.php.net/package/imagickqh8]h7]h5]h6]h:]uh+hKh%]qhFXImagickqq}q(h*Uh+hubah1h^ubh_)q}q(h*X& hbKh+hKh1hch3}q(Urefurihh8]qh ah7]h5]h6]h:]qh auh%]ubhFX extension for PHP.qq}q(h*X extension for PHP.h+hKubeubhJ)q}q(h*X:You will also need a backend for storing image information, like for instance `MongoDB `_ or `MySQL `_. If you want to use MongoDB as a database and/or `GridFS `_ for storage, you will need to install the `Mongo `_ PECL extension, and if you want to use a :abbr:`RDBMS (Relational Database Management System)` like MySQL, you will need to install the `Doctrine Database Abstraction Layer `_.qh+h(h,h/h1hNh3}q(h5]h6]h7]h8]h:]uh`_h3}q(UnameXMongoDBhXXhttp://www.mongodb.org/qh8]h7]h5]h6]h:]uh+hh%]qhFXMongoDBqq}q(h*Uh+hubah1h^ubh_)q}q(h*X hbKh+hh1hch3}q(Urefurihh8]qhah7]h5]h6]h:]qhauh%]ubhFX or qq}q(h*X or h+hubhT)q}q(h*X`MySQL `_h3}q(UnameXMySQLhXXhttp://www.mysql.comqh8]h7]h5]h6]h:]uh+hh%]qhFXMySQLqDžq}q(h*Uh+hubah1h^ubh_)q}q(h*X hbKh+hh1hch3}q(Urefurihh8]qh#ah7]h5]h6]h:]qhauh%]ubhFX2. If you want to use MongoDB as a database and/or qυq}q(h*X2. If you want to use MongoDB as a database and/or h+hubhT)q}q(h*X7`GridFS `_h3}q(UnameXGridFShXX+http://docs.mongodb.org/manual/core/gridfs/qh8]h7]h5]h6]h:]uh+hh%]qhFXGridFSqׅq}q(h*Uh+hubah1h^ubh_)q}q(h*X. hbKh+hh1hch3}q(Urefurihh8]qhah7]h5]h6]h:]qh auh%]ubhFX+ for storage, you will need to install the q߅q}q(h*X+ for storage, you will need to install the h+hubhT)q}q(h*X,`Mongo `_h3}q(UnameXMongohXX!http://pecl.php.net/package/mongoqh8]h7]h5]h6]h:]uh+hh%]qhFXMongoq煁q}q(h*Uh+hubah1h^ubh_)q}q(h*X$ hbKh+hh1hch3}q(Urefurihh8]qhah7]h5]h6]h:]qhauh%]ubhFX* PECL extension, and if you want to use a qq}q(h*X* PECL extension, and if you want to use a h+hubcsphinx.addnodes abbreviation q)q}q(h*XRDBMSh3}q(U explanationX%Relational Database Management Systemh8]h7]h5]h6]h:]uh+hh%]qhFXRDBMSqq}q(h*Uh+hubah1U abbreviationqubhFX* like MySQL, you will need to install the qq}q(h*X* like MySQL, you will need to install the h+hubhT)q}q(h*X[`Doctrine Database Abstraction Layer `_h3}r(UnameX#Doctrine Database Abstraction LayerhXX2http://www.doctrine-project.org/projects/dbal.htmlrh8]h7]h5]h6]h:]uh+hh%]rhFX#Doctrine Database Abstraction Layerrr}r(h*Uh+hubah1h^ubh_)r}r(h*X5 hbKh+hh1hch3}r(Urefurijh8]r h!ah7]h5]h6]h:]r h auh%]ubhFX.r }r (h*X.h+hubeubeubah*UU transformerr NU footnote_refsr}rUrefnamesr}rUsymbol_footnotesr]rUautofootnote_refsr]rUsymbol_footnote_refsr]rU citationsr]rh=hU current_linerNUtransform_messagesr]rUreporterrNUid_startrKU autofootnotesr]r U citation_refsr!}r"Uindirect_targetsr#]r$Usettingsr%(cdocutils.frontend Values r&or'}r((Ufootnote_backlinksr)KUrecord_dependenciesr*NU rfc_base_urlr+Uhttp://tools.ietf.org/html/r,U tracebackr-Upep_referencesr.NUstrip_commentsr/NU toc_backlinksr0Uentryr1U language_coder2Uenr3U datestampr4NU report_levelr5KU _destinationr6NU halt_levelr7KU strip_classesr8NhCNUerror_encoding_error_handlerr9Ubackslashreplacer:Udebugr;NUembed_stylesheetr<Uoutput_encoding_error_handlerr=Ustrictr>U sectnum_xformr?KUdump_transformsr@NU docinfo_xformrAKUwarning_streamrBNUpep_file_url_templaterCUpep-%04drDUexit_status_levelrEKUconfigrFNUstrict_visitorrGNUcloak_email_addressesrHUtrim_footnote_reference_spacerIUenvrJNUdump_pseudo_xmlrKNUexpose_internalsrLNUsectsubtitle_xformrMU source_linkrNNUrfc_referencesrONUoutput_encodingrPUutf-8rQU source_urlrRNUinput_encodingrSU utf-8-sigrTU_disable_configrUNU id_prefixrVUU tab_widthrWKUerror_encodingrXUUTF-8rYU_sourcerZUN/var/build/user_builds/imbo/checkouts/1.1.1/docs/installation/requirements.rstr[Ugettext_compactr\U generatorr]NUdump_internalsr^NU smart_quotesr_U pep_base_urlr`Uhttp://www.python.org/dev/peps/raUsyntax_highlightrbUlongrcUinput_encoding_error_handlerrdj>Uauto_id_prefixreUidrfUdoctitle_xformrgUstrip_elements_with_classesrhNU _config_filesri]Ufile_insertion_enabledrjU raw_enabledrkKU dump_settingsrlNubUsymbol_footnote_startrmKUidsrn}ro(hh(hhhhhhhhhhrh hh#hh$h`h!jh"huUsubstitution_namesrp}rqh1h=h3}rr(h5]h8]h7]Usourceh/h6]h:]uU footnotesrs]rtUrefidsru}rvub.PKrNDt_@X@X7imbo-1.1.1/.doctrees/installation/configuration.doctreecdocutils.nodes document q)q}q(U nametypesq}q(Xmongo extensionqXdefault-storage-adapterqXgridfs specificationqXlisteners added by defaultq NX replica setq Xfilesystem-storage-adapterq Xexamplesq NXdoctrineq NXstorage configuration - storageqNX event listeners - eventlistenersqNUcontentsqNXimage-transformations-configqXamazon simple storage serviceqNXdoctrine-project.orgqXgridfs-storage-adapterqXdefault-database-adapterqXopenssl_random_pseudo_bytesqXmongodbqXmongodb-database-adapterqXpull request on githubqX#doctrine database abstraction layerqX7event listener initializers - eventlistenerinitializersqNXsha-256qX!database configuration - databaseqNX2custom resources and routes - resources and routesqNXimbo users - authqNX4image transformation presets - transformationpresetsq NXgridfsq!NXs3-storage-adapterq"X)configuration-event-listener-initializersq#Xcustom storage adapterq$NX configurationq%Xstorage-configurationq&Xdatabase-configurationq'Xdoctrine-database-adapterq(Xconfiguration-event-listenersq)Xpdoq*X filesystemq+NX&manual for the mongoclient constructorq,Xcustom database adapterq-NuUsubstitution_defsq.}q/Uparse_messagesq0]q1(cdocutils.nodes system_message q2)q3}q4(U rawsourceq5UUparentq6cdocutils.nodes section q7)q8}q9(h5UU referencedq:Kh6hUsourceq;cdocutils.nodes reprunicode q}q?bUexpect_referenced_by_nameq@}qAh%cdocutils.nodes target qB)qC}qD(h5X.. _configuration:h6hh;h>UtagnameqEUtargetqFU attributesqG}qH(UidsqI]UbackrefsqJ]UdupnamesqK]UclassesqL]UnamesqM]UrefidqNU configurationqOuUlineqPKUdocumentqQhUchildrenqR]ubshEUsectionqShG}qT(hK]qUX configurationqVahL]hJ]hI]qW(hOUid1qXehM]qYh%auhPKhQhUexpect_referenced_by_idqZ}q[hOhCshR]q\(cdocutils.nodes title q])q^}q_(h5X Configurationq`h6h8h;h>hEUtitleqahG}qb(hK]hL]hJ]hI]hM]uhPKhQhhR]qccdocutils.nodes Text qdX Configurationqeqf}qg(h5h`h6h^ubaubcdocutils.nodes paragraph qh)qi}qj(h5XImbo ships with a default configuration file that will be automatically loaded. You will have to create one or more configuration files of your own that will be automatically merged with the default configuration by Imbo. The location of these files depends on the :ref:`installation method ` you choose. You should never have to edit the default configuration file provided by Imbo.qkh6h8h;h>hEU paragraphqlhG}qm(hK]hL]hJ]hI]hM]uhPKhQhhR]qn(hdX Imbo ships with a default configuration file that will be automatically loaded. You will have to create one or more configuration files of your own that will be automatically merged with the default configuration by Imbo. The location of these files depends on the qoqp}qq(h5X Imbo ships with a default configuration file that will be automatically loaded. You will have to create one or more configuration files of your own that will be automatically merged with the default configuration by Imbo. The location of these files depends on the h6hiubcsphinx.addnodes pending_xref qr)qs}qt(h5X):ref:`installation method `quh6hih;h>hEU pending_xrefqvhG}qw(UreftypeXrefUrefwarnqxU reftargetqyX installationU refdomainXstdqzhI]hJ]U refexplicithK]hL]hM]Urefdocq{Xinstallation/configurationq|uhPKhR]q}cdocutils.nodes emphasis q~)q}q(h5huhG}q(hK]hL]q(UxrefqhzXstd-refqehJ]hI]hM]uh6hshR]qhdXinstallation methodqq}q(h5Uh6hubahEUemphasisqubaubhdX[ you choose. You should never have to edit the default configuration file provided by Imbo.qq}q(h5X[ you choose. You should never have to edit the default configuration file provided by Imbo.h6hiubeubhh)q}q(h5XThe configuration file(s) you need to create should simply return arrays with configuration data. All available configuration options are covered in this chapter.qh6h8h;h>hEhlhG}q(hK]hL]hJ]hI]hM]uhPKhQhhR]qhdXThe configuration file(s) you need to create should simply return arrays with configuration data. All available configuration options are covered in this chapter.qq}q(h5hh6hubaubcdocutils.nodes topic q)q}q(h5Uh6h8h;h>hEUtopicqhG}q(hK]hL]q(UcontentsqUlocalqehJ]hI]qUcontentsqahM]qhauhPK hQhhR]qcdocutils.nodes bullet_list q)q}q(h5Uh6hh;NhEU bullet_listqhG}q(hK]hL]hJ]hI]hM]uhPNhQhhR]q(cdocutils.nodes list_item q)q}q(h5UhG}q(hK]hL]hJ]hI]hM]uh6hhR]qhh)q}q(h5UhG}q(hK]hL]hJ]hI]hM]uh6hhR]qcdocutils.nodes reference q)q}q(h5UhG}q(hI]qUid14qahJ]hK]hL]hM]UrefidUimbo-users-authquh6hhR]q(hdX Imbo users - qq}q(h5X Imbo users - qh6hubcdocutils.nodes literal q)q}q(h5X``auth``qhG}q(hK]hL]hJ]hI]hM]uh6hhR]qhdXauthq…q}q(h5Uh6hubahEUliteralqubehEU referencequbahEhlubahEU list_itemqubh)q}q(h5UhG}q(hK]hL]hJ]hI]hM]uh6hhR]qhh)q}q(h5UhG}q(hK]hL]hJ]hI]hM]uh6hhR]qh)q}q(h5UhG}q(hI]qUid15qahJ]hK]hL]hM]UrefidUdatabase-configuration-databasequh6hhR]q(hdXDatabase configuration - qׅq}q(h5XDatabase configuration - qh6hubh)q}q(h5X ``database``qhG}q(hK]hL]hJ]hI]hM]uh6hhR]qhdXdatabaseqq}q(h5Uh6hubahEhubehEhubahEhlubahEhubh)q}q(h5UhG}q(hK]hL]hJ]hI]hM]uh6hhR]qhh)q}q(h5UhG}q(hK]hL]hJ]hI]hM]uh6hhR]qh)q}q(h5UhG}q(hI]qUid16qahJ]hK]hL]hM]UrefidUstorage-configuration-storagequh6hhR]q(hdXStorage configuration - qq}q(h5XStorage configuration - qh6hubh)q}q(h5X ``storage``qhG}q(hK]hL]hJ]hI]hM]uh6hhR]qhdXstorageqq}q(h5Uh6hubahEhubehEhubahEhlubahEhubh)q}q(h5UhG}r(hK]hL]hJ]hI]hM]uh6hhR]rhh)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6hhR]rh)r}r(h5UhG}r(hI]r Uid17r ahJ]hK]hL]hM]UrefidUevent-listeners-eventlistenersr uh6jhR]r (hdXEvent listeners - r r}r(h5XEvent listeners - rh6jubh)r}r(h5X``eventListeners``rhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdXeventListenersrr}r(h5Uh6jubahEhubehEhubahEhlubahEhubh)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6hhR]rhh)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6jhR]r h)r!}r"(h5UhG}r#(hI]r$Uid18r%ahJ]hK]hL]hM]UrefidU5event-listener-initializers-eventlistenerinitializersr&uh6jhR]r'(hdXEvent listener initializers - r(r)}r*(h5XEvent listener initializers - r+h6j!ubh)r,}r-(h5X``eventListenerInitializers``r.hG}r/(hK]hL]hJ]hI]hM]uh6j!hR]r0hdXeventListenerInitializersr1r2}r3(h5Uh6j,ubahEhubehEhubahEhlubahEhubh)r4}r5(h5UhG}r6(hK]hL]hJ]hI]hM]uh6hhR]r7hh)r8}r9(h5UhG}r:(hK]hL]hJ]hI]hM]uh6j4hR]r;h)r<}r=(h5UhG}r>(hI]r?Uid19r@ahJ]hK]hL]hM]UrefidU2image-transformation-presets-transformationpresetsrAuh6j8hR]rB(hdXImage transformation presets - rCrD}rE(h5XImage transformation presets - rFh6j<ubh)rG}rH(h5X``transformationPresets``rIhG}rJ(hK]hL]hJ]hI]hM]uh6j<hR]rKhdXtransformationPresetsrLrM}rN(h5Uh6jGubahEhubehEhubahEhlubahEhubh)rO}rP(h5UhG}rQ(hK]hL]hJ]hI]hM]uh6hhR]rRhh)rS}rT(h5UhG}rU(hK]hL]hJ]hI]hM]uh6jOhR]rVh)rW}rX(h5UhG}rY(hI]rZUid20r[ahJ]hK]hL]hM]UrefidU0custom-resources-and-routes-resources-and-routesr\uh6jShR]r](hdXCustom resources and routes - r^r_}r`(h5XCustom resources and routes - rah6jWubh)rb}rc(h5X ``resources``rdhG}re(hK]hL]hJ]hI]hM]uh6jWhR]rfhdX resourcesrgrh}ri(h5Uh6jbubahEhubhdX and rjrk}rl(h5X and rmh6jWubh)rn}ro(h5X ``routes``rphG}rq(hK]hL]hJ]hI]hM]uh6jWhR]rrhdXroutesrsrt}ru(h5Uh6jnubahEhubehEhubahEhlubahEhubeubaubh7)rv}rw(h5Uh6h8h;h>hEhShG}rx(hK]hL]hJ]hI]ryhahM]rzhauhPKhQhhR]r{(h])r|}r}(h5XImbo users - ``auth``r~h6jvh;h>hEhahG}r(hI]hJ]hK]hL]hM]hNhuhPKhQhhR]r(hdX Imbo users - rr}r(h5hh6j|ubh)r}r(h5hhG}r(hK]hL]hJ]hI]hM]uh6j|hR]rhdXauthrr}r(h5Uh6jubahEhubeubhh)r}r(h5XEvery user that wants to store images in Imbo needs a public and private key pair. These keys are stored in the ``auth`` part of your configuration file:rh6jvh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPKhQhhR]r(hdXpEvery user that wants to store images in Imbo needs a public and private key pair. These keys are stored in the rr}r(h5XpEvery user that wants to store images in Imbo needs a public and private key pair. These keys are stored in the h6jubh)r}r(h5X``auth``hG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdXauthrr}r(h5Uh6jubahEhubhdX! part of your configuration file:rr}r(h5X! part of your configuration file:h6jubeubcdocutils.nodes literal_block r)r}r(h5X array( 'username' => '95f02d701b8dc19ee7d3710c477fd5f4633cec32087f562264e4975659029af7', 'otheruser' => 'b312ff29d5da23dcd230b61ff4db1e2515c862b9fb0bb59e7dd54ce1e4e94a53', ), // ... );h6jvh;h>hEU literal_blockrhG}r(UlinenosrUlanguagerXphpU xml:spacerUpreserverhI]hJ]hK]hL]hM]uhPKhQhhR]rhdX array( 'username' => '95f02d701b8dc19ee7d3710c477fd5f4633cec32087f562264e4975659029af7', 'otheruser' => 'b312ff29d5da23dcd230b61ff4db1e2515c862b9fb0bb59e7dd54ce1e4e94a53', ), // ... );rr}r(h5Uh6jubaubhh)r}r(h5X8The public keys can consist of the following characters:rh6jvh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPK!hQhhR]rhdX8The public keys can consist of the following characters:rr}r(h5jh6jubaubh)r}r(h5Uh6jvh;h>hEhhG}r(UbulletrX*hI]hJ]hK]hL]hM]uhPK#hQhhR]r(h)r}r(h5Xa-z (only lowercase is allowed)rh6jh;h>hEhhG}r(hK]hL]hJ]hI]hM]uhPNhQhhR]rhh)r}r(h5jh6jh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPK#hR]rhdXa-z (only lowercase is allowed)rr}r(h5jh6jubaubaubh)r}r(h5X0-9rh6jh;h>hEhhG}r(hK]hL]hJ]hI]hM]uhPNhQhhR]rhh)r}r(h5jh6jh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPK$hR]rhdX0-9rr}r(h5jh6jubaubaubh)r}r(h5X_ and - h6jh;h>hEhhG}r(hK]hL]hJ]hI]hM]uhPNhQhhR]rhh)r}r(h5X_ and -rh6jh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPK%hR]rhdX_ and -rr}r(h5jh6jubaubaubeubhh)r}r(h5X'and must be at least 3 characters long.rh6jvh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPK'hQhhR]rhdX'and must be at least 3 characters long.rr}r(h5jh6jubaubhh)r}r(h5XIFor the private keys you can for instance use a `SHA-256 `_ hash of a random value. The private key is used by clients to sign requests, and if you accidentally give away your private key users can use it to delete all your images. Make sure not to generate a private key that is easy to guess (like for instance the MD5 or SHA-256 hash of the public key). Imbo does not require the private key to be in a specific format, so you can also use regular passwords if you want. The key itself will never be a part of the payload sent to/from the server.rh6jvh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPK)hQhhR]r(hdX0For the private keys you can for instance use a rr}r(h5X0For the private keys you can for instance use a h6jubh)r}r(h5X/`SHA-256 `_hG}r(UnameXSHA-256UrefurirX"http://en.wikipedia.org/wiki/SHA-2rhI]hJ]hK]hL]hM]uh6jhR]rhdXSHA-256rr}r(h5Uh6jubahEhubhB)r}r(h5X% h:Kh6jhEhFhG}r(UrefurijhI]rUsha-256rahJ]hK]hL]hM]rhauhR]ubhdX hash of a random value. The private key is used by clients to sign requests, and if you accidentally give away your private key users can use it to delete all your images. Make sure not to generate a private key that is easy to guess (like for instance the MD5 or SHA-256 hash of the public key). Imbo does not require the private key to be in a specific format, so you can also use regular passwords if you want. The key itself will never be a part of the payload sent to/from the server.rr}r(h5X hash of a random value. The private key is used by clients to sign requests, and if you accidentally give away your private key users can use it to delete all your images. Make sure not to generate a private key that is easy to guess (like for instance the MD5 or SHA-256 hash of the public key). Imbo does not require the private key to be in a specific format, so you can also use regular passwords if you want. The key itself will never be a part of the payload sent to/from the server.h6jubeubhh)r}r(h5X+Imbo ships with a small command line tool that can be used to generate private keys for you using the `openssl_random_pseudo_bytes `_ function. The script is located in the ``scripts`` directory of the Imbo installation and does not require any arguments:rh6jvh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPK+hQhhR]r(hdXfImbo ships with a small command line tool that can be used to generate private keys for you using the rr}r(h5XfImbo ships with a small command line tool that can be used to generate private keys for you using the h6jubh)r}r(h5XK`openssl_random_pseudo_bytes `_hG}r(UnamehjX*http://php.net/openssl_random_pseudo_bytesrhI]hJ]hK]hL]hM]uh6jhR]r hdXopenssl_random_pseudo_bytesr r }r (h5Uh6jubahEhubhB)r }r(h5X- h:Kh6jhEhFhG}r(UrefurijhI]rUopenssl-random-pseudo-bytesrahJ]hK]hL]hM]rhauhR]ubhdX( function. The script is located in the rr}r(h5X( function. The script is located in the h6jubh)r}r(h5X ``scripts``hG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdXscriptsrr}r(h5Uh6jubahEhubhdXG directory of the Imbo installation and does not require any arguments:rr}r(h5XG directory of the Imbo installation and does not require any arguments:h6jubeubj)r }r!(h5Xe$ php scripts/generatePrivateKey.php 3b98dde5f67989a878b8b268d82f81f0858d4f1954597cc713ae161cdffcc84ah6jvh;h>hEjhG}r"(jjXbashjjhI]hJ]hK]hL]hM]uhPK-hQhhR]r#hdXe$ php scripts/generatePrivateKey.php 3b98dde5f67989a878b8b268d82f81f0858d4f1954597cc713ae161cdffcc84ar$r%}r&(h5Uh6j ubaubhh)r'}r((h5X The private key can be changed whenever you want as long as you remember to change it in both the server configuration and in the client you use. The public key can not be changed easily as database and storage adapters use it when storing/fetching images and metadata.r)h6jvh;h>hEhlhG}r*(hK]hL]hJ]hI]hM]uhPK2hQhhR]r+hdX The private key can be changed whenever you want as long as you remember to change it in both the server configuration and in the client you use. The public key can not be changed easily as database and storage adapters use it when storing/fetching images and metadata.r,r-}r.(h5j)h6j'ubaubhB)r/}r0(h5X.. _database-configuration:h6jvh;h>hEhFhG}r1(hI]hJ]hK]hL]hM]hNUdatabase-configurationr2uhPK4hQhhR]ubeubh7)r3}r4(h5Uh6h8h;h>h@}r5h'j/shEhShG}r6(hK]hL]hJ]hI]r7(hj2ehM]r8(hh'euhPK7hQhhZ}r9j2j/shR]r:(h])r;}r<(h5X%Database configuration - ``database``r=h6j3h;h>hEhahG}r>(hI]hJ]hK]hL]hM]hNhuhPK7hQhhR]r?(hdXDatabase configuration - r@rA}rB(h5hh6j;ubh)rC}rD(h5hhG}rE(hK]hL]hJ]hI]hM]uh6j;hR]rFhdXdatabaserGrH}rI(h5Uh6jCubahEhubeubhh)rJ}rK(h5XThe database adapter you decide to use is responsible for storing metadata and basic image information, like width and height for example, along with the generated short URLs. Imbo ships with some different database adapters that you can use. Remember that you will not be able to switch the adapter whenever you want and expect all data to be automatically transferred. Choosing a database adapter should be a long term commitment unless you have migration scripts available.rLh6j3h;h>hEhlhG}rM(hK]hL]hJ]hI]hM]uhPK9hQhhR]rNhdXThe database adapter you decide to use is responsible for storing metadata and basic image information, like width and height for example, along with the generated short URLs. Imbo ships with some different database adapters that you can use. Remember that you will not be able to switch the adapter whenever you want and expect all data to be automatically transferred. Choosing a database adapter should be a long term commitment unless you have migration scripts available.rOrP}rQ(h5jLh6jJubaubhh)rR}rS(h5XIn the default configuration file the :ref:`default-database-adapter` database adapter is used. You can choose to override this in your configuration file by specifying a different adapter. You can either specify an instance of a database adapter directly, or specify a closure that will return an instance of a database adapter when executed. Which database adapter to use is specified in the ``database`` key in the configuration array:rTh6j3h;h>hEhlhG}rU(hK]hL]hJ]hI]hM]uhPK;hQhhR]rV(hdX&In the default configuration file the rWrX}rY(h5X&In the default configuration file the h6jRubhr)rZ}r[(h5X:ref:`default-database-adapter`r\h6jRh;h>hEhvhG}r](UreftypeXrefhxhyXdefault-database-adapterU refdomainXstdr^hI]hJ]U refexplicithK]hL]hM]h{h|uhPK;hR]r_h~)r`}ra(h5j\hG}rb(hK]hL]rc(hj^Xstd-refrdehJ]hI]hM]uh6jZhR]rehdXdefault-database-adapterrfrg}rh(h5Uh6j`ubahEhubaubhdXE database adapter is used. You can choose to override this in your configuration file by specifying a different adapter. You can either specify an instance of a database adapter directly, or specify a closure that will return an instance of a database adapter when executed. Which database adapter to use is specified in the rirj}rk(h5XE database adapter is used. You can choose to override this in your configuration file by specifying a different adapter. You can either specify an instance of a database adapter directly, or specify a closure that will return an instance of a database adapter when executed. Which database adapter to use is specified in the h6jRubh)rl}rm(h5X ``database``hG}rn(hK]hL]hJ]hI]hM]uh6jRhR]rohdXdatabaserprq}rr(h5Uh6jlubahEhubhdX key in the configuration array:rsrt}ru(h5X key in the configuration array:h6jRubeubj)rv}rw(h5X function() { return new Imbo\Database\MongoDB(array( 'databaseName' => 'imbo', )); }, // or 'database' => new Imbo\Database\MongoDB(array( 'databaseName' => 'imbo', )), // ... );h6j3h;h>hEjhG}rx(jjXphpjjhI]hJ]hK]hL]hM]uhPK=hQhhR]ryhdX function() { return new Imbo\Database\MongoDB(array( 'databaseName' => 'imbo', )); }, // or 'database' => new Imbo\Database\MongoDB(array( 'databaseName' => 'imbo', )), // ... );rzr{}r|(h5Uh6jvubaubhh)r}}r~(h5XUBelow you will find documentation on the different database adapters Imbo ships with.rh6j3h;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPKRhQhhR]rhdXUBelow you will find documentation on the different database adapters Imbo ships with.rr}r(h5jh6j}ubaubh)r}r(h5Uh6j3h;h>hEhhG}r(hK]hL]r(hhehJ]hI]rUid2rahM]uhPKVhQhhR]rh)r}r(h5Uh6jh;NhEhhG}r(hK]hL]hJ]hI]hM]uhPNhQhhR]r(h)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhh)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6jhR]rh)r}r(h5UhG}r(hI]rUid21rahJ]hK]hL]hM]UrefidUdoctrineruh6jhR]rhdXDoctrinerr}r(h5XDoctrinerh6jubahEhubahEhlubahEhubh)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhh)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6jhR]rh)r}r(h5UhG}r(hI]rUid22rahJ]hK]hL]hM]UrefidUmongodbruh6jhR]rhdXMongoDBrr}r(h5XMongoDBrh6jubahEhubahEhlubahEhubh)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhh)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6jhR]rh)r}r(h5UhG}r(hI]rUid23rahJ]hK]hL]hM]UrefidUcustom-database-adapterruh6jhR]rhdXCustom database adapterrr}r(h5XCustom database adapterrh6jubahEhubahEhlubahEhubeubaubhB)r}r(h5X.. _doctrine-database-adapter:h6j3h;h>hEhFhG}r(hI]hJ]hK]hL]hM]hNUdoctrine-database-adapterruhPKXhQhhR]ubh7)r}r(h5Uh:Kh6j3h;h>h@}rh(jshEhShG}r(hK]rXdoctrinerahL]hJ]hI]r(jjehM]rh(auhPK[hQhhZ}rjjshR]r(h])r}r(h5jh6jh;h>hEhahG}r(hI]hJ]hK]hL]hM]hNjuhPK[hQhhR]rhdXDoctrinerr}r(h5jh6jubaubhh)r}r(h5XThis adapter uses the `Doctrine Database Abstraction Layer `_. The options you pass to the constructor of this adapter is passed to the underlying classes, so have a look at the Doctrine DBAL documentation over at `doctrine-project.org `_. When using this adapter you need to create the required tables in the RDBMS first, as specified in the :ref:`database-setup` section.rh6jh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPK]hQhhR]r(hdXThis adapter uses the rr}r(h5XThis adapter uses the h6jubh)r}r(h5X[`Doctrine Database Abstraction Layer `_hG}r(UnameX#Doctrine Database Abstraction LayerjX2http://www.doctrine-project.org/projects/dbal.htmlrhI]hJ]hK]hL]hM]uh6jhR]rhdX#Doctrine Database Abstraction Layerrr}r(h5Uh6jubahEhubhB)r}r(h5X5 h:Kh6jhEhFhG}r(UrefurijhI]rU#doctrine-database-abstraction-layerrahJ]hK]hL]hM]rhauhR]ubhdX. The options you pass to the constructor of this adapter is passed to the underlying classes, so have a look at the Doctrine DBAL documentation over at rr}r(h5X. The options you pass to the constructor of this adapter is passed to the underlying classes, so have a look at the Doctrine DBAL documentation over at h6jubh)r}r(h5Xf`doctrine-project.org `_hG}r(UnamehjXLhttp://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/index.htmlrhI]hJ]hK]hL]hM]uh6jhR]rhdXdoctrine-project.orgrr}r(h5Uh6jubahEhubhB)r}r(h5XO h:Kh6jhEhFhG}r(UrefurijhI]rUdoctrine-project-orgrahJ]hK]hL]hM]rhauhR]ubhdXi. When using this adapter you need to create the required tables in the RDBMS first, as specified in the rr}r(h5Xi. When using this adapter you need to create the required tables in the RDBMS first, as specified in the h6jubhr)r}r (h5X:ref:`database-setup`r h6jh;h>hEhvhG}r (UreftypeXrefhxhyXdatabase-setupU refdomainXstdr hI]hJ]U refexplicithK]hL]hM]h{h|uhPK]hR]r h~)r}r(h5j hG}r(hK]hL]r(hj Xstd-refrehJ]hI]hM]uh6jhR]rhdXdatabase-setuprr}r(h5Uh6jubahEhubaubhdX section.rr}r(h5X section.h6jubeubh7)r}r(h5Uh:Kh6jh;h>hEhShG}r(hK]rXexamplesrahL]hJ]hI]rUexamplesr ahM]uhPK`hQhhR]r!(h])r"}r#(h5XExamplesr$h6jh;h>hEhahG}r%(hK]hL]hJ]hI]hM]uhPK`hQhhR]r&hdXExamplesr'r(}r)(h5j$h6j"ubaubhh)r*}r+(h5XTHere are some examples on how to use the Doctrine adapter in the configuration file:r,h6jh;h>hEhlhG}r-(hK]hL]hJ]hI]hM]uhPKbhQhhR]r.hdXTHere are some examples on how to use the Doctrine adapter in the configuration file:r/r0}r1(h5j,h6j*ubaubcdocutils.nodes enumerated_list r2)r3}r4(h5Uh6jh;h>hEUenumerated_listr5hG}r6(Usuffixr7U)hI]hJ]hK]Uprefixr8UhL]hM]Uenumtyper9Uarabicr:uhPKdhQhhR]r;h)r<}r=(h5XMUse a `PDO `_ instance to connect to a SQLite database: h6j3h;h>hEhhG}r>(hK]hL]hJ]hI]hM]uhPNhQhhR]r?hh)r@}rA(h5XLUse a `PDO `_ instance to connect to a SQLite database:h6j<h;h>hEhlhG}rB(hK]hL]hJ]hI]hM]uhPKdhR]rC(hdXUse a rDrE}rF(h5XUse a h6j@ubh)rG}rH(h5X`PDO `_hG}rI(UnameXPDOjXhttp://php.net/pdo,rJhI]hJ]hK]hL]hM]uh6j@hR]rKhdXPDOrLrM}rN(h5Uh6jGubahEhubhB)rO}rP(h5X h:Kh6j@hEhFhG}rQ(UrefurijJhI]rRUpdorSahJ]hK]hL]hM]rTh*auhR]ubhdX* instance to connect to a SQLite database:rUrV}rW(h5X* instance to connect to a SQLite database:h6j@ubeubaubaubj)rX}rY(h5X function() { return new Imbo\Database\Doctrine(array( 'pdo' => new PDO('sqlite:/path/to/database'), )); }, // ... );h6jh;h>hEjhG}rZ(jjXphpjjhI]hJ]hK]hL]hM]uhPKfhQhhR]r[hdX function() { return new Imbo\Database\Doctrine(array( 'pdo' => new PDO('sqlite:/path/to/database'), )); }, // ... );r\r]}r^(h5Uh6jXubaubj2)r_}r`(h5Uh6jh;h>hEj5hG}ra(j7U)UstartrbKhI]hJ]hK]j8UhL]hM]j9j:uhPKuhQhhR]rch)rd}re(h5X'Connect to a MySQL database using PDO: h6j_h;h>hEhhG}rf(hK]hL]hJ]hI]hM]uhPNhQhhR]rghh)rh}ri(h5X&Connect to a MySQL database using PDO:rjh6jdh;h>hEhlhG}rk(hK]hL]hJ]hI]hM]uhPKuhR]rlhdX&Connect to a MySQL database using PDO:rmrn}ro(h5jjh6jhubaubaubaubj)rp}rq(h5XP function() { return new Imbo\Database\Doctrine(array( 'dbname' => 'database', 'user' => 'username', 'password' => 'password', 'host' => 'hostname', 'driver' => 'pdo_mysql', )); }, // ... );h6jh;h>hEjhG}rr(jjXphpjjhI]hJ]hK]hL]hM]uhPKwhQhhR]rshdXP function() { return new Imbo\Database\Doctrine(array( 'dbname' => 'database', 'user' => 'username', 'password' => 'password', 'host' => 'hostname', 'driver' => 'pdo_mysql', )); }, // ... );rtru}rv(h5Uh6jpubaubhB)rw}rx(h5X.. _mongodb-database-adapter:h6jh;h>hEhFhG}ry(hI]hJ]hK]hL]hM]hNUmongodb-database-adapterrzuhPKhQhhR]ubhB)r{}r|(h5X.. _default-database-adapter:h6jh;h>h@}r}hjwshEhFhG}r~(hI]hJ]hK]hL]hM]hNUdefault-database-adapterruhPKhQhhZ}rjzjwshR]ubeubeubh7)r}r(h5Uh:Kh6j3h;h>h@}r(hjwhj{uhEhShG}r(hK]rXmongodbrahL]hJ]hI]r(jjjzehM]r(hheuhPKhQhhZ}r(jzjwjj{uhR]r(h])r}r(h5jh6jh;h>hEhahG}r(hI]hJ]hK]hL]hM]hNjuhPKhQhhR]rhdXMongoDBrr}r(h5jh6jubaubhh)r}r(h5XThis adapter uses PHP's `mongo extension `_ to store data in `MongoDB `_. The following parameters are supported:rh6jh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPKhQhhR]r(hdXThis adapter uses PHP's rr}r(h5XThis adapter uses PHP's h6jubh)r}r(h5X6`mongo extension `_hG}r(UnameXmongo extensionjX!http://pecl.php.net/package/mongorhI]hJ]hK]hL]hM]uh6jhR]rhdXmongo extensionrr}r(h5Uh6jubahEhubhB)r}r(h5X$ h:Kh6jhEhFhG}r(UrefurijhI]rUmongo-extensionrahJ]hK]hL]hM]rhauhR]ubhdX to store data in rr}r(h5X to store data in h6jubh)r}r(h5X$`MongoDB `_hG}r(UnameXMongoDBjXhttp://www.mongodb.org/rhI]hJ]hK]hL]hM]uh6jhR]rhdXMongoDBrr}r(h5Uh6jubahEhubhB)r}r(h5X h:Kh6jhEhFhG}r(UrefurijhI]rUid3rahJ]hK]hL]hM]rjauhR]ubhdX). The following parameters are supported:rr}r(h5X). The following parameters are supported:h6jubeubcdocutils.nodes definition_list r)r}r(h5Uh6jh;h>hEUdefinition_listrhG}r(hK]hL]hJ]hI]hM]uhPNhQhhR]r(cdocutils.nodes definition_list_item r)r}r(h5XD``databaseName`` Name of the database to use. Defaults to ``imbo``. h6jh;h>hEUdefinition_list_itemrhG}r(hK]hL]hJ]hI]hM]uhPKhR]r(cdocutils.nodes term r)r}r(h5X``databaseName``rh6jh;h>hEUtermrhG}r(hK]hL]hJ]hI]hM]uhPKhR]rh)r}r(h5jhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdX databaseNamerr}r(h5Uh6jubahEhubaubcdocutils.nodes definition r)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhh)r}r(h5X2Name of the database to use. Defaults to ``imbo``.h6jh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPKhR]r(hdX)Name of the database to use. Defaults to rr}r(h5X)Name of the database to use. Defaults to h6jubh)r}r(h5X``imbo``hG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdXimborr}r(h5Uh6jubahEhubhdX.r}r(h5X.h6jubeubahEU definitionrubeubj)r}r(h5X```server`` The server string to use when connecting. Defaults to ``mongodb://localhost:27017``. h6jh;h>hEjhG}r(hK]hL]hJ]hI]hM]uhPKhQhhR]r(j)r}r(h5X ``server``rh6jh;h>hEjhG}r(hK]hL]hJ]hI]hM]uhPKhR]rh)r}r(h5jhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdXserverrr}r(h5Uh6jubahEhubaubj)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhh)r}r(h5XTThe server string to use when connecting. Defaults to ``mongodb://localhost:27017``.h6jh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPKhR]r(hdX6The server string to use when connecting. Defaults to rr}r(h5X6The server string to use when connecting. Defaults to h6jubh)r}r(h5X``mongodb://localhost:27017``hG}r (hK]hL]hJ]hI]hM]uh6jhR]r hdXmongodb://localhost:27017r r }r (h5Uh6jubahEhubhdX.r}r(h5X.h6jubeubahEjubeubj)r}r(h5X``options`` Options passed to the underlying adapter. Defaults to ``array('connect' => true, 'timeout' => 1000)``. See the `manual for the MongoClient constructor `_ for available options. h6jh;h>hEjhG}r(hK]hL]hJ]hI]hM]uhPKhQhhR]r(j)r}r(h5X ``options``rh6jh;h>hEjhG}r(hK]hL]hJ]hI]hM]uhPKhR]rh)r}r(h5jhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdXoptionsrr}r(h5Uh6jubahEhubaubj)r }r!(h5UhG}r"(hK]hL]hJ]hI]hM]uh6jhR]r#hh)r$}r%(h5XOptions passed to the underlying adapter. Defaults to ``array('connect' => true, 'timeout' => 1000)``. See the `manual for the MongoClient constructor `_ for available options.h6j h;h>hEhlhG}r&(hK]hL]hJ]hI]hM]uhPKhR]r'(hdX6Options passed to the underlying adapter. Defaults to r(r)}r*(h5X6Options passed to the underlying adapter. Defaults to h6j$ubh)r+}r,(h5X/``array('connect' => true, 'timeout' => 1000)``hG}r-(hK]hL]hJ]hI]hM]uh6j$hR]r.hdX+array('connect' => true, 'timeout' => 1000)r/r0}r1(h5Uh6j+ubahEhubhdX . See the r2r3}r4(h5X . See the h6j$ubh)r5}r6(h5Xb`manual for the MongoClient constructor `_hG}r7(UnameX&manual for the MongoClient constructorjX6http://www.php.net/manual/en/mongoclient.construct.phpr8hI]hJ]hK]hL]hM]uh6j$hR]r9hdX&manual for the MongoClient constructorr:r;}r<(h5Uh6j5ubahEhubhB)r=}r>(h5X9 h:Kh6j$hEhFhG}r?(Urefurij8hI]r@U&manual-for-the-mongoclient-constructorrAahJ]hK]hL]hM]rBh,auhR]ubhdX for available options.rCrD}rE(h5X for available options.h6j$ubeubahEjubeubeubh7)rF}rG(h5Uh:Kh6jh;h>hEhShG}rH(hK]rIjahL]hJ]hI]rJUid4rKahM]uhPKhQhhR]rL(h])rM}rN(h5XExamplesrOh6jFh;h>hEhahG}rP(hK]hL]hJ]hI]hM]uhPKhQhhR]rQhdXExamplesrRrS}rT(h5jOh6jMubaubj2)rU}rV(h5Uh6jFh;h>hEj5hG}rW(j7U)hI]hJ]hK]j8UhL]hM]j9j:uhPKhQhhR]rXh)rY}rZ(h5XHConnect to a local MongoDB instance using the default ``databaseName``: h6jUh;h>hEhhG}r[(hK]hL]hJ]hI]hM]uhPNhQhhR]r\hh)r]}r^(h5XGConnect to a local MongoDB instance using the default ``databaseName``:h6jYh;h>hEhlhG}r_(hK]hL]hJ]hI]hM]uhPKhR]r`(hdX6Connect to a local MongoDB instance using the default rarb}rc(h5X6Connect to a local MongoDB instance using the default h6j]ubh)rd}re(h5X``databaseName``hG}rf(hK]hL]hJ]hI]hM]uh6j]hR]rghdX databaseNamerhri}rj(h5Uh6jdubahEhubhdX:rk}rl(h5X:h6j]ubeubaubaubj)rm}rn(h5X function() { return new Imbo\Database\MongoDB(); }, // ... );h6jFh;h>hEjhG}ro(jjXphpjjhI]hJ]hK]hL]hM]uhPKhQhhR]rphdX function() { return new Imbo\Database\MongoDB(); }, // ... );rqrr}rs(h5Uh6jmubaubj2)rt}ru(h5Uh6jFh;h>hEj5hG}rv(j7U)jbKhI]hJ]hK]j8UhL]hM]j9j:uhPKhQhhR]rwh)rx}ry(h5XPConnect to a `replica set `_: h6jth;h>hEhhG}rz(hK]hL]hJ]hI]hM]uhPNhQhhR]r{hh)r|}r}(h5XOConnect to a `replica set `_:h6jxh;h>hEhlhG}r~(hK]hL]hJ]hI]hM]uhPKhR]r(hdX Connect to a rr}r(h5X Connect to a h6j|ubh)r}r(h5XA`replica set `_hG}r(UnameX replica setjX0http://www.mongodb.org/display/DOCS/Replica+SetsrhI]hJ]hK]hL]hM]uh6j|hR]rhdX replica setrr}r(h5Uh6jubahEhubhB)r}r(h5X3 h:Kh6j|hEhFhG}r(UrefurijhI]rU replica-setrahJ]hK]hL]hM]rh auhR]ubhdX:r}r(h5X:h6j|ubeubaubaubj)r}r(h5X0 function() { return new Imbo\Database\MongoDB(array( 'server' => 'mongodb://server1,server2,server3', 'options' => array( 'replicaSet' => 'nameOfReplicaSet', ), )); }, // ... );h6jFh;h>hEjhG}r(jjXphpjjhI]hJ]hK]hL]hM]uhPKhQhhR]rhdX0 function() { return new Imbo\Database\MongoDB(array( 'server' => 'mongodb://server1,server2,server3', 'options' => array( 'replicaSet' => 'nameOfReplicaSet', ), )); }, // ... );rr}r(h5Uh6jubaubeubeubh7)r}r(h5Uh6j3h;h>hEhShG}r(hK]hL]hJ]hI]rjahM]rh-auhPKhQhhR]r(h])r}r(h5jh6jh;h>hEhahG}r(hI]hJ]hK]hL]hM]hNjuhPKhQhhR]rhdXCustom database adapterrr}r(h5jh6jubaubhh)r}r(h5XIf you need to create your own database adapter you need to create a class that implements the ``Imbo\Database\DatabaseInterface`` interface, and then specify that adapter in the configuration:rh6jh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPKhQhhR]r(hdX_If you need to create your own database adapter you need to create a class that implements the rr}r(h5X_If you need to create your own database adapter you need to create a class that implements the h6jubh)r}r(h5X#``Imbo\Database\DatabaseInterface``hG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdXImbo\Database\DatabaseInterfacerr}r(h5Uh6jubahEhubhdX? interface, and then specify that adapter in the configuration:rr}r(h5X? interface, and then specify that adapter in the configuration:h6jubeubj)r}r(h5X function() { return new My\Custom\Adapter(array( 'some' => 'option', )); }, // ... );h6jh;h>hEjhG}r(jjXphpjjhI]hJ]hK]hL]hM]uhPKhQhhR]rhdX function() { return new My\Custom\Adapter(array( 'some' => 'option', )); }, // ... );rr}r(h5Uh6jubaubhh)r}r(h5X]You can read more about how to achieve this in the :doc:`../develop/custom_adapters` chapter.rh6jh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPKhQhhR]r(hdX3You can read more about how to achieve this in the rr}r(h5X3You can read more about how to achieve this in the h6jubhr)r}r(h5X!:doc:`../develop/custom_adapters`rh6jh;h>hEhvhG}r(UreftypeXdocrhxhyX../develop/custom_adaptersU refdomainUhI]hJ]U refexplicithK]hL]hM]h{h|uhPKhR]rh)r}r(h5jhG}r(hK]hL]r(hjehJ]hI]hM]uh6jhR]rhdX../develop/custom_adaptersrr}r(h5Uh6jubahEhubaubhdX chapter.rr}r(h5X chapter.h6jubeubhB)r}r(h5X.. _storage-configuration:h6jh;h>hEhFhG}r(hI]hJ]hK]hL]hM]hNUstorage-configurationruhPKhQhhR]ubeubeubh7)r}r(h5Uh6h8h;h>h@}rh&jshEhShG}r(hK]hL]hJ]hI]r(hjehM]r(hh&euhPKhQhhZ}rjjshR]r(h])r}r(h5X#Storage configuration - ``storage``rh6jh;h>hEhahG}r(hI]hJ]hK]hL]hM]hNhuhPKhQhhR]r(hdXStorage configuration - rr}r(h5hh6jubh)r}r(h5hhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdXstoragerr}r(h5Uh6jubahEhubeubhh)r}r(h5XStorage adapters are responsible for storing the original images you put into Imbo. As with the database adapter it is not possible to simply switch the adapter without having migration scripts available to move the stored images. Choose an adapter with care.rh6jh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPKhQhhR]rhdXStorage adapters are responsible for storing the original images you put into Imbo. As with the database adapter it is not possible to simply switch the adapter without having migration scripts available to move the stored images. Choose an adapter with care.rr}r(h5jh6jubaubhh)r}r(h5XIn the default configuration file the :ref:`default-storage-adapter` storage adapter is used. You can choose to override this in your configuration file by specifying a different adapter. You can either specify an instance of a storage adapter directly, or specify a closure that will return an instance of a storage adapter when executed. Which storage adapter to use is specified in the ``storage`` key in the configuration array:rh6jh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPKhQhhR]r(hdX&In the default configuration file the rr}r(h5X&In the default configuration file the h6jubhr)r}r(h5X:ref:`default-storage-adapter`rh6jh;h>hEhvhG}r(UreftypeXrefhxhyXdefault-storage-adapterU refdomainXstdrhI]hJ]U refexplicithK]hL]hM]h{h|uhPKhR]r h~)r }r (h5jhG}r (hK]hL]r (hjXstd-refrehJ]hI]hM]uh6jhR]rhdXdefault-storage-adapterrr}r(h5Uh6j ubahEhubaubhdXA storage adapter is used. You can choose to override this in your configuration file by specifying a different adapter. You can either specify an instance of a storage adapter directly, or specify a closure that will return an instance of a storage adapter when executed. Which storage adapter to use is specified in the rr}r(h5XA storage adapter is used. You can choose to override this in your configuration file by specifying a different adapter. You can either specify an instance of a storage adapter directly, or specify a closure that will return an instance of a storage adapter when executed. Which storage adapter to use is specified in the h6jubh)r}r(h5X ``storage``hG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdXstoragerr}r(h5Uh6jubahEhubhdX key in the configuration array:rr}r(h5X key in the configuration array:h6jubeubj)r }r!(h5X- function() { return new Imbo\Storage\Filesystem(array( 'dataDir' => '/path/to/images', )); }, // or 'storage' => new Imbo\Storage\Filesystem(array( 'dataDir' => '/path/to/images', )), // ... );h6jh;h>hEjhG}r"(jjXphpjjhI]hJ]hK]hL]hM]uhPKhQhhR]r#hdX- function() { return new Imbo\Storage\Filesystem(array( 'dataDir' => '/path/to/images', )); }, // or 'storage' => new Imbo\Storage\Filesystem(array( 'dataDir' => '/path/to/images', )), // ... );r$r%}r&(h5Uh6j ubaubhh)r'}r((h5XTBelow you will find documentation on the different storage adapters Imbo ships with.r)h6jh;h>hEhlhG}r*(hK]hL]hJ]hI]hM]uhPKhQhhR]r+hdXTBelow you will find documentation on the different storage adapters Imbo ships with.r,r-}r.(h5j)h6j'ubaubh)r/}r0(h5Uh6jh;h>hEhhG}r1(hK]hL]r2(hhehJ]hI]r3Uid5r4ahM]uhPKhQhhR]r5h)r6}r7(h5Uh6j/h;NhEhhG}r8(hK]hL]hJ]hI]hM]uhPNhQhhR]r9(h)r:}r;(h5UhG}r<(hK]hL]hJ]hI]hM]uh6j6hR]r=hh)r>}r?(h5UhG}r@(hK]hL]hJ]hI]hM]uh6j:hR]rAh)rB}rC(h5UhG}rD(hI]rEUid24rFahJ]hK]hL]hM]UrefidUamazon-simple-storage-servicerGuh6j>hR]rHhdXAmazon Simple Storage ServicerIrJ}rK(h5XAmazon Simple Storage ServicerLh6jBubahEhubahEhlubahEhubh)rM}rN(h5UhG}rO(hK]hL]hJ]hI]hM]uh6j6hR]rPhh)rQ}rR(h5UhG}rS(hK]hL]hJ]hI]hM]uh6jMhR]rTh)rU}rV(h5UhG}rW(hI]rXUid25rYahJ]hK]hL]hM]UrefidUid7rZuh6jQhR]r[hdXDoctriner\r]}r^(h5XDoctriner_h6jUubahEhubahEhlubahEhubh)r`}ra(h5UhG}rb(hK]hL]hJ]hI]hM]uh6j6hR]rchh)rd}re(h5UhG}rf(hK]hL]hJ]hI]hM]uh6j`hR]rgh)rh}ri(h5UhG}rj(hI]rkUid26rlahJ]hK]hL]hM]UrefidU filesystemrmuh6jdhR]rnhdX Filesystemrorp}rq(h5X Filesystemrrh6jhubahEhubahEhlubahEhubh)rs}rt(h5UhG}ru(hK]hL]hJ]hI]hM]uh6j6hR]rvhh)rw}rx(h5UhG}ry(hK]hL]hJ]hI]hM]uh6jshR]rzh)r{}r|(h5UhG}r}(hI]r~Uid27rahJ]hK]hL]hM]UrefidUgridfsruh6jwhR]rhdXGridFSrr}r(h5XGridFSrh6j{ubahEhubahEhlubahEhubh)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6j6hR]rhh)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6jhR]rh)r}r(h5UhG}r(hI]rUid28rahJ]hK]hL]hM]UrefidUcustom-storage-adapterruh6jhR]rhdXCustom storage adapterrr}r(h5XCustom storage adapterrh6jubahEhubahEhlubahEhubeubaubhB)r}r(h5X.. _s3-storage-adapter:h6jh;h>hEhFhG}r(hI]hJ]hK]hL]hM]hNUs3-storage-adapterruhPKhQhhR]ubh7)r}r(h5Uh6jh;h>h@}rh"jshEhShG}r(hK]hL]hJ]hI]r(jGjehM]r(hh"euhPKhQhhZ}rjjshR]r(h])r}r(h5jLh6jh;h>hEhahG}r(hI]hJ]hK]hL]hM]hNjFuhPKhQhhR]rhdXAmazon Simple Storage Servicerr}r(h5jLh6jubaubhh)r}r(h5XjThis adapter stores your images in a bucket in the Amazon Simple Storage Service (S3). The parameters are:rh6jh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPMhQhhR]rhdXjThis adapter stores your images in a bucket in the Amazon Simple Storage Service (S3). The parameters are:rr}r(h5jh6jubaubj)r}r(h5Uh6jh;h>hEjhG}r(hK]hL]hJ]hI]hM]uhPNhQhhR]r(j)r}r(h5X``key`` Your AWS access key h6jh;h>hEjhG}r(hK]hL]hJ]hI]hM]uhPMhR]r(j)r}r(h5X``key``rh6jh;h>hEjhG}r(hK]hL]hJ]hI]hM]uhPMhR]rh)r}r(h5jhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdXkeyrr}r(h5Uh6jubahEhubaubj)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhh)r}r(h5XYour AWS access keyrh6jh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPMhR]rhdXYour AWS access keyrr}r(h5jh6jubaubahEjubeubj)r}r(h5X``secret`` Your AWS secret key h6jh;h>hEjhG}r(hK]hL]hJ]hI]hM]uhPMhQhhR]r(j)r}r(h5X ``secret``rh6jh;h>hEjhG}r(hK]hL]hJ]hI]hM]uhPMhR]rh)r}r(h5jhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdXsecretrr}r(h5Uh6jubahEhubaubj)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhh)r}r(h5XYour AWS secret keyrh6jh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPMhR]rhdXYour AWS secret keyrr}r(h5jh6jubaubahEjubeubj)r}r(h5Xk``bucket`` The name of the bucket you want to store your images in. Imbo will **not** create this for you. h6jh;h>hEjhG}r(hK]hL]hJ]hI]hM]uhPM hQhhR]r(j)r}r(h5X ``bucket``rh6jh;h>hEjhG}r(hK]hL]hJ]hI]hM]uhPM hR]rh)r}r(h5jhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdXbucketrr}r(h5Uh6jubahEhubaubj)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhh)r}r(h5X_The name of the bucket you want to store your images in. Imbo will **not** create this for you.h6jh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPM hR]r(hdXCThe name of the bucket you want to store your images in. Imbo will rr }r (h5XCThe name of the bucket you want to store your images in. Imbo will h6jubcdocutils.nodes strong r )r }r (h5X**not**hG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdXnotrr}r(h5Uh6j ubahEUstrongrubhdX create this for you.rr}r(h5X create this for you.h6jubeubahEjubeubeubhh)r}r(h5XThis adapter creates subdirectories in the bucket in the same fashion as the :ref:`Filesystem storage adapter ` stores the files on the local filesystem.rh6jh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPM hQhhR]r(hdXMThis adapter creates subdirectories in the bucket in the same fashion as the rr}r(h5XMThis adapter creates subdirectories in the bucket in the same fashion as the h6jubhr)r}r (h5X>:ref:`Filesystem storage adapter `r!h6jh;h>hEhvhG}r"(UreftypeXrefhxhyXfilesystem-storage-adapterU refdomainXstdr#hI]hJ]U refexplicithK]hL]hM]h{h|uhPM hR]r$h~)r%}r&(h5j!hG}r'(hK]hL]r((hj#Xstd-refr)ehJ]hI]hM]uh6jhR]r*hdXFilesystem storage adapterr+r,}r-(h5Uh6j%ubahEhubaubhdX* stores the files on the local filesystem.r.r/}r0(h5X* stores the files on the local filesystem.h6jubeubh7)r1}r2(h5Uh:Kh6jh;h>hEhShG}r3(hK]r4Xexamplesr5ahL]hJ]hI]r6Uid6r7ahM]uhPMhQhhR]r8(h])r9}r:(h5XExamplesr;h6j1h;h>hEhahG}r<(hK]hL]hJ]hI]hM]uhPMhQhhR]r=hdXExamplesr>r?}r@(h5j;h6j9ubaubj)rA}rB(h5X function() { new Imbo\Storage\S3(array( 'key' => '' 'secret' => '', 'bucket' => 'my-imbo-bucket', )); }, // ... );h6j1h;h>hEjhG}rC(jjXphpjjhI]hJ]hK]hL]hM]uhPMhQhhR]rDhdX function() { new Imbo\Storage\S3(array( 'key' => '' 'secret' => '', 'bucket' => 'my-imbo-bucket', )); }, // ... );rErF}rG(h5Uh6jAubaubeubeubh7)rH}rI(h5Uh:Kh6jh;h>hEhShG}rJ(hK]rKjahL]hJ]hI]rLjZahM]uhPM"hQhhR]rM(h])rN}rO(h5j_h6jHh;h>hEhahG}rP(hI]hJ]hK]hL]hM]hNjYuhPM"hQhhR]rQhdXDoctrinerRrS}rT(h5j_h6jNubaubhh)rU}rV(h5XThis adapter uses the `Doctrine Database Abstraction Layer `_. The options you pass to the constructor of this adapter is passed to the underlying classes, so have a look at the Doctrine DBAL documentation over at `doctrine-project.org `_. When using this adapter you need to create the required tables in the RDBMS first, as specified in the :ref:`database-setup` section.rWh6jHh;h>hEhlhG}rX(hK]hL]hJ]hI]hM]uhPM$hQhhR]rY(hdXThis adapter uses the rZr[}r\(h5XThis adapter uses the h6jUubh)r]}r^(h5X[`Doctrine Database Abstraction Layer `_hG}r_(UnameX#Doctrine Database Abstraction LayerjX2http://www.doctrine-project.org/projects/dbal.htmlr`hI]hJ]hK]hL]hM]uh6jUhR]rahdX#Doctrine Database Abstraction Layerrbrc}rd(h5Uh6j]ubahEhubhB)re}rf(h5X5 h:Kh6jUhEhFhG}rg(Urefurij`hI]rhUid8riahJ]hK]rjX#doctrine database abstraction layerrkahL]hM]uhR]ubhdX. The options you pass to the constructor of this adapter is passed to the underlying classes, so have a look at the Doctrine DBAL documentation over at rlrm}rn(h5X. The options you pass to the constructor of this adapter is passed to the underlying classes, so have a look at the Doctrine DBAL documentation over at h6jUubh)ro}rp(h5Xf`doctrine-project.org `_hG}rq(UnameXdoctrine-project.orgrrjXLhttp://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/index.htmlrshI]hJ]hK]hL]hM]uh6jUhR]rthdXdoctrine-project.orgrurv}rw(h5Uh6joubahEhubhB)rx}ry(h5XO h:Kh6jUhEhFhG}rz(UrefurijshI]r{Uid9r|ahJ]hK]r}jrahL]hM]uhR]ubhdXi. When using this adapter you need to create the required tables in the RDBMS first, as specified in the r~r}r(h5Xi. When using this adapter you need to create the required tables in the RDBMS first, as specified in the h6jUubhr)r}r(h5X:ref:`database-setup`rh6jUh;h>hEhvhG}r(UreftypeXrefhxhyXdatabase-setupU refdomainXstdrhI]hJ]U refexplicithK]hL]hM]h{h|uhPM$hR]rh~)r}r(h5jhG}r(hK]hL]r(hjXstd-refrehJ]hI]hM]uh6jhR]rhdXdatabase-setuprr}r(h5Uh6jubahEhubaubhdX section.rr}r(h5X section.h6jUubeubh7)r}r(h5Uh:Kh6jHh;h>hEhShG}r(hK]rXexamplesrahL]hJ]hI]rUid10rahM]uhPM'hQhhR]r(h])r}r(h5XExamplesrh6jh;h>hEhahG}r(hK]hL]hJ]hI]hM]uhPM'hQhhR]rhdXExamplesrr}r(h5jh6jubaubhh)r}r(h5XTHere are some examples on how to use the Doctrine adapter in the configuration file:rh6jh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPM)hQhhR]rhdXTHere are some examples on how to use the Doctrine adapter in the configuration file:rr}r(h5jh6jubaubj2)r}r(h5Uh6jh;h>hEj5hG}r(j7U)hI]hJ]hK]j8UhL]hM]j9j:uhPM+hQhhR]rh)r}r(h5X4Use a PDO instance to connect to a SQLite database: h6jh;h>hEhhG}r(hK]hL]hJ]hI]hM]uhPNhQhhR]rhh)r}r(h5X3Use a PDO instance to connect to a SQLite database:rh6jh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPM+hR]rhdX3Use a PDO instance to connect to a SQLite database:rr}r(h5jh6jubaubaubaubj)r}r(h5X function() { return new Imbo\Storage\Doctrine(array( 'pdo' => new PDO('sqlite:/path/to/database'), )); }, // ... );h6jh;h>hEjhG}r(jjXphpjjhI]hJ]hK]hL]hM]uhPM-hQhhR]rhdX function() { return new Imbo\Storage\Doctrine(array( 'pdo' => new PDO('sqlite:/path/to/database'), )); }, // ... );rr}r(h5Uh6jubaubj2)r}r(h5Uh6jh;h>hEj5hG}r(j7U)jbKhI]hJ]hK]j8UhL]hM]j9j:uhPM<hQhhR]rh)r}r(h5X'Connect to a MySQL database using PDO: h6jh;h>hEhhG}r(hK]hL]hJ]hI]hM]uhPNhQhhR]rhh)r}r(h5X&Connect to a MySQL database using PDO:rh6jh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPM<hR]rhdX&Connect to a MySQL database using PDO:rr}r(h5jh6jubaubaubaubj)r}r(h5XN function() { return new Imbo\Storage\Doctrine(array( 'dbname' => 'database', 'user' => 'username', 'password' => 'password', 'host' => 'hostname', 'driver' => 'pdo_mysql', )); }, // ... );h6jh;h>hEjhG}r(jjXphpjjhI]hJ]hK]hL]hM]uhPM>hQhhR]rhdXN function() { return new Imbo\Storage\Doctrine(array( 'dbname' => 'database', 'user' => 'username', 'password' => 'password', 'host' => 'hostname', 'driver' => 'pdo_mysql', )); }, // ... );rr}r(h5Uh6jubaubhB)r}r(h5X.. _filesystem-storage-adapter:h6jh;h>hEhFhG}r(hI]hJ]hK]hL]hM]hNUfilesystem-storage-adapterruhPMQhQhhR]ubeubeubh7)r}r(h5Uh6jh;h>h@}rh jshEhShG}r(hK]hL]hJ]hI]r(jmjehM]r(h+h euhPMThQhhZ}rjjshR]r(h])r}r(h5jrh6jh;h>hEhahG}r(hI]hJ]hK]hL]hM]hNjluhPMThQhhR]rhdX Filesystemrr}r(h5jrh6jubaubhh)r}r(h5XThis adapter simply stores all images on the file system. It has a single parameter, and that is the base directory of where you want your images stored:rh6jh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPMVhQhhR]rhdXThis adapter simply stores all images on the file system. It has a single parameter, and that is the base directory of where you want your images stored:rr}r(h5jh6jubaubj)r}r(h5Uh6jh;h>hEjhG}r(hK]hL]hJ]hI]hM]uhPNhQhhR]rj)r}r(h5X7``dataDir`` The base path where the images are stored. h6jh;h>hEjhG}r(hK]hL]hJ]hI]hM]uhPMYhR]r(j)r}r(h5X ``dataDir``rh6jh;h>hEjhG}r(hK]hL]hJ]hI]hM]uhPMYhR]rh)r}r(h5jhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdXdataDirrr}r(h5Uh6jubahEhubaubj)r}r (h5UhG}r (hK]hL]hJ]hI]hM]uh6jhR]r hh)r }r (h5X*The base path where the images are stored.rh6jh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPMYhR]rhdX*The base path where the images are stored.rr}r(h5jh6j ubaubahEjubeubaubhh)r}r(h5XThis adapter is configured to create subdirectories inside of ``dataDir`` based on the public key of the user and the checksum of the images added to Imbo. The algorithm that generates the path simply takes the three first characters of the public key and creates directories for each of them, then the full public key, then a directory of each of the first characters in the image identifier, and lastly it stores the image in a file with a filename equal to the image identifier itself.rh6jh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPM[hQhhR]r(hdX>This adapter is configured to create subdirectories inside of rr}r(h5X>This adapter is configured to create subdirectories inside of h6jubh)r}r(h5X ``dataDir``hG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdXdataDirr r!}r"(h5Uh6jubahEhubhdX based on the public key of the user and the checksum of the images added to Imbo. The algorithm that generates the path simply takes the three first characters of the public key and creates directories for each of them, then the full public key, then a directory of each of the first characters in the image identifier, and lastly it stores the image in a file with a filename equal to the image identifier itself.r#r$}r%(h5X based on the public key of the user and the checksum of the images added to Imbo. The algorithm that generates the path simply takes the three first characters of the public key and creates directories for each of them, then the full public key, then a directory of each of the first characters in the image identifier, and lastly it stores the image in a file with a filename equal to the image identifier itself.h6jubeubh7)r&}r'(h5Uh:Kh6jh;h>hEhShG}r((hK]r)Xexamplesr*ahL]hJ]hI]r+Uid11r,ahM]uhPM^hQhhR]r-(h])r.}r/(h5XExamplesr0h6j&h;h>hEhahG}r1(hK]hL]hJ]hI]hM]uhPM^hQhhR]r2hdXExamplesr3r4}r5(h5j0h6j.ubaubj2)r6}r7(h5Uh6j&h;h>hEj5hG}r8(j7U)hI]hJ]hK]j8UhL]hM]j9j:uhPM`hQhhR]r9h)r:}r;(h5X%Store images in ``/path/to/images``: h6j6h;h>hEhhG}r<(hK]hL]hJ]hI]hM]uhPNhQhhR]r=hh)r>}r?(h5X$Store images in ``/path/to/images``:h6j:h;h>hEhlhG}r@(hK]hL]hJ]hI]hM]uhPM`hR]rA(hdXStore images in rBrC}rD(h5XStore images in h6j>ubh)rE}rF(h5X``/path/to/images``hG}rG(hK]hL]hJ]hI]hM]uh6j>hR]rHhdX/path/to/imagesrIrJ}rK(h5Uh6jEubahEhubhdX:rL}rM(h5X:h6j>ubeubaubaubj)rN}rO(h5X function() { new Imbo\Storage\Filesystem(array( 'dataDir' => '/path/to/images', )); }, // ... );h6j&h;h>hEjhG}rP(jjXphpjjhI]hJ]hK]hL]hM]uhPMbhQhhR]rQhdX function() { new Imbo\Storage\Filesystem(array( 'dataDir' => '/path/to/images', )); }, // ... );rRrS}rT(h5Uh6jNubaubhB)rU}rV(h5X.. _gridfs-storage-adapter:h6j&h;h>hEhFhG}rW(hI]hJ]hK]hL]hM]hNUgridfs-storage-adapterrXuhPMqhQhhR]ubhB)rY}rZ(h5X.. _default-storage-adapter:h6j&h;h>h@}r[hjUshEhFhG}r\(hI]hJ]hK]hL]hM]hNUdefault-storage-adapterr]uhPMrhQhhZ}r^jXjUshR]ubeubeubh7)r_}r`(h5Uh6jh;h>h@}ra(hjUhjYuhEhShG}rb(hK]hL]hJ]hI]rc(jj]jXehM]rd(h!hheuhPMuhQhhZ}re(jXjUj]jYuhR]rf(h])rg}rh(h5jh6j_h;h>hEhahG}ri(hI]hJ]hK]hL]hM]hNjuhPMuhQhhR]rjhdXGridFSrkrl}rm(h5jh6jgubaubhh)rn}ro(h5XThe GridFS adapter is used to store the images in MongoDB using the `GridFS specification `_. This adapter has the following parameters:rph6j_h;h>hEhlhG}rq(hK]hL]hJ]hI]hM]uhPMwhQhhR]rr(hdXDThe GridFS adapter is used to store the images in MongoDB using the rsrt}ru(h5XDThe GridFS adapter is used to store the images in MongoDB using the h6jnubh)rv}rw(h5XD`GridFS specification `_hG}rx(UnameXGridFS specificationjX*http://www.mongodb.org/display/DOCS/GridFSryhI]hJ]hK]hL]hM]uh6jnhR]rzhdXGridFS specificationr{r|}r}(h5Uh6jvubahEhubhB)r~}r(h5X- h:Kh6jnhEhFhG}r(UrefurijyhI]rUgridfs-specificationrahJ]hK]hL]hM]rhauhR]ubhdX,. This adapter has the following parameters:rr}r(h5X,. This adapter has the following parameters:h6jnubeubj)r}r(h5Uh6j_h;h>hEjhG}r(hK]hL]hJ]hI]hM]uhPNhQhhR]r(j)r}r(h5X```databaseName`` The name of the database to store the images in. Defaults to ``imbo_storage``. h6jh;h>hEjhG}r(hK]hL]hJ]hI]hM]uhPMzhR]r(j)r}r(h5X``databaseName``rh6jh;h>hEjhG}r(hK]hL]hJ]hI]hM]uhPMzhR]rh)r}r(h5jhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdX databaseNamerr}r(h5Uh6jubahEhubaubj)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhh)r}r(h5XNThe name of the database to store the images in. Defaults to ``imbo_storage``.h6jh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPMzhR]r(hdX=The name of the database to store the images in. Defaults to rr}r(h5X=The name of the database to store the images in. Defaults to h6jubh)r}r(h5X``imbo_storage``hG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdX imbo_storagerr}r(h5Uh6jubahEhubhdX.r}r(h5X.h6jubeubahEjubeubj)r}r(h5Xj``server`` The server string to use when connecting to MongoDB. Defaults to ``mongodb://localhost:27017`` h6jh;h>hEjhG}r(hK]hL]hJ]hI]hM]uhPM}hQhhR]r(j)r}r(h5X ``server``rh6jh;h>hEjhG}r(hK]hL]hJ]hI]hM]uhPM}hR]rh)r}r(h5jhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdXserverrr}r(h5Uh6jubahEhubaubj)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhh)r}r(h5X^The server string to use when connecting to MongoDB. Defaults to ``mongodb://localhost:27017``h6jh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPM}hR]r(hdXAThe server string to use when connecting to MongoDB. Defaults to rr}r(h5XAThe server string to use when connecting to MongoDB. Defaults to h6jubh)r}r(h5X``mongodb://localhost:27017``hG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdXmongodb://localhost:27017rr}r(h5Uh6jubahEhubeubahEjubeubj)r}r(h5X``options`` Options passed to the underlying adapter. Defaults to ``array('connect' => true, 'timeout' => 1000)``. See the `manual for the MongoClient constructor `_ for available options. h6jh;h>hEjhG}r(hK]hL]hJ]hI]hM]uhPMhQhhR]r(j)r}r(h5X ``options``rh6jh;h>hEjhG}r(hK]hL]hJ]hI]hM]uhPMhR]rh)r}r(h5jhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdXoptionsrr}r(h5Uh6jubahEhubaubj)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhh)r}r(h5XOptions passed to the underlying adapter. Defaults to ``array('connect' => true, 'timeout' => 1000)``. See the `manual for the MongoClient constructor `_ for available options.h6jh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPMhR]r(hdX6Options passed to the underlying adapter. Defaults to rr}r(h5X6Options passed to the underlying adapter. Defaults to h6jubh)r}r(h5X/``array('connect' => true, 'timeout' => 1000)``hG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdX+array('connect' => true, 'timeout' => 1000)rr}r(h5Uh6jubahEhubhdX . See the rr}r(h5X . See the h6jubh)r}r(h5Xb`manual for the MongoClient constructor `_hG}r(UnameX&manual for the MongoClient constructorjX6http://www.php.net/manual/en/mongoclient.construct.phprhI]hJ]hK]hL]hM]uh6jhR]rhdX&manual for the MongoClient constructorrr}r(h5Uh6jubahEhubhB)r}r(h5X9 h:Kh6jhEhFhG}r(UrefurijhI]rUid12rahJ]hK]rX&manual for the mongoclient constructorrahL]hM]uhR]ubhdX for available options.rr}r(h5X for available options.h6jubeubahEjubeubeubh7)r}r (h5Uh:Kh6j_h;h>hEhShG}r (hK]r Xexamplesr ahL]hJ]hI]r Uid13rahM]uhPMhQhhR]r(h])r}r(h5XExamplesrh6jh;h>hEhahG}r(hK]hL]hJ]hI]hM]uhPMhQhhR]rhdXExamplesrr}r(h5jh6jubaubj2)r}r(h5Uh6jh;h>hEj5hG}r(j7U)hI]hJ]hK]j8UhL]hM]j9j:uhPMhQhhR]rh)r}r(h5XHConnect to a local MongoDB instance using the default ``databaseName``: h6jh;h>hEhhG}r(hK]hL]hJ]hI]hM]uhPNhQhhR]rhh)r }r!(h5XGConnect to a local MongoDB instance using the default ``databaseName``:h6jh;h>hEhlhG}r"(hK]hL]hJ]hI]hM]uhPMhR]r#(hdX6Connect to a local MongoDB instance using the default r$r%}r&(h5X6Connect to a local MongoDB instance using the default h6j ubh)r'}r((h5X``databaseName``hG}r)(hK]hL]hJ]hI]hM]uh6j hR]r*hdX databaseNamer+r,}r-(h5Uh6j'ubahEhubhdX:r.}r/(h5X:h6j ubeubaubaubj)r0}r1(h5X} function() { return new Imbo\Storage\GridFS(); }, // ... );h6jh;h>hEjhG}r2(jjXphpjjhI]hJ]hK]hL]hM]uhPMhQhhR]r3hdX} function() { return new Imbo\Storage\GridFS(); }, // ... );r4r5}r6(h5Uh6j0ubaubj2)r7}r8(h5Uh6jh;h>hEj5hG}r9(j7U)jbKhI]hJ]hK]j8UhL]hM]j9j:uhPMhQhhR]r:h)r;}r<(h5XConnect to a replica set: h6j7h;h>hEhhG}r=(hK]hL]hJ]hI]hM]uhPNhQhhR]r>hh)r?}r@(h5XConnect to a replica set:rAh6j;h;h>hEhlhG}rB(hK]hL]hJ]hI]hM]uhPMhR]rChdXConnect to a replica set:rDrE}rF(h5jAh6j?ubaubaubaubj)rG}rH(h5X- function() { return new Imbo\Storage\GridFS(array( 'server' => 'mongodb://server1,server2,server3', 'options' => array( 'replicaSet' => 'nameOfReplicaSet', ), )); }, // ... );h6jh;h>hEjhG}rI(jjXphpjjhI]hJ]hK]hL]hM]uhPMhQhhR]rJhdX- function() { return new Imbo\Storage\GridFS(array( 'server' => 'mongodb://server1,server2,server3', 'options' => array( 'replicaSet' => 'nameOfReplicaSet', ), )); }, // ... );rKrL}rM(h5Uh6jGubaubeubeubh7)rN}rO(h5Uh6jh;h>hEhShG}rP(hK]hL]hJ]hI]rQjahM]rRh$auhPMhQhhR]rS(h])rT}rU(h5jh6jNh;h>hEhahG}rV(hI]hJ]hK]hL]hM]hNjuhPMhQhhR]rWhdXCustom storage adapterrXrY}rZ(h5jh6jTubaubhh)r[}r\(h5XIf you need to create your own storage adapter you need to create a class that implements the ``Imbo\Storage\StorageInterface`` interface, and then specify that adapter in the configuration:r]h6jNh;h>hEhlhG}r^(hK]hL]hJ]hI]hM]uhPMhQhhR]r_(hdX^If you need to create your own storage adapter you need to create a class that implements the r`ra}rb(h5X^If you need to create your own storage adapter you need to create a class that implements the h6j[ubh)rc}rd(h5X!``Imbo\Storage\StorageInterface``hG}re(hK]hL]hJ]hI]hM]uh6j[hR]rfhdXImbo\Storage\StorageInterfacergrh}ri(h5Uh6jcubahEhubhdX? interface, and then specify that adapter in the configuration:rjrk}rl(h5X? interface, and then specify that adapter in the configuration:h6j[ubeubj)rm}rn(h5X function() { return new My\Custom\Adapter(array( 'some' => 'option', )); }, // ... );h6jNh;h>hEjhG}ro(jjXphpjjhI]hJ]hK]hL]hM]uhPMhQhhR]rphdX function() { return new My\Custom\Adapter(array( 'some' => 'option', )); }, // ... );rqrr}rs(h5Uh6jmubaubhh)rt}ru(h5X]You can read more about how to achieve this in the :doc:`../develop/custom_adapters` chapter.rvh6jNh;h>hEhlhG}rw(hK]hL]hJ]hI]hM]uhPMhQhhR]rx(hdX3You can read more about how to achieve this in the ryrz}r{(h5X3You can read more about how to achieve this in the h6jtubhr)r|}r}(h5X!:doc:`../develop/custom_adapters`r~h6jth;h>hEhvhG}r(UreftypeXdocrhxhyX../develop/custom_adaptersU refdomainUhI]hJ]U refexplicithK]hL]hM]h{h|uhPMhR]rh)r}r(h5j~hG}r(hK]hL]r(hjehJ]hI]hM]uh6j|hR]rhdX../develop/custom_adaptersrr}r(h5Uh6jubahEhubaubhdX chapter.rr}r(h5X chapter.h6jtubeubhB)r}r(h5X".. _configuration-event-listeners:h6jNh;h>hEhFhG}r(hI]hJ]hK]hL]hM]hNUconfiguration-event-listenersruhPMhQhhR]ubeubeubh7)r}r(h5Uh6h8h;h>h@}rh)jshEhShG}r(hK]hL]hJ]hI]r(j jehM]r(hh)euhPMhQhhZ}rjjshR]r(h])r}r(h5X$Event listeners - ``eventListeners``rh6jh;h>hEhahG}r(hI]hJ]hK]hL]hM]hNj uhPMhQhhR]r(hdXEvent listeners - rr}r(h5jh6jubh)r}r(h5jhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdXeventListenersrr}r(h5Uh6jubahEhubeubhh)r}r(h5X-Imbo support event listeners that you can use to hook into Imbo at different phases without having to edit Imbo itself. An event listener is simply a piece of code that will be executed when a certain event is triggered from Imbo. Event listeners are added to the ``eventListeners`` part of the configuration array as associative arrays. If you want to disable some of the default event listeners simply specify the same key in your configuration file and set the value to ``null`` or ``false``. Keep in mind that not all event listeners should be disabled.rh6jh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPMhQhhR]r(hdXImbo support event listeners that you can use to hook into Imbo at different phases without having to edit Imbo itself. An event listener is simply a piece of code that will be executed when a certain event is triggered from Imbo. Event listeners are added to the rr}r(h5XImbo support event listeners that you can use to hook into Imbo at different phases without having to edit Imbo itself. An event listener is simply a piece of code that will be executed when a certain event is triggered from Imbo. Event listeners are added to the h6jubh)r}r(h5X``eventListeners``hG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdXeventListenersrr}r(h5Uh6jubahEhubhdX part of the configuration array as associative arrays. If you want to disable some of the default event listeners simply specify the same key in your configuration file and set the value to rr}r(h5X part of the configuration array as associative arrays. If you want to disable some of the default event listeners simply specify the same key in your configuration file and set the value to h6jubh)r}r(h5X``null``hG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdXnullrr}r(h5Uh6jubahEhubhdX or rr}r(h5X or h6jubh)r}r(h5X ``false``hG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdXfalserr}r(h5Uh6jubahEhubhdX?. Keep in mind that not all event listeners should be disabled.rr}r(h5X?. Keep in mind that not all event listeners should be disabled.h6jubeubhh)r}r(h5X8Event listeners can be configured in the following ways:rh6jh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPMhQhhR]rhdX8Event listeners can be configured in the following ways:rr}r(h5jh6jubaubj2)r}r(h5Uh6jh;h>hEj5hG}r(j7U)hI]hJ]hK]j8UhL]hM]j9j:uhPMhQhhR]rh)r}r(h5XrA string representing a class name of a class implementing the ``Imbo\EventListener\ListenerInteface`` interface: h6jh;h>hEhhG}r(hK]hL]hJ]hI]hM]uhPNhQhhR]rhh)r}r(h5XqA string representing a class name of a class implementing the ``Imbo\EventListener\ListenerInteface`` interface:h6jh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPMhR]r(hdX?A string representing a class name of a class implementing the rr}r(h5X?A string representing a class name of a class implementing the h6jubh)r}r(h5X'``Imbo\EventListener\ListenerInteface``hG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdX#Imbo\EventListener\ListenerIntefacerr}r(h5Uh6jubahEhubhdX interface:rr}r(h5X interface:h6jubeubaubaubj)r}r(h5X array( 'accessToken' => 'Imbo\EventListener\AccessToken', ), // ... );h6jh;h>hEjhG}r(jjXphpjjhI]hJ]hK]hL]hM]uhPMhQhhR]rhdX array( 'accessToken' => 'Imbo\EventListener\AccessToken', ), // ... );rr}r(h5Uh6jubaubj2)r}r(h5Uh6jh;h>hEj5hG}r(j7U)jbKhI]hJ]hK]j8UhL]hM]j9j:uhPMhQhhR]rh)r}r(h5X`Use an instance of a class implementing the ``Imbo\EventListener\ListenerInterface`` interface: h6jh;h>hEhhG}r(hK]hL]hJ]hI]hM]uhPNhQhhR]rhh)r}r(h5X_Use an instance of a class implementing the ``Imbo\EventListener\ListenerInterface`` interface:h6jh;h>hEhlhG}r (hK]hL]hJ]hI]hM]uhPMhR]r (hdX,Use an instance of a class implementing the r r }r (h5X,Use an instance of a class implementing the h6jubh)r }r (h5X(``Imbo\EventListener\ListenerInterface``hG}r (hK]hL]hJ]hI]hM]uh6jhR]r hdX$Imbo\EventListener\ListenerInterfacer r }r (h5Uh6j ubahEhubhdX interface:r r }r (h5X interface:h6jubeubaubaubj)r }r (h5X array( 'accessToken' => new Imbo\EventListener\AccessToken(), ), // ... );h6jh;h>hEjhG}r (jjXphpjjhI]hJ]hK]hL]hM]uhPMhQhhR]r hdX array( 'accessToken' => new Imbo\EventListener\AccessToken(), ), // ... );r r }r (h5Uh6j ubaubj2)r }r (h5Uh6jh;h>hEj5hG}r (j7U)jbKhI]hJ]hK]j8UhL]hM]j9j:uhPMhQhhR]r h)r }r (h5XpA closure returning an instance of a class implementing the ``Imbo\EventListener\ListenerInterface`` interface: h6j h;h>hEhhG}r (hK]hL]hJ]hI]hM]uhPNhQhhR]r hh)r }r (h5XoA closure returning an instance of a class implementing the ``Imbo\EventListener\ListenerInterface`` interface:h6j h;h>hEhlhG}r (hK]hL]hJ]hI]hM]uhPMhR]r! (hdX<A closure returning an instance of a class implementing the r" r# }r$ (h5X<A closure returning an instance of a class implementing the h6j ubh)r% }r& (h5X(``Imbo\EventListener\ListenerInterface``hG}r' (hK]hL]hJ]hI]hM]uh6j hR]r( hdX$Imbo\EventListener\ListenerInterfacer) r* }r+ (h5Uh6j% ubahEhubhdX interface:r, r- }r. (h5X interface:h6j ubeubaubaubj)r/ }r0 (h5X array( 'accessToken' => function() { return new Imbo\EventListener\AccessToken(); }, ), // ... );h6jh;h>hEjhG}r1 (jjXphpjjhI]hJ]hK]hL]hM]uhPMhQhhR]r2 hdX array( 'accessToken' => function() { return new Imbo\EventListener\AccessToken(); }, ), // ... );r3 r4 }r5 (h5Uh6j/ ubaubj2)r6 }r7 (h5Uh6jh;h>hEj5hG}r8 (j7U)jbKhI]hJ]hK]j8UhL]hM]j9j:uhPMhQhhR]r9 h)r: }r; (h5X}Use a class implementing the ``Imbo\EventListener\ListenerInterface`` interface together with an optional public key filter: h6j6 h;h>hEhhG}r< (hK]hL]hJ]hI]hM]uhPNhQhhR]r= hh)r> }r? (h5X|Use a class implementing the ``Imbo\EventListener\ListenerInterface`` interface together with an optional public key filter:h6j: h;h>hEhlhG}r@ (hK]hL]hJ]hI]hM]uhPMhR]rA (hdXUse a class implementing the rB rC }rD (h5XUse a class implementing the h6j> ubh)rE }rF (h5X(``Imbo\EventListener\ListenerInterface``hG}rG (hK]hL]hJ]hI]hM]uh6j> hR]rH hdX$Imbo\EventListener\ListenerInterfacerI rJ }rK (h5Uh6jE ubahEhubhdX7 interface together with an optional public key filter:rL rM }rN (h5X7 interface together with an optional public key filter:h6j> ubeubaubaubj)rO }rP (h5X array( 'maxImageSize' => array( 'listener' => new Imbo\EventListener\MaxImageSize(1024, 768), 'publicKeys' => array( 'whitelist' => array('user'), // 'blacklist' => array('someotheruser'), ), // 'params' => array( ... ) ), ), // ... );h6jh;h>hEjhG}rQ (jjXphpjjhI]hJ]hK]hL]hM]uhPMhQhhR]rR hdX array( 'maxImageSize' => array( 'listener' => new Imbo\EventListener\MaxImageSize(1024, 768), 'publicKeys' => array( 'whitelist' => array('user'), // 'blacklist' => array('someotheruser'), ), // 'params' => array( ... ) ), ), // ... );rS rT }rU (h5Uh6jO ubaubhh)rV }rW (h5X+where ``listener`` is one of the following:rX h6jh;h>hEhlhG}rY (hK]hL]hJ]hI]hM]uhPM hQhhR]rZ (hdXwhere r[ r\ }r] (h5Xwhere h6jV ubh)r^ }r_ (h5X ``listener``hG}r` (hK]hL]hJ]hI]hM]uh6jV hR]ra hdXlistenerrb rc }rd (h5Uh6j^ ubahEhubhdX is one of the following:re rf }rg (h5X is one of the following:h6jV ubeubj2)rh }ri (h5Uh6jh;h>hEj5hG}rj (j7U)hI]hJ]hK]j8UhL]hM]j9U loweralphark uhPMhQhhR]rl (h)rm }rn (h5Xqa string representing a class name of a class implementing the ``Imbo\EventListener\ListenerInterface`` interfacero h6jh h;h>hEhhG}rp (hK]hL]hJ]hI]hM]uhPNhQhhR]rq hh)rr }rs (h5jo h6jm h;h>hEhlhG}rt (hK]hL]hJ]hI]hM]uhPMhR]ru (hdX?a string representing a class name of a class implementing the rv rw }rx (h5X?a string representing a class name of a class implementing the h6jr ubh)ry }rz (h5X(``Imbo\EventListener\ListenerInterface``hG}r{ (hK]hL]hJ]hI]hM]uh6jr hR]r| hdX$Imbo\EventListener\ListenerInterfacer} r~ }r (h5Uh6jy ubahEhubhdX interfacer r }r (h5X interfaceh6jr ubeubaubh)r }r (h5XEan instance of the ``Imbo\EventListener\ListenerInterface`` interfacer h6jh h;h>hEhhG}r (hK]hL]hJ]hI]hM]uhPNhQhhR]r hh)r }r (h5j h6j h;h>hEhlhG}r (hK]hL]hJ]hI]hM]uhPMhR]r (hdXan instance of the r r }r (h5Xan instance of the h6j ubh)r }r (h5X(``Imbo\EventListener\ListenerInterface``hG}r (hK]hL]hJ]hI]hM]uh6j hR]r hdX$Imbo\EventListener\ListenerInterfacer r }r (h5Uh6j ubahEhubhdX interfacer r }r (h5X interfaceh6j ubeubaubh)r }r (h5XIa closure returning an instance ``Imbo\EventListener\ListenerInterface`` h6jh h;h>hEhhG}r (hK]hL]hJ]hI]hM]uhPNhQhhR]r hh)r }r (h5XHa closure returning an instance ``Imbo\EventListener\ListenerInterface``h6j h;h>hEhlhG}r (hK]hL]hJ]hI]hM]uhPMhR]r (hdX a closure returning an instance r r }r (h5X a closure returning an instance h6j ubh)r }r (h5X(``Imbo\EventListener\ListenerInterface``hG}r (hK]hL]hJ]hI]hM]uh6j hR]r hdX$Imbo\EventListener\ListenerInterfacer r }r (h5Uh6j ubahEhubeubaubeubhh)r }r (h5XThe ``publicKeys`` element is an array that you can use if you want your listener to only be triggered for some users (public keys). The value of this is an array with two elements, ``whitelist`` and ``blacklist``, where ``whitelist`` is an array of public keys you **want** your listener to trigger for, and ``blacklist`` is an array of public keys you **don't want** your listener to trigger for. ``publicKeys`` is optional, and per default the listener will trigger for all users.r h6jh;h>hEhlhG}r (hK]hL]hJ]hI]hM]uhPMhQhhR]r (hdXThe r r }r (h5XThe h6j ubh)r }r (h5X``publicKeys``hG}r (hK]hL]hJ]hI]hM]uh6j hR]r hdX publicKeysr r }r (h5Uh6j ubahEhubhdX element is an array that you can use if you want your listener to only be triggered for some users (public keys). The value of this is an array with two elements, r r }r (h5X element is an array that you can use if you want your listener to only be triggered for some users (public keys). The value of this is an array with two elements, h6j ubh)r }r (h5X ``whitelist``hG}r (hK]hL]hJ]hI]hM]uh6j hR]r hdX whitelistr r }r (h5Uh6j ubahEhubhdX and r r }r (h5X and h6j ubh)r }r (h5X ``blacklist``hG}r (hK]hL]hJ]hI]hM]uh6j hR]r hdX blacklistr r }r (h5Uh6j ubahEhubhdX, where r r }r (h5X, where h6j ubh)r }r (h5X ``whitelist``hG}r (hK]hL]hJ]hI]hM]uh6j hR]r hdX whitelistr r }r (h5Uh6j ubahEhubhdX is an array of public keys you r r }r (h5X is an array of public keys you h6j ubj )r }r (h5X**want**hG}r (hK]hL]hJ]hI]hM]uh6j hR]r hdXwantr r }r (h5Uh6j ubahEjubhdX# your listener to trigger for, and r r }r (h5X# your listener to trigger for, and h6j ubh)r }r (h5X ``blacklist``hG}r (hK]hL]hJ]hI]hM]uh6j hR]r hdX blacklistr r }r (h5Uh6j ubahEhubhdX is an array of public keys you r r }r (h5X is an array of public keys you h6j ubj )r }r (h5X**don't want**hG}r (hK]hL]hJ]hI]hM]uh6j hR]r hdX don't wantr r }r (h5Uh6j ubahEjubhdX your listener to trigger for. r r }r (h5X your listener to trigger for. h6j ubh)r }r (h5X``publicKeys``hG}r (hK]hL]hJ]hI]hM]uh6j hR]r hdX publicKeysr r }r (h5Uh6j ubahEhubhdXF is optional, and per default the listener will trigger for all users.r r }r (h5XF is optional, and per default the listener will trigger for all users.h6j ubeubhh)r }r (h5XThere also exists a ``params`` key that can be used to specify parameters for the event listener, if you choose to specify the listener as a string in the ``listener`` key:r h6jh;h>hEhlhG}r (hK]hL]hJ]hI]hM]uhPMhQhhR]r (hdXThere also exists a r r }r (h5XThere also exists a h6j ubh)r }r (h5X ``params``hG}r (hK]hL]hJ]hI]hM]uh6j hR]r hdXparamsr r }r (h5Uh6j ubahEhubhdX} key that can be used to specify parameters for the event listener, if you choose to specify the listener as a string in the r r }r (h5X} key that can be used to specify parameters for the event listener, if you choose to specify the listener as a string in the h6j ubh)r }r (h5X ``listener``hG}r (hK]hL]hJ]hI]hM]uh6j hR]r hdXlistenerr r }r (h5Uh6j ubahEhubhdX key:r r }r (h5X key:h6j ubeubj)r }r (h5X array( 'maxImageSize' => array( 'listener' => 'Imbo\EventListener\MaxImageSize', 'publicKeys' => array( 'whitelist' => array('user'), // 'blacklist' => array('someotheruser'), ), 'params' => array( 'width' => 1024, 'height' => 768, ) ), ), // ... );h6jh;h>hEjhG}r! (jjXphpjjhI]hJ]hK]hL]hM]uhPMhQhhR]r" hdX array( 'maxImageSize' => array( 'listener' => 'Imbo\EventListener\MaxImageSize', 'publicKeys' => array( 'whitelist' => array('user'), // 'blacklist' => array('someotheruser'), ), 'params' => array( 'width' => 1024, 'height' => 768, ) ), ), // ... );r# r$ }r% (h5Uh6j ubaubhh)r& }r' (h5X^The value of the ``params`` array will be sent to the constructor of the event listener class.r( h6jh;h>hEhlhG}r) (hK]hL]hJ]hI]hM]uhPM-hQhhR]r* (hdXThe value of the r+ r, }r- (h5XThe value of the h6j& ubh)r. }r/ (h5X ``params``hG}r0 (hK]hL]hJ]hI]hM]uh6j& hR]r1 hdXparamsr2 r3 }r4 (h5Uh6j. ubahEhubhdXC array will be sent to the constructor of the event listener class.r5 r6 }r7 (h5XC array will be sent to the constructor of the event listener class.h6j& ubeubj2)r8 }r9 (h5Uh6jh;h>hEj5hG}r: (j7U)jbKhI]hJ]hK]j8UhL]hM]j9j:uhPM/hQhhR]r; h)r< }r= (h5XUse a closure directly: h6j8 h;h>hEhhG}r> (hK]hL]hJ]hI]hM]uhPNhQhhR]r? hh)r@ }rA (h5XUse a closure directly:rB h6j< h;h>hEhlhG}rC (hK]hL]hJ]hI]hM]uhPM/hR]rD hdXUse a closure directly:rE rF }rG (h5jB h6j@ ubaubaubaubj)rH }rI (h5X array( 'customListener' => array( 'callback' => function(Imbo\EventManager\EventInterface $event) { // Custom code }, 'events' => array('image.get'), 'priority' => 1, 'publicKeys' => array( 'whitelist' => array('user'), // 'blacklist' => array('someotheruser'), ), ), ), // ... );h6jh;h>hEjhG}rJ (jjXphpjjhI]hJ]hK]hL]hM]uhPM1hQhhR]rK hdX array( 'customListener' => array( 'callback' => function(Imbo\EventManager\EventInterface $event) { // Custom code }, 'events' => array('image.get'), 'priority' => 1, 'publicKeys' => array( 'whitelist' => array('user'), // 'blacklist' => array('someotheruser'), ), ), ), // ... );rL rM }rN (h5Uh6jH ubaubhh)rO }rP (h5Xwhere ``callback`` is the code you want executed, and ``events`` is an array of the events you want it triggered for. ``priority`` is the priority of the listener and defaults to 0. The higher the number, the earlier in the chain your listener will be triggered. This number can also be negative. Imbo's internal event listeners uses numbers between 0 and 100. ``publicKeys`` uses the same format as described above. If you use this method, and want your callback to trigger for multiple events with different priorities, specify an associative array in the ``events`` element, where the keys are the event names, and the values are the priorities for the different events. This way of attaching event listeners should mostly be used for quick and temporary solutions.rQ h6jh;h>hEhlhG}rR (hK]hL]hJ]hI]hM]uhPMHhQhhR]rS (hdXwhere rT rU }rV (h5Xwhere h6jO ubh)rW }rX (h5X ``callback``hG}rY (hK]hL]hJ]hI]hM]uh6jO hR]rZ hdXcallbackr[ r\ }r] (h5Uh6jW ubahEhubhdX$ is the code you want executed, and r^ r_ }r` (h5X$ is the code you want executed, and h6jO ubh)ra }rb (h5X ``events``hG}rc (hK]hL]hJ]hI]hM]uh6jO hR]rd hdXeventsre rf }rg (h5Uh6ja ubahEhubhdX6 is an array of the events you want it triggered for. rh ri }rj (h5X6 is an array of the events you want it triggered for. h6jO ubh)rk }rl (h5X ``priority``hG}rm (hK]hL]hJ]hI]hM]uh6jO hR]rn hdXpriorityro rp }rq (h5Uh6jk ubahEhubhdX is the priority of the listener and defaults to 0. The higher the number, the earlier in the chain your listener will be triggered. This number can also be negative. Imbo's internal event listeners uses numbers between 0 and 100. rr rs }rt (h5X is the priority of the listener and defaults to 0. The higher the number, the earlier in the chain your listener will be triggered. This number can also be negative. Imbo's internal event listeners uses numbers between 0 and 100. h6jO ubh)ru }rv (h5X``publicKeys``hG}rw (hK]hL]hJ]hI]hM]uh6jO hR]rx hdX publicKeysry rz }r{ (h5Uh6ju ubahEhubhdX uses the same format as described above. If you use this method, and want your callback to trigger for multiple events with different priorities, specify an associative array in the r| r} }r~ (h5X uses the same format as described above. If you use this method, and want your callback to trigger for multiple events with different priorities, specify an associative array in the h6jO ubh)r }r (h5X ``events``hG}r (hK]hL]hJ]hI]hM]uh6jO hR]r hdXeventsr r }r (h5Uh6j ubahEhubhdX element, where the keys are the event names, and the values are the priorities for the different events. This way of attaching event listeners should mostly be used for quick and temporary solutions.r r }r (h5X element, where the keys are the event names, and the values are the priorities for the different events. This way of attaching event listeners should mostly be used for quick and temporary solutions.h6jO ubeubhh)r }r (h5XAll event listeners will receive an event object (which implements ``Imbo\EventManager\EventInterface``), that is described in detail in the :ref:`the-event-object` section.r h6jh;h>hEhlhG}r (hK]hL]hJ]hI]hM]uhPMJhQhhR]r (hdXCAll event listeners will receive an event object (which implements r r }r (h5XCAll event listeners will receive an event object (which implements h6j ubh)r }r (h5X$``Imbo\EventManager\EventInterface``hG}r (hK]hL]hJ]hI]hM]uh6j hR]r hdX Imbo\EventManager\EventInterfacer r }r (h5Uh6j ubahEhubhdX&), that is described in detail in the r r }r (h5X&), that is described in detail in the h6j ubhr)r }r (h5X:ref:`the-event-object`r h6j h;h>hEhvhG}r (UreftypeXrefhxhyXthe-event-objectU refdomainXstdr hI]hJ]U refexplicithK]hL]hM]h{h|uhPMJhR]r h~)r }r (h5j hG}r (hK]hL]r (hj Xstd-refr ehJ]hI]hM]uh6j hR]r hdXthe-event-objectr r }r (h5Uh6j ubahEhubaubhdX section.r r }r (h5X section.h6j ubeubh7)r }r (h5Uh6jh;h>hEhShG}r (hK]hL]hJ]hI]r Ulisteners-added-by-defaultr ahM]r h auhPMMhQhhR]r (h])r }r (h5XListeners added by defaultr h6j h;h>hEhahG}r (hK]hL]hJ]hI]hM]uhPMMhQhhR]r hdXListeners added by defaultr r }r (h5j h6j ubaubhh)r }r (h5XHThe default configuration file includes some event listeners by default:r h6j h;h>hEhlhG}r (hK]hL]hJ]hI]hM]uhPMOhQhhR]r hdXHThe default configuration file includes some event listeners by default:r r }r (h5j h6j ubaubh)r }r (h5Uh6j h;h>hEhhG}r (jX*hI]hJ]hK]hL]hM]uhPMQhQhhR]r (h)r }r (h5X":ref:`access-token-event-listener`r h6j h;h>hEhhG}r (hK]hL]hJ]hI]hM]uhPNhQhhR]r hh)r }r (h5j h6j h;h>hEhlhG}r (hK]hL]hJ]hI]hM]uhPMQhR]r hr)r }r (h5j h6j h;h>hEhvhG}r (UreftypeXrefhxhyXaccess-token-event-listenerU refdomainXstdr hI]hJ]U refexplicithK]hL]hM]h{h|uhPMQhR]r h~)r }r (h5j hG}r (hK]hL]r (hj Xstd-refr ehJ]hI]hM]uh6j hR]r hdXaccess-token-event-listenerr r }r (h5Uh6j ubahEhubaubaubaubh)r }r (h5X":ref:`authenticate-event-listener`r h6j h;h>hEhhG}r (hK]hL]hJ]hI]hM]uhPNhQhhR]r hh)r }r (h5j h6j h;h>hEhlhG}r (hK]hL]hJ]hI]hM]uhPMRhR]r hr)r }r (h5j h6j h;h>hEhvhG}r (UreftypeXrefhxhyXauthenticate-event-listenerU refdomainXstdr hI]hJ]U refexplicithK]hL]hM]h{h|uhPMRhR]r h~)r }r (h5j hG}r (hK]hL]r (hj Xstd-refr ehJ]hI]hM]uh6j hR]r hdXauthenticate-event-listenerr r }r (h5Uh6j ubahEhubaubaubaubh)r }r (h5X":ref:`stats-access-event-listener`r h6j h;h>hEhhG}r (hK]hL]hJ]hI]hM]uhPNhQhhR]r hh)r }r (h5j h6j h;h>hEhlhG}r (hK]hL]hJ]hI]hM]uhPMShR]r hr)r }r (h5j h6j h;h>hEhvhG}r (UreftypeXrefhxhyXstats-access-event-listenerU refdomainXstdr hI]hJ]U refexplicithK]hL]hM]h{h|uhPMShR]r h~)r }r (h5j hG}r (hK]hL]r (hj Xstd-refr ehJ]hI]hM]uh6j hR]r hdXstats-access-event-listenerr r }r (h5Uh6j ubahEhubaubaubaubh)r }r (h5X:ref:`imagick-event-listener` h6j h;h>hEhhG}r (hK]hL]hJ]hI]hM]uhPNhQhhR]r hh)r }r (h5X:ref:`imagick-event-listener`r h6j h;h>hEhlhG}r (hK]hL]hJ]hI]hM]uhPMThR]r hr)r }r (h5j h6j h;h>hEhvhG}r (UreftypeXrefhxhyXimagick-event-listenerU refdomainXstdr hI]hJ]U refexplicithK]hL]hM]h{h|uhPMThR]r h~)r }r (h5j hG}r (hK]hL]r (hj Xstd-refr ehJ]hI]hM]uh6j hR]r hdXimagick-event-listenerr! r" }r# (h5Uh6j ubahEhubaubaubaubeubhh)r$ }r% (h5X5as well as event listeners for image transformations:r& h6j h;h>hEhlhG}r' (hK]hL]hJ]hI]hM]uhPMVhQhhR]r( hdX5as well as event listeners for image transformations:r) r* }r+ (h5j& h6j$ ubaubh)r, }r- (h5Uh6j h;h>hEhhG}r. (jX*hI]hJ]hK]hL]hM]uhPMXhQhhR]r/ (h)r0 }r1 (h5X.:ref:`autoRotate `r2 h6j, h;h>hEhhG}r3 (hK]hL]hJ]hI]hM]uhPNhQhhR]r4 hh)r5 }r6 (h5j2 h6j0 h;h>hEhlhG}r7 (hK]hL]hJ]hI]hM]uhPMXhR]r8 hr)r9 }r: (h5j2 h6j5 h;h>hEhvhG}r; (UreftypeXrefhxhyXauto-rotate-transformationU refdomainXstdr< hI]hJ]U refexplicithK]hL]hM]h{h|uhPMXhR]r= h~)r> }r? (h5j2 hG}r@ (hK]hL]rA (hj< Xstd-refrB ehJ]hI]hM]uh6j9 hR]rC hdX autoRotaterD rE }rF (h5Uh6j> ubahEhubaubaubaubh)rG }rH (h5X%:ref:`border `rI h6j, h;h>hEhhG}rJ (hK]hL]hJ]hI]hM]uhPNhQhhR]rK hh)rL }rM (h5jI h6jG h;h>hEhlhG}rN (hK]hL]hJ]hI]hM]uhPMYhR]rO hr)rP }rQ (h5jI h6jL h;h>hEhvhG}rR (UreftypeXrefhxhyXborder-transformationU refdomainXstdrS hI]hJ]U refexplicithK]hL]hM]h{h|uhPMYhR]rT h~)rU }rV (h5jI hG}rW (hK]hL]rX (hjS Xstd-refrY ehJ]hI]hM]uh6jP hR]rZ hdXborderr[ r\ }r] (h5Uh6jU ubahEhubaubaubaubh)r^ }r_ (h5X%:ref:`canvas `r` h6j, h;h>hEhhG}ra (hK]hL]hJ]hI]hM]uhPNhQhhR]rb hh)rc }rd (h5j` h6j^ h;h>hEhlhG}re (hK]hL]hJ]hI]hM]uhPMZhR]rf hr)rg }rh (h5j` h6jc h;h>hEhvhG}ri (UreftypeXrefhxhyXcanvas-transformationU refdomainXstdrj hI]hJ]U refexplicithK]hL]hM]h{h|uhPMZhR]rk h~)rl }rm (h5j` hG}rn (hK]hL]ro (hjj Xstd-refrp ehJ]hI]hM]uh6jg hR]rq hdXcanvasrr rs }rt (h5Uh6jl ubahEhubaubaubaubh)ru }rv (h5X):ref:`compress `rw h6j, h;h>hEhhG}rx (hK]hL]hJ]hI]hM]uhPNhQhhR]ry hh)rz }r{ (h5jw h6ju h;h>hEhlhG}r| (hK]hL]hJ]hI]hM]uhPM[hR]r} hr)r~ }r (h5jw h6jz h;h>hEhvhG}r (UreftypeXrefhxhyXcompress-transformationU refdomainXstdr hI]hJ]U refexplicithK]hL]hM]h{h|uhPM[hR]r h~)r }r (h5jw hG}r (hK]hL]r (hj Xstd-refr ehJ]hI]hM]uh6j~ hR]r hdXcompressr r }r (h5Uh6j ubahEhubaubaubaubh)r }r (h5X':ref:`convert `r h6j, h;h>hEhhG}r (hK]hL]hJ]hI]hM]uhPNhQhhR]r hh)r }r (h5j h6j h;h>hEhlhG}r (hK]hL]hJ]hI]hM]uhPM\hR]r hr)r }r (h5j h6j h;h>hEhvhG}r (UreftypeXrefhxhyXconvert-transformationU refdomainXstdr hI]hJ]U refexplicithK]hL]hM]h{h|uhPM\hR]r h~)r }r (h5j hG}r (hK]hL]r (hj Xstd-refr ehJ]hI]hM]uh6j hR]r hdXconvertr r }r (h5Uh6j ubahEhubaubaubaubh)r }r (h5X!:ref:`crop `r h6j, h;h>hEhhG}r (hK]hL]hJ]hI]hM]uhPNhQhhR]r hh)r }r (h5j h6j h;h>hEhlhG}r (hK]hL]hJ]hI]hM]uhPM]hR]r hr)r }r (h5j h6j h;h>hEhvhG}r (UreftypeXrefhxhyXcrop-transformationU refdomainXstdr hI]hJ]U refexplicithK]hL]hM]h{h|uhPM]hR]r h~)r }r (h5j hG}r (hK]hL]r (hj Xstd-refr ehJ]hI]hM]uh6j hR]r hdXcropr r }r (h5Uh6j ubahEhubaubaubaubh)r }r (h5X-:ref:`desaturate `r h6j, h;h>hEhhG}r (hK]hL]hJ]hI]hM]uhPNhQhhR]r hh)r }r (h5j h6j h;h>hEhlhG}r (hK]hL]hJ]hI]hM]uhPM^hR]r hr)r }r (h5j h6j h;h>hEhvhG}r (UreftypeXrefhxhyXdesaturate-transformationU refdomainXstdr hI]hJ]U refexplicithK]hL]hM]h{h|uhPM^hR]r h~)r }r (h5j hG}r (hK]hL]r (hj Xstd-refr ehJ]hI]hM]uh6j hR]r hdX desaturater r }r (h5Uh6j ubahEhubaubaubaubh)r }r (h5X::ref:`flipHorizontally `r h6j, h;h>hEhhG}r (hK]hL]hJ]hI]hM]uhPNhQhhR]r hh)r }r (h5j h6j h;h>hEhlhG}r (hK]hL]hJ]hI]hM]uhPM_hR]r hr)r }r (h5j h6j h;h>hEhvhG}r (UreftypeXrefhxhyX flip-horizontally-transformationU refdomainXstdr hI]hJ]U refexplicithK]hL]hM]h{h|uhPM_hR]r h~)r }r (h5j hG}r (hK]hL]r (hj Xstd-refr ehJ]hI]hM]uh6j hR]r hdXflipHorizontallyr r }r (h5Uh6j ubahEhubaubaubaubh)r }r (h5X6:ref:`flipVertically `r h6j, h;h>hEhhG}r (hK]hL]hJ]hI]hM]uhPNhQhhR]r hh)r }r (h5j h6j h;h>hEhlhG}r (hK]hL]hJ]hI]hM]uhPM`hR]r hr)r }r (h5j h6j h;h>hEhvhG}r (UreftypeXrefhxhyXflip-vertically-transformationU refdomainXstdr hI]hJ]U refexplicithK]hL]hM]h{h|uhPM`hR]r h~)r }r (h5j hG}r (hK]hL]r (hj Xstd-refr ehJ]hI]hM]uh6j hR]r hdXflipVerticallyr r }r (h5Uh6j ubahEhubaubaubaubh)r }r (h5X(:ref:`maxSize `r h6j, h;h>hEhhG}r (hK]hL]hJ]hI]hM]uhPNhQhhR]r hh)r }r (h5j h6j h;h>hEhlhG}r (hK]hL]hJ]hI]hM]uhPMahR]r hr)r }r (h5j h6j h;h>hEhvhG}r (UreftypeXrefhxhyXmax-size-transformationU refdomainXstdr hI]hJ]U refexplicithK]hL]hM]h{h|uhPMahR]r h~)r }r (h5j hG}r (hK]hL]r (hj Xstd-refr ehJ]hI]hM]uh6j hR]r hdXmaxSizer r }r (h5Uh6j ubahEhubaubaubaubh)r }r (h5X%:ref:`resize `r h6j, h;h>hEhhG}r (hK]hL]hJ]hI]hM]uhPNhQhhR]r hh)r }r (h5j h6j h;h>hEhlhG}r (hK]hL]hJ]hI]hM]uhPMbhR]r hr)r }r (h5j h6j h;h>hEhvhG}r! (UreftypeXrefhxhyXresize-transformationU refdomainXstdr" hI]hJ]U refexplicithK]hL]hM]h{h|uhPMbhR]r# h~)r$ }r% (h5j hG}r& (hK]hL]r' (hj" Xstd-refr( ehJ]hI]hM]uh6j hR]r) hdXresizer* r+ }r, (h5Uh6j$ ubahEhubaubaubaubh)r- }r. (h5X%:ref:`rotate `r/ h6j, h;h>hEhhG}r0 (hK]hL]hJ]hI]hM]uhPNhQhhR]r1 hh)r2 }r3 (h5j/ h6j- h;h>hEhlhG}r4 (hK]hL]hJ]hI]hM]uhPMchR]r5 hr)r6 }r7 (h5j/ h6j2 h;h>hEhvhG}r8 (UreftypeXrefhxhyXrotate-transformationU refdomainXstdr9 hI]hJ]U refexplicithK]hL]hM]h{h|uhPMchR]r: h~)r; }r< (h5j/ hG}r= (hK]hL]r> (hj9 Xstd-refr? ehJ]hI]hM]uh6j6 hR]r@ hdXrotaterA rB }rC (h5Uh6j; ubahEhubaubaubaubh)rD }rE (h5X#:ref:`sepia `rF h6j, h;h>hEhhG}rG (hK]hL]hJ]hI]hM]uhPNhQhhR]rH hh)rI }rJ (h5jF h6jD h;h>hEhlhG}rK (hK]hL]hJ]hI]hM]uhPMdhR]rL hr)rM }rN (h5jF h6jI h;h>hEhvhG}rO (UreftypeXrefhxhyXsepia-transformationU refdomainXstdrP hI]hJ]U refexplicithK]hL]hM]h{h|uhPMdhR]rQ h~)rR }rS (h5jF hG}rT (hK]hL]rU (hjP Xstd-refrV ehJ]hI]hM]uh6jM hR]rW hdXsepiarX rY }rZ (h5Uh6jR ubahEhubaubaubaubh)r[ }r\ (h5X#:ref:`strip `r] h6j, h;h>hEhhG}r^ (hK]hL]hJ]hI]hM]uhPNhQhhR]r_ hh)r` }ra (h5j] h6j[ h;h>hEhlhG}rb (hK]hL]hJ]hI]hM]uhPMehR]rc hr)rd }re (h5j] h6j` h;h>hEhvhG}rf (UreftypeXrefhxhyXstrip-transformationU refdomainXstdrg hI]hJ]U refexplicithK]hL]hM]h{h|uhPMehR]rh h~)ri }rj (h5j] hG}rk (hK]hL]rl (hjg Xstd-refrm ehJ]hI]hM]uh6jd hR]rn hdXstripro rp }rq (h5Uh6ji ubahEhubaubaubaubh)rr }rs (h5X+:ref:`thumbnail `rt h6j, h;h>hEhhG}ru (hK]hL]hJ]hI]hM]uhPNhQhhR]rv hh)rw }rx (h5jt h6jr h;h>hEhlhG}ry (hK]hL]hJ]hI]hM]uhPMfhR]rz hr)r{ }r| (h5jt h6jw h;h>hEhvhG}r} (UreftypeXrefhxhyXthumbnail-transformationU refdomainXstdr~ hI]hJ]U refexplicithK]hL]hM]h{h|uhPMfhR]r h~)r }r (h5jt hG}r (hK]hL]r (hj~ Xstd-refr ehJ]hI]hM]uh6j{ hR]r hdX thumbnailr r }r (h5Uh6j ubahEhubaubaubaubh)r }r (h5X+:ref:`transpose `r h6j, h;h>hEhhG}r (hK]hL]hJ]hI]hM]uhPNhQhhR]r hh)r }r (h5j h6j h;h>hEhlhG}r (hK]hL]hJ]hI]hM]uhPMghR]r hr)r }r (h5j h6j h;h>hEhvhG}r (UreftypeXrefhxhyXtranspose-transformationU refdomainXstdr hI]hJ]U refexplicithK]hL]hM]h{h|uhPMghR]r h~)r }r (h5j hG}r (hK]hL]r (hj Xstd-refr ehJ]hI]hM]uh6j hR]r hdX transposer r }r (h5Uh6j ubahEhubaubaubaubh)r }r (h5X-:ref:`transverse `r h6j, h;h>hEhhG}r (hK]hL]hJ]hI]hM]uhPNhQhhR]r hh)r }r (h5j h6j h;h>hEhlhG}r (hK]hL]hJ]hI]hM]uhPMhhR]r hr)r }r (h5j h6j h;h>hEhvhG}r (UreftypeXrefhxhyXtransverse-transformationU refdomainXstdr hI]hJ]U refexplicithK]hL]hM]h{h|uhPMhhR]r h~)r }r (h5j hG}r (hK]hL]r (hj Xstd-refr ehJ]hI]hM]uh6j hR]r hdX transverser r }r (h5Uh6j ubahEhubaubaubaubh)r }r (h5X,:ref:`watermark ` h6j, h;h>hEhhG}r (hK]hL]hJ]hI]hM]uhPNhQhhR]r hh)r }r (h5X+:ref:`watermark `r h6j h;h>hEhlhG}r (hK]hL]hJ]hI]hM]uhPMihR]r hr)r }r (h5j h6j h;h>hEhvhG}r (UreftypeXrefhxhyXwatermark-transformationU refdomainXstdr hI]hJ]U refexplicithK]hL]hM]h{h|uhPMihR]r h~)r }r (h5j hG}r (hK]hL]r (hj Xstd-refr ehJ]hI]hM]uh6j hR]r hdX watermarkr r }r (h5Uh6j ubahEhubaubaubaubeubhh)r }r (h5XRead more about these listeners (and more) in the :doc:`../installation/event_listeners` and :doc:`../usage/image-transformations` chapters. If you want to disable any of these you could do so in your configuration file in the following way:r h6j h;h>hEhlhG}r (hK]hL]hJ]hI]hM]uhPMkhQhhR]r (hdX2Read more about these listeners (and more) in the r r }r (h5X2Read more about these listeners (and more) in the h6j ubhr)r }r (h5X&:doc:`../installation/event_listeners`r h6j h;h>hEhvhG}r (UreftypeXdocr hxhyX../installation/event_listenersU refdomainUhI]hJ]U refexplicithK]hL]hM]h{h|uhPMkhR]r h)r }r (h5j hG}r (hK]hL]r (hj ehJ]hI]hM]uh6j hR]r hdX../installation/event_listenersr r }r (h5Uh6j ubahEhubaubhdX and r r }r (h5X and h6j ubhr)r }r (h5X%:doc:`../usage/image-transformations`r h6j h;h>hEhvhG}r (UreftypeXdocr hxhyX../usage/image-transformationsU refdomainUhI]hJ]U refexplicithK]hL]hM]h{h|uhPMkhR]r h)r }r (h5j hG}r (hK]hL]r (hj ehJ]hI]hM]uh6j hR]r hdX../usage/image-transformationsr r }r (h5Uh6j ubahEhubaubhdXo chapters. If you want to disable any of these you could do so in your configuration file in the following way:r r }r (h5Xo chapters. If you want to disable any of these you could do so in your configuration file in the following way:h6j ubeubj)r }r (h5X array( 'accessToken' => null, 'auth' => null, 'statsAccess' => null, ), // ... );h6j h;h>hEjhG}r (jjXphpjjhI]hJ]hK]hL]hM]uhPMmhQhhR]r hdX array( 'accessToken' => null, 'auth' => null, 'statsAccess' => null, ), // ... );r r }r (h5Uh6j ubaubcdocutils.nodes warning r )r }r (h5XDo not disable the event listeners used in the example above unless you are absolutely sure about the consequences. Your images can potentially be deleted by anyone.r h6j h;h>hEUwarningr hG}r (hK]hL]hJ]hI]hM]uhPNhQhhR]r hh)r }r (h5j h6j h;h>hEhlhG}r (hK]hL]hJ]hI]hM]uhPM|hR]r hdXDo not disable the event listeners used in the example above unless you are absolutely sure about the consequences. Your images can potentially be deleted by anyone.r r }r (h5j h6j ubaubaubj )r }r (h5XBDisabling image transformation event listeners is not recommended.r h6j h;h>hEj hG}r (hK]hL]hJ]hI]hM]uhPNhQhhR]r hh)r }r (h5j h6j h;h>hEhlhG}r (hK]hL]hJ]hI]hM]uhPM}hR]r hdXBDisabling image transformation event listeners is not recommended.r r }r (h5j h6j ubaubaubhB)r }r (h5X!.. _image-transformations-config:h6j h;h>hEhFhG}r (hI]hJ]hK]hL]hM]hNUimage-transformations-configr uhPMhQhhR]ubhB)r }r (h5X... _configuration-event-listener-initializers:h6j h;h>h@}r hj shEhFhG}r (hI]hJ]hK]hL]hM]hNU)configuration-event-listener-initializersr! uhPMhQhhZ}r" j j shR]ubeubeubh7)r# }r$ (h5Uh6h8h;h>h@}r% (h#j hj uhEhShG}r& (hK]hL]hJ]hI]r' (j&j! j ehM]r( (hh#heuhPMhQhhZ}r) (j! j j j uhR]r* (h])r+ }r, (h5X;Event listener initializers - ``eventListenerInitializers``r- h6j# h;h>hEhahG}r. (hI]hJ]hK]hL]hM]hNj%uhPMhQhhR]r/ (hdXEvent listener initializers - r0 r1 }r2 (h5j+h6j+ ubh)r3 }r4 (h5j.hG}r5 (hK]hL]hJ]hI]hM]uh6j+ hR]r6 hdXeventListenerInitializersr7 r8 }r9 (h5Uh6j3 ubahEhubeubhh)r: }r; (h5XOSome event listeners might require custom initialization, and if you don't want to do this in-line in the configuration, Imbo supports event listener initializer classes. This is handled via the ``eventListenerInitializers`` key. The value of this element is an associative array where the keys identify the initializers (only used in the configuration itself), and the values are strings representing class names, or implementations of the ``Imbo\EventListener\Initializer\InitializerInterface`` interface. If you specify strings the classes you refer to must also implement this interface.r< h6j# h;h>hEhlhG}r= (hK]hL]hJ]hI]hM]uhPMhQhhR]r> (hdXSome event listeners might require custom initialization, and if you don't want to do this in-line in the configuration, Imbo supports event listener initializer classes. This is handled via the r? r@ }rA (h5XSome event listeners might require custom initialization, and if you don't want to do this in-line in the configuration, Imbo supports event listener initializer classes. This is handled via the h6j: ubh)rB }rC (h5X``eventListenerInitializers``hG}rD (hK]hL]hJ]hI]hM]uh6j: hR]rE hdXeventListenerInitializersrF rG }rH (h5Uh6jB ubahEhubhdX key. The value of this element is an associative array where the keys identify the initializers (only used in the configuration itself), and the values are strings representing class names, or implementations of the rI rJ }rK (h5X key. The value of this element is an associative array where the keys identify the initializers (only used in the configuration itself), and the values are strings representing class names, or implementations of the h6j: ubh)rL }rM (h5X7``Imbo\EventListener\Initializer\InitializerInterface``hG}rN (hK]hL]hJ]hI]hM]uh6j: hR]rO hdX3Imbo\EventListener\Initializer\InitializerInterfacerP rQ }rR (h5Uh6jL ubahEhubhdX_ interface. If you specify strings the classes you refer to must also implement this interface.rS rT }rU (h5X_ interface. If you specify strings the classes you refer to must also implement this interface.h6j: ubeubhh)rV }rW (h5XThe interface has a single method called ``initialize`` and receives instances of event listeners implementing the ``Imbo\EventListener\ListenerInterface`` interface. This method is called once for each event listener instantiated by Imbo's event manager. Example:rX h6j# h;h>hEhlhG}rY (hK]hL]hJ]hI]hM]uhPMhQhhR]rZ (hdX)The interface has a single method called r[ r\ }r] (h5X)The interface has a single method called h6jV ubh)r^ }r_ (h5X``initialize``hG}r` (hK]hL]hJ]hI]hM]uh6jV hR]ra hdX initializerb rc }rd (h5Uh6j^ ubahEhubhdX< and receives instances of event listeners implementing the re rf }rg (h5X< and receives instances of event listeners implementing the h6jV ubh)rh }ri (h5X(``Imbo\EventListener\ListenerInterface``hG}rj (hK]hL]hJ]hI]hM]uh6jV hR]rk hdX$Imbo\EventListener\ListenerInterfacerl rm }rn (h5Uh6jh ubahEhubhdXm interface. This method is called once for each event listener instantiated by Imbo's event manager. Example:ro rp }rq (h5Xm interface. This method is called once for each event listener instantiated by Imbo's event manager. Example:h6jV ubeubj)rr }rs (h5X2dependency = new SomeDependency(); } public function initialize(Imbo\EventListener\ListenerInterface $listener) { if ($listener instanceof Listener || $listener instanceof OtherListener) { $listener->setDependency($this->dependency); } } } // Configuration return array( 'eventListeners' => array( 'customListener' => 'Listener', 'otherCustomListener' => 'OtherListener', ), 'eventListenerInitializers' => array( 'initializerForCustomListener' => 'Initializer', ), );h6j# h;h>hEjhG}rt (jjXphpjjhI]hJ]hK]hL]hM]uhPMhQhhR]ru hdX2dependency = new SomeDependency(); } public function initialize(Imbo\EventListener\ListenerInterface $listener) { if ($listener instanceof Listener || $listener instanceof OtherListener) { $listener->setDependency($this->dependency); } } } // Configuration return array( 'eventListeners' => array( 'customListener' => 'Listener', 'otherCustomListener' => 'OtherListener', ), 'eventListenerInitializers' => array( 'initializerForCustomListener' => 'Initializer', ), );rv rw }rx (h5Uh6jr ubaubhh)ry }rz (h5XIn the above example the ``Initializer`` class will be instantiated by Imbo, and in the ``__construct`` method it will create an instance of some dependency. When the event manager creates the instances of the two event listeners these will in turn be sent to the ``initialize`` method, and the same dependency will be injected into both listeners. An alternative way to accomplish this by using Closures in the configuration could look something like this:r{ h6j# h;h>hEhlhG}r| (hK]hL]hJ]hI]hM]uhPMhQhhR]r} (hdXIn the above example the r~ r }r (h5XIn the above example the h6jy ubh)r }r (h5X``Initializer``hG}r (hK]hL]hJ]hI]hM]uh6jy hR]r hdX Initializerr r }r (h5Uh6j ubahEhubhdX0 class will be instantiated by Imbo, and in the r r }r (h5X0 class will be instantiated by Imbo, and in the h6jy ubh)r }r (h5X``__construct``hG}r (hK]hL]hJ]hI]hM]uh6jy hR]r hdX __constructr r }r (h5Uh6j ubahEhubhdX method it will create an instance of some dependency. When the event manager creates the instances of the two event listeners these will in turn be sent to the r r }r (h5X method it will create an instance of some dependency. When the event manager creates the instances of the two event listeners these will in turn be sent to the h6jy ubh)r }r (h5X``initialize``hG}r (hK]hL]hJ]hI]hM]uh6jy hR]r hdX initializer r }r (h5Uh6j ubahEhubhdX method, and the same dependency will be injected into both listeners. An alternative way to accomplish this by using Closures in the configuration could look something like this:r r }r (h5X method, and the same dependency will be injected into both listeners. An alternative way to accomplish this by using Closures in the configuration could look something like this:h6jy ubeubj)r }r (h5X array( 'customListener' => function() use ($dependency) { $listener = new Listener(); $listener->setDependency($dependency); return $listener; }, 'otherCustomListener' => function() use ($dependency) { $listener = new OtherListener(); $listener->setDependency($dependency); return $listener; }, ), );h6j# h;h>hEjhG}r (jjXphpjjhI]hJ]hK]hL]hM]uhPMhQhhR]r hdX array( 'customListener' => function() use ($dependency) { $listener = new Listener(); $listener->setDependency($dependency); return $listener; }, 'otherCustomListener' => function() use ($dependency) { $listener = new OtherListener(); $listener->setDependency($dependency); return $listener; }, ), );r r }r (h5Uh6j ubaubhh)r }r (h5XImbo itself includes an event listener initializer in the default configuration that is used to inject the same instance of Imagick to all image transformations.r h6j# h;h>hEhlhG}r (hK]hL]hJ]hI]hM]uhPMhQhhR]r hdXImbo itself includes an event listener initializer in the default configuration that is used to inject the same instance of Imagick to all image transformations.r r }r (h5j h6j ubaubcdocutils.nodes note r )r }r (h5XOnly event listeners specified as strings (class names) in the configuration will be instantiated by Imbo, so event listeners instantiated in the configuration array, either directly or via a Closures, will not be initialized by the configured event listener initializers.r h6j# h;h>hEUnoter hG}r (hK]hL]hJ]hI]hM]uhPNhQhhR]r hh)r }r (h5j h6j h;h>hEhlhG}r (hK]hL]hJ]hI]hM]uhPMhR]r hdXOnly event listeners specified as strings (class names) in the configuration will be instantiated by Imbo, so event listeners instantiated in the configuration array, either directly or via a Closures, will not be initialized by the configured event listener initializers.r r }r (h5j h6j ubaubaubeubh7)r }r (h5Uh6h8h;h>hEhShG}r (hK]hL]hJ]hI]r jAahM]r h auhPMhQhhR]r (h])r }r (h5X8Image transformation presets - ``transformationPresets``r h6j h;h>hEhahG}r (hI]hJ]hK]hL]hM]hNj@uhPMhQhhR]r (hdXImage transformation presets - r r }r (h5jFh6j ubh)r }r (h5jIhG}r (hK]hL]hJ]hI]hM]uh6j hR]r hdXtransformationPresetsr r }r (h5Uh6j ubahEhubeubhh)r }r (h5XThrough the configuration you can also combine image transformations to make presets (transformation chains). This is done via the ``transformationPresets`` key:r h6j h;h>hEhlhG}r (hK]hL]hJ]hI]hM]uhPMhQhhR]r (hdXThrough the configuration you can also combine image transformations to make presets (transformation chains). This is done via the r r }r (h5XThrough the configuration you can also combine image transformations to make presets (transformation chains). This is done via the h6j ubh)r }r (h5X``transformationPresets``hG}r (hK]hL]hJ]hI]hM]uh6j hR]r hdXtransformationPresetsr r }r (h5Uh6j ubahEhubhdX key:r r }r (h5X key:h6j ubeubj)r }r (h5X array( 'graythumb' => array( 'thumbnail', 'desaturate', ), // ... ), // ... );h6j h;h>hEjhG}r (jjXphpjjhI]hJ]hK]hL]hM]uhPMhQhhR]r hdX array( 'graythumb' => array( 'thumbnail', 'desaturate', ), // ... ), // ... );r r }r (h5Uh6j ubaubhh)r }r (h5XGwhere the keys are the names of the transformations as specified in the URL, and the values are arrays containing other transformation names (as used in the ``eventListeners`` part of the configuration). You can also specify hard coded parameters for the presets if some of the transformations in the chain supports parameters:r h6j h;h>hEhlhG}r (hK]hL]hJ]hI]hM]uhPMhQhhR]r (hdXwhere the keys are the names of the transformations as specified in the URL, and the values are arrays containing other transformation names (as used in the r r }r (h5Xwhere the keys are the names of the transformations as specified in the URL, and the values are arrays containing other transformation names (as used in the h6j ubh)r }r (h5X``eventListeners``hG}r (hK]hL]hJ]hI]hM]uh6j hR]r hdXeventListenersr r }r (h5Uh6j ubahEhubhdX part of the configuration). You can also specify hard coded parameters for the presets if some of the transformations in the chain supports parameters:r r }r (h5X part of the configuration). You can also specify hard coded parameters for the presets if some of the transformations in the chain supports parameters:h6j ubeubj)r }r (h5X" array( 'fixedGraythumb' => array( 'thumbnail' => array( 'width' => 50, 'height' => 50, ), 'desaturate', ), // ... ), // ... );h6j h;h>hEjhG}r (jjXphpjjhI]hJ]hK]hL]hM]uhPMhQhhR]r hdX" array( 'fixedGraythumb' => array( 'thumbnail' => array( 'width' => 50, 'height' => 50, ), 'desaturate', ), // ... ), // ... );rr}r(h5Uh6j ubaubhh)r}r(h5X4By doing this the ``thumbnail`` part of the ``fixedGraythumb`` preset will ignore the ``width`` and ``height`` query parameters, if present. By only specifying for instance ``'width' => 50`` in the configuration the height of the thumbnail can be adjusted via the query parameter, but the ``width`` is fixed.rh6j h;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPMhQhhR]r(hdXBy doing this the rr }r (h5XBy doing this the h6jubh)r }r (h5X ``thumbnail``hG}r (hK]hL]hJ]hI]hM]uh6jhR]rhdX thumbnailrr}r(h5Uh6j ubahEhubhdX part of the rr}r(h5X part of the h6jubh)r}r(h5X``fixedGraythumb``hG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdXfixedGraythumbrr}r(h5Uh6jubahEhubhdX preset will ignore the rr}r(h5X preset will ignore the h6jubh)r}r (h5X ``width``hG}r!(hK]hL]hJ]hI]hM]uh6jhR]r"hdXwidthr#r$}r%(h5Uh6jubahEhubhdX and r&r'}r((h5X and h6jubh)r)}r*(h5X ``height``hG}r+(hK]hL]hJ]hI]hM]uh6jhR]r,hdXheightr-r.}r/(h5Uh6j)ubahEhubhdX? query parameters, if present. By only specifying for instance r0r1}r2(h5X? query parameters, if present. By only specifying for instance h6jubh)r3}r4(h5X``'width' => 50``hG}r5(hK]hL]hJ]hI]hM]uh6jhR]r6hdX 'width' => 50r7r8}r9(h5Uh6j3ubahEhubhdXc in the configuration the height of the thumbnail can be adjusted via the query parameter, but the r:r;}r<(h5Xc in the configuration the height of the thumbnail can be adjusted via the query parameter, but the h6jubh)r=}r>(h5X ``width``hG}r?(hK]hL]hJ]hI]hM]uh6jhR]r@hdXwidthrArB}rC(h5Uh6j=ubahEhubhdX is fixed.rDrE}rF(h5X is fixed.h6jubeubj )rG}rH(h5XThe URL's will stay the same if you change the transformation chain in a preset. Keep this in mind if you use for instance Varnish or some other HTTP accelerator in front of your web server(s).rIh6j h;h>hEj hG}rJ(hK]hL]hJ]hI]hM]uhPNhQhhR]rKhh)rL}rM(h5jIh6jGh;h>hEhlhG}rN(hK]hL]hJ]hI]hM]uhPMhR]rOhdXThe URL's will stay the same if you change the transformation chain in a preset. Keep this in mind if you use for instance Varnish or some other HTTP accelerator in front of your web server(s).rPrQ}rR(h5jIh6jLubaubaubeubh7)rS}rT(h5Uh6h8h;h>hEhShG}rU(hK]hL]hJ]hI]rVj\ahM]rWhauhPMhQhhR]rX(h])rY}rZ(h5X:Custom resources and routes - ``resources`` and ``routes``r[h6jSh;h>hEhahG}r\(hI]hJ]hK]hL]hM]hNj[uhPMhQhhR]r](hdXCustom resources and routes - r^r_}r`(h5jah6jYubh)ra}rb(h5jdhG}rc(hK]hL]hJ]hI]hM]uh6jYhR]rdhdX resourcesrerf}rg(h5Uh6jaubahEhubhdX and rhri}rj(h5jmh6jYubh)rk}rl(h5jphG}rm(hK]hL]hJ]hI]hM]uh6jYhR]rnhdXroutesrorp}rq(h5Uh6jkubahEhubeubj )rr}rs(h5XCustom resources and routes is an experimental and advanced way of extending Imbo, and requires extensive knowledge of how Imbo works internally. This feature can potentially be removed in future releases, so only use this for testing purposes.rth6jSh;h>hEj hG}ru(hK]hL]hJ]hI]hM]uhPNhQhhR]rvhh)rw}rx(h5jth6jrh;h>hEhlhG}ry(hK]hL]hJ]hI]hM]uhPMhR]rzhdXCustom resources and routes is an experimental and advanced way of extending Imbo, and requires extensive knowledge of how Imbo works internally. This feature can potentially be removed in future releases, so only use this for testing purposes.r{r|}r}(h5jth6jwubaubaubhh)r~}r(h5XIf you need to create a custom route you can attach a route and a custom resource class using the configuration. Two keys exists for this purpose: ``resources`` and ``routes``:rh6jSh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPM hQhhR]r(hdXIf you need to create a custom route you can attach a route and a custom resource class using the configuration. Two keys exists for this purpose: rr}r(h5XIf you need to create a custom route you can attach a route and a custom resource class using the configuration. Two keys exists for this purpose: h6j~ubh)r}r(h5X ``resources``hG}r(hK]hL]hJ]hI]hM]uh6j~hR]rhdX resourcesrr}r(h5Uh6jubahEhubhdX and rr}r(h5X and h6j~ubh)r}r(h5X ``routes``hG}r(hK]hL]hJ]hI]hM]uh6j~hR]rhdXroutesrr}r(h5Uh6jubahEhubhdX:r}r(h5X:h6j~ubeubj)r}r(h5X] array( 'users' => new ImboUsers(); // or 'users' => function() { return new ImboUsers(); }, // or 'users' => 'ImboUsers', ), 'routes' => array( 'users' => '#^/users(\.(?json|xml))?$#', ), // ... );h6jSh;h>hEjhG}r(jjXphpjjhI]hJ]hK]hL]hM]uhPM hQhhR]rhdX] array( 'users' => new ImboUsers(); // or 'users' => function() { return new ImboUsers(); }, // or 'users' => 'ImboUsers', ), 'routes' => array( 'users' => '#^/users(\.(?json|xml))?$#', ), // ... );rr}r(h5Uh6jubaubhh)r}r(h5XIn the above example we are creating a route for Imbo using a regular expression, called ``users``. The route itself will match the following three requests:rh6jSh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPM'hQhhR]r(hdXYIn the above example we are creating a route for Imbo using a regular expression, called rr}r(h5XYIn the above example we are creating a route for Imbo using a regular expression, called h6jubh)r}r(h5X ``users``hG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdXusersrr}r(h5Uh6jubahEhubhdX;. The route itself will match the following three requests:rr}r(h5X;. The route itself will match the following three requests:h6jubeubh)r}r(h5Uh6jSh;h>hEhhG}r(jX*hI]hJ]hK]hL]hM]uhPM)hQhhR]r(h)r}r(h5X ``/users``rh6jh;h>hEhhG}r(hK]hL]hJ]hI]hM]uhPNhQhhR]rhh)r}r(h5jh6jh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPM)hR]rh)r}r(h5jhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdX/usersrr}r(h5Uh6jubahEhubaubaubh)r}r(h5X``/users.json``rh6jh;h>hEhhG}r(hK]hL]hJ]hI]hM]uhPNhQhhR]rhh)r}r(h5jh6jh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPM*hR]rh)r}r(h5jhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdX /users.jsonrr}r(h5Uh6jubahEhubaubaubh)r}r(h5X``/users.xml`` h6jh;h>hEhhG}r(hK]hL]hJ]hI]hM]uhPNhQhhR]rhh)r}r(h5X``/users.xml``rh6jh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPM+hR]rh)r}r(h5jhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdX /users.xmlrr}r(h5Uh6jubahEhubaubaubeubhh)r}r(h5XWhen a request is made against any of these endpoints Imbo will try to access a resource that is specified with the same key (``users``). The value specified for this entry in the ``resources`` array can be:rh6jSh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPM-hQhhR]r(hdX~When a request is made against any of these endpoints Imbo will try to access a resource that is specified with the same key (rr}r(h5X~When a request is made against any of these endpoints Imbo will try to access a resource that is specified with the same key (h6jubh)r}r(h5X ``users``hG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdXusersrr}r(h5Uh6jubahEhubhdX-). The value specified for this entry in the rr}r(h5X-). The value specified for this entry in the h6jubh)r}r(h5X ``resources``hG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdX resourcesrr}r(h5Uh6jubahEhubhdX array can be:rr}r(h5X array can be:h6jubeubj2)r}r(h5Uh6jSh;h>hEj5hG}r(j7U)hI]hJ]hK]j8UhL]hM]j9j:uhPM/hQhhR]r(h)r}r(h5X4a string representing the name of the resource classrh6jh;h>hEhhG}r (hK]hL]hJ]hI]hM]uhPNhQhhR]r hh)r }r (h5jh6jh;h>hEhlhG}r (hK]hL]hJ]hI]hM]uhPM/hR]rhdX4a string representing the name of the resource classrr}r(h5jh6j ubaubaubh)r}r(h5Xan instance of a resource classrh6jh;h>hEhhG}r(hK]hL]hJ]hI]hM]uhPNhQhhR]rhh)r}r(h5jh6jh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPM0hR]rhdXan instance of a resource classrr}r(h5jh6jubaubaubh)r}r(h5XSan anonymous function that, when executed, returns an instance of a resource class h6jh;h>hEhhG}r (hK]hL]hJ]hI]hM]uhPNhQhhR]r!hh)r"}r#(h5XRan anonymous function that, when executed, returns an instance of a resource classr$h6jh;h>hEhlhG}r%(hK]hL]hJ]hI]hM]uhPM1hR]r&hdXRan anonymous function that, when executed, returns an instance of a resource classr'r(}r)(h5j$h6j"ubaubaubeubhh)r*}r+(h5XxThe resource class must implement the ``Imbo\Resource\ResourceInterface`` interface to be able to response to a request.r,h6jSh;h>hEhlhG}r-(hK]hL]hJ]hI]hM]uhPM3hQhhR]r.(hdX&The resource class must implement the r/r0}r1(h5X&The resource class must implement the h6j*ubh)r2}r3(h5X#``Imbo\Resource\ResourceInterface``hG}r4(hK]hL]hJ]hI]hM]uh6j*hR]r5hdXImbo\Resource\ResourceInterfacer6r7}r8(h5Uh6j2ubahEhubhdX/ interface to be able to response to a request.r9r:}r;(h5X/ interface to be able to response to a request.h6j*ubeubhh)r<}r=(h5XaBelow is an example implementation of the ``ImboUsers`` resource used in the above configuration:r>h6jSh;h>hEhlhG}r?(hK]hL]hJ]hI]hM]uhPM5hQhhR]r@(hdX*Below is an example implementation of the rArB}rC(h5X*Below is an example implementation of the h6j<ubh)rD}rE(h5X ``ImboUsers``hG}rF(hK]hL]hJ]hI]hM]uh6j<hR]rGhdX ImboUsersrHrI}rJ(h5Uh6jDubahEhubhdX* resource used in the above configuration:rKrL}rM(h5X* resource used in the above configuration:h6j<ubeubj)rN}rO(h5XD 'get', ); } public function get(EventInterface $event) { $model = new ListModel(); $model->setList('users', 'user', array_keys($event->getConfig()['auth'])); $event->getResponse()->setModel($model); } }h6jSh;h>hEjhG}rP(jjXphpjjhI]hJ]hK]hL]hM]uhPM7hQhhR]rQhdXD 'get', ); } public function get(EventInterface $event) { $model = new ListModel(); $model->setList('users', 'user', array_keys($event->getConfig()['auth'])); $event->getResponse()->setModel($model); } }rRrS}rT(h5Uh6jNubaubhh)rU}rV(h5XThis resource informs Imbo that it supports ``HTTP GET``, and specifies a callback for the ``users.get`` event. The name of the event is the name specified for the resource in the configuration above, along with the HTTP method, separated with a dot.rWh6jSh;h>hEhlhG}rX(hK]hL]hJ]hI]hM]uhPMPhQhhR]rY(hdX,This resource informs Imbo that it supports rZr[}r\(h5X,This resource informs Imbo that it supports h6jUubh)r]}r^(h5X ``HTTP GET``hG}r_(hK]hL]hJ]hI]hM]uh6jUhR]r`hdXHTTP GETrarb}rc(h5Uh6j]ubahEhubhdX#, and specifies a callback for the rdre}rf(h5X#, and specifies a callback for the h6jUubh)rg}rh(h5X ``users.get``hG}ri(hK]hL]hJ]hI]hM]uh6jUhR]rjhdX users.getrkrl}rm(h5Uh6jgubahEhubhdX event. The name of the event is the name specified for the resource in the configuration above, along with the HTTP method, separated with a dot.rnro}rp(h5X event. The name of the event is the name specified for the resource in the configuration above, along with the HTTP method, separated with a dot.h6jUubeubhh)rq}rr(h5XIn the ``get()`` method we are simply creating a list model for Imbo's response formatter, and we are supplying the keys from the ``auth`` part of your configuration file as data. When formatted as JSON the response looks like this:rsh6jSh;h>hEhlhG}rt(hK]hL]hJ]hI]hM]uhPMRhQhhR]ru(hdXIn the rvrw}rx(h5XIn the h6jqubh)ry}rz(h5X ``get()``hG}r{(hK]hL]hJ]hI]hM]uh6jqhR]r|hdXget()r}r~}r(h5Uh6jyubahEhubhdXr method we are simply creating a list model for Imbo's response formatter, and we are supplying the keys from the rr}r(h5Xr method we are simply creating a list model for Imbo's response formatter, and we are supplying the keys from the h6jqubh)r}r(h5X``auth``hG}r(hK]hL]hJ]hI]hM]uh6jqhR]rhdXauthrr}r(h5Uh6jubahEhubhdX^ part of your configuration file as data. When formatted as JSON the response looks like this:rr}r(h5X^ part of your configuration file as data. When formatted as JSON the response looks like this:h6jqubeubj)r}r(h5X8{ "users": [ "someuser", "someotheruser" ] }h6jSh;h>hEjhG}r(jjXjsonjjhI]hJ]hK]hL]hM]uhPMThQhhR]rhdX8{ "users": [ "someuser", "someotheruser" ] }rr}r(h5Uh6jubaubhh)r}r(h5X+and the XML representation looks like this:rh6jSh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPM]hQhhR]rhdX+and the XML representation looks like this:rr}r(h5jh6jubaubj)r}r(h5X someuser someotheruser h6jSh;h>hEjhG}r(jjXxmljjhI]hJ]hK]hL]hM]uhPM_hQhhR]rhdX someuser someotheruser rr}r(h5Uh6jubaubhh)r}r(h5XFeel free to experiment with this feature. If you end up creating a resource that you think should be a part of Imbo, send a `pull request on GitHub `_.rh6jSh;h>hEhlhG}r(hK]hL]hJ]hI]hM]uhPMihQhhR]r(hdX}Feel free to experiment with this feature. If you end up creating a resource that you think should be a part of Imbo, send a rr}r(h5X}Feel free to experiment with this feature. If you end up creating a resource that you think should be a part of Imbo, send a h6jubh)r}r(h5X8`pull request on GitHub `_hG}r(UnameXpull request on GitHubjXhttps://github.com/imbo/imborhI]hJ]hK]hL]hM]uh6jhR]rhdXpull request on GitHubrr}r(h5Uh6jubahEhubhB)r}r(h5X h:Kh6jhEhFhG}r(UrefurijhI]rUpull-request-on-githubrahJ]hK]hL]hM]rhauhR]ubhdX.r}r(h5X.h6jubeubeubeubh;h>hEUsystem_messagerhG}r(hK]UlevelKhI]hJ]rhXaUsourceh>hL]hM]UlineKUtypeUINFOruhPKhQhhR]rhh)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6h3hR]rhdX0Duplicate implicit target name: "configuration".rr}r(h5Uh6jubahEhlubaubh2)r}r(h5Uh6jh;h>hEjhG}r(hK]UlevelKhI]hJ]Usourceh>hL]hM]UlineKUtypejuhPKuhQhhR]rhh)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdX:Enumerated list start value not ordinal-1: "2" (ordinal 2)rr}r(h5Uh6jubahEhlubaubh2)r}r(h5Uh6jh;h>hEjhG}r(hK]UlevelKhI]hJ]rjaUsourceh>hL]hM]UlineKUtypejuhPKhQhhR]rhh)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdX*Duplicate implicit target name: "mongodb".rr}r(h5Uh6jubahEhlubaubh2)r}r(h5Uh6jFh;h>hEjhG}r(hK]UlevelKhI]hJ]rjKaUsourceh>hL]hM]UlineKUtypejuhPKhQhhR]rhh)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdX+Duplicate implicit target name: "examples".rr}r(h5Uh6jubahEhlubaubh2)r}r(h5Uh6jFh;h>hEjhG}r(hK]UlevelKhI]hJ]Usourceh>hL]hM]UlineKUtypejuhPKhQhhR]rhh)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdX:Enumerated list start value not ordinal-1: "2" (ordinal 2)rr}r(h5Uh6jubahEhlubaubh2)r}r(h5Uh6j1h;h>hEjhG}r(hK]UlevelKhI]hJ]rj7aUsourceh>hL]hM]UlineMUtypejuhPMhQhhR]rhh)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdX+Duplicate implicit target name: "examples".rr}r(h5Uh6jubahEhlubaubh2)r}r(h5Uh6jHh;h>hEjhG}r(hK]UlevelKhI]hJ]rjZaUsourceh>hL]hM]UlineM"UtypejuhPM"hQhhR]rhh)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6jhR]r hdX+Duplicate implicit target name: "doctrine".r r }r (h5Uh6jubahEhlubaubh2)r }r(h5Uh6jHh;h>hEjhG}r(hK]UlevelKhI]hJ]rjiaUsourceh>hL]hM]UlineKUtypejuhPM%hQhhR]rhh)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6j hR]rhdXFDuplicate explicit target name: "doctrine database abstraction layer".rr}r(h5Uh6jubahEhlubaubh2)r}r(h5Uh6jHh;h>hEjhG}r(hK]UlevelKhI]hJ]rj|aUsourceh>hL]hM]UlineKUtypejuhPM%hQhhR]rhh)r}r(h5UhG}r (hK]hL]hJ]hI]hM]uh6jhR]r!hdX7Duplicate explicit target name: "doctrine-project.org".r"r#}r$(h5Uh6jubahEhlubaubh2)r%}r&(h5Uh6jh;h>hEjhG}r'(hK]UlevelKhI]hJ]r(jaUsourceh>hL]hM]UlineM'UtypejuhPM'hQhhR]r)hh)r*}r+(h5UhG}r,(hK]hL]hJ]hI]hM]uh6j%hR]r-hdX+Duplicate implicit target name: "examples".r.r/}r0(h5Uh6j*ubahEhlubaubh2)r1}r2(h5Uh6jh;h>hEjhG}r3(hK]UlevelKhI]hJ]Usourceh>hL]hM]UlineKUtypejuhPM<hQhhR]r4hh)r5}r6(h5UhG}r7(hK]hL]hJ]hI]hM]uh6j1hR]r8hdX:Enumerated list start value not ordinal-1: "2" (ordinal 2)r9r:}r;(h5Uh6j5ubahEhlubaubh2)r<}r=(h5Uh6j&h;h>hEjhG}r>(hK]UlevelKhI]hJ]r?j,aUsourceh>hL]hM]UlineM^UtypejuhPM^hQhhR]r@hh)rA}rB(h5UhG}rC(hK]hL]hJ]hI]hM]uh6j<hR]rDhdX+Duplicate implicit target name: "examples".rErF}rG(h5Uh6jAubahEhlubaubh2)rH}rI(h5UhG}rJ(hK]UlevelKhI]hJ]rKjaUsourceh>hL]hM]UlineKUtypejuh6jhR]rLhh)rM}rN(h5UhG}rO(hK]hL]hJ]hI]hM]uh6jHhR]rPhdXIDuplicate explicit target name: "manual for the mongoclient constructor".rQrR}rS(h5Uh6jMubahEhlubahEjubh2)rT}rU(h5Uh6jh;h>hEjhG}rV(hK]UlevelKhI]hJ]rWjaUsourceh>hL]hM]UlineMUtypejuhPMhQhhR]rXhh)rY}rZ(h5UhG}r[(hK]hL]hJ]hI]hM]uh6jThR]r\hdX+Duplicate implicit target name: "examples".r]r^}r_(h5Uh6jYubahEhlubaubh2)r`}ra(h5Uh6jh;h>hEjhG}rb(hK]UlevelKhI]hJ]Usourceh>hL]hM]UlineKUtypejuhPMhQhhR]rchh)rd}re(h5UhG}rf(hK]hL]hJ]hI]hM]uh6j`hR]rghdX:Enumerated list start value not ordinal-1: "2" (ordinal 2)rhri}rj(h5Uh6jdubahEhlubaubh2)rk}rl(h5Uh6jh;h>hEjhG}rm(hK]UlevelKhI]hJ]Usourceh>hL]hM]UlineKUtypejuhPMhQhhR]rnhh)ro}rp(h5UhG}rq(hK]hL]hJ]hI]hM]uh6jkhR]rrhdX:Enumerated list start value not ordinal-1: "2" (ordinal 2)rsrt}ru(h5Uh6joubahEhlubaubh2)rv}rw(h5Uh6jh;h>hEjhG}rx(hK]UlevelKhI]hJ]Usourceh>hL]hM]UlineKUtypejuhPMhQhhR]ryhh)rz}r{(h5UhG}r|(hK]hL]hJ]hI]hM]uh6jvhR]r}hdX:Enumerated list start value not ordinal-1: "3" (ordinal 3)r~r}r(h5Uh6jzubahEhlubaubh2)r}r(h5Uh6jh;h>hEjhG}r(hK]UlevelKhI]hJ]Usourceh>hL]hM]UlineKUtypejuhPMhQhhR]rhh)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdX:Enumerated list start value not ordinal-1: "4" (ordinal 4)rr}r(h5Uh6jubahEhlubaubh2)r}r(h5Uh6jh;h>hEjhG}r(hK]UlevelKhI]hJ]Usourceh>hL]hM]UlineKUtypejuhPM/hQhhR]rhh)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdX:Enumerated list start value not ordinal-1: "5" (ordinal 5)rr}r(h5Uh6jubahEhlubaubeUcurrent_sourcerNU decorationrNUautofootnote_startrKUnameidsr}r(hjhj]hjh j h jh jh Nh Nhhhj hhhj hjGhjhjXhjhjhjhjzhjhjhj&hjhhhj\hhh jAh!jh"jh#j! h$jh%hOh&jh'j2h(jh)jh*jSh+jmh,jAh-juhR]r(hCh8eh5UU transformerrNU footnote_refsr}rUrefnamesr}rUsymbol_footnotesr]rUautofootnote_refsr]rUsymbol_footnote_refsr]rU citationsr]rhQhU current_linerNUtransform_messagesr]r(h2)r}r(h5UhG}r(hK]UlevelKhI]hJ]Usourceh>hL]hM]UlineKUtypejuhR]rhh)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdX3Hyperlink target "configuration" is not referenced.rr}r(h5Uh6jubahEhlubahEjubh2)r}r(h5UhG}r(hK]UlevelKhI]hJ]Usourceh>hL]hM]UlineK4UtypejuhR]rhh)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdX<Hyperlink target "database-configuration" is not referenced.rr}r(h5Uh6jubahEhlubahEjubh2)r}r(h5UhG}r(hK]UlevelKhI]hJ]Usourceh>hL]hM]UlineKXUtypejuhR]rhh)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdX?Hyperlink target "doctrine-database-adapter" is not referenced.rr}r(h5Uh6jubahEhlubahEjubh2)r}r(h5UhG}r(hK]UlevelKhI]hJ]Usourceh>hL]hM]UlineKUtypejuhR]rhh)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdX>Hyperlink target "mongodb-database-adapter" is not referenced.rr}r(h5Uh6jubahEhlubahEjubh2)r}r(h5UhG}r(hK]UlevelKhI]hJ]Usourceh>hL]hM]UlineKUtypejuhR]rhh)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdX>Hyperlink target "default-database-adapter" is not referenced.rr}r(h5Uh6jubahEhlubahEjubh2)r}r(h5UhG}r(hK]UlevelKhI]hJ]Usourceh>hL]hM]UlineKUtypejuhR]rhh)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdX;Hyperlink target "storage-configuration" is not referenced.rr}r(h5Uh6jubahEhlubahEjubh2)r}r(h5UhG}r(hK]UlevelKhI]hJ]Usourceh>hL]hM]UlineKUtypejuhR]rhh)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdX8Hyperlink target "s3-storage-adapter" is not referenced.rr}r(h5Uh6jubahEhlubahEjubh2)r}r(h5UhG}r(hK]UlevelKhI]hJ]Usourceh>hL]hM]UlineMQUtypejuhR]rhh)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdX@Hyperlink target "filesystem-storage-adapter" is not referenced.rr}r(h5Uh6jubahEhlubahEjubh2)r}r(h5UhG}r(hK]UlevelKhI]hJ]Usourceh>hL]hM]UlineMqUtypejuhR]rhh)r }r (h5UhG}r (hK]hL]hJ]hI]hM]uh6jhR]r hdX<Hyperlink target "gridfs-storage-adapter" is not referenced.r r}r(h5Uh6j ubahEhlubahEjubh2)r}r(h5UhG}r(hK]UlevelKhI]hJ]Usourceh>hL]hM]UlineMrUtypejuhR]rhh)r}r(h5UhG}r(hK]hL]hJ]hI]hM]uh6jhR]rhdX=Hyperlink target "default-storage-adapter" is not referenced.rr}r(h5Uh6jubahEhlubahEjubh2)r}r(h5UhG}r(hK]UlevelKhI]hJ]Usourceh>hL]hM]UlineMUtypejuhR]rhh)r}r (h5UhG}r!(hK]hL]hJ]hI]hM]uh6jhR]r"hdXCHyperlink target "configuration-event-listeners" is not referenced.r#r$}r%(h5Uh6jubahEhlubahEjubh2)r&}r'(h5UhG}r((hK]UlevelKhI]hJ]Usourceh>hL]hM]UlineMUtypejuhR]r)hh)r*}r+(h5UhG}r,(hK]hL]hJ]hI]hM]uh6j&hR]r-hdXBHyperlink target "image-transformations-config" is not referenced.r.r/}r0(h5Uh6j*ubahEhlubahEjubh2)r1}r2(h5UhG}r3(hK]UlevelKhI]hJ]Usourceh>hL]hM]UlineMUtypejuhR]r4hh)r5}r6(h5UhG}r7(hK]hL]hJ]hI]hM]uh6j1hR]r8hdXOHyperlink target "configuration-event-listener-initializers" is not referenced.r9r:}r;(h5Uh6j5ubahEhlubahEjubeUreporterr<NUid_startr=KU autofootnotesr>]r?U citation_refsr@}rAUindirect_targetsrB]rCUsettingsrD(cdocutils.frontend Values rEorF}rG(Ufootnote_backlinksrHKUrecord_dependenciesrINU rfc_base_urlrJUhttp://tools.ietf.org/html/rKU tracebackrLUpep_referencesrMNUstrip_commentsrNNU toc_backlinksrOUentryrPU language_coderQUenrRU datestamprSNU report_levelrTKU _destinationrUNU halt_levelrVKU strip_classesrWNhaNUerror_encoding_error_handlerrXUbackslashreplacerYUdebugrZNUembed_stylesheetr[Uoutput_encoding_error_handlerr\Ustrictr]U sectnum_xformr^KUdump_transformsr_NU docinfo_xformr`KUwarning_streamraNUpep_file_url_templaterbUpep-%04drcUexit_status_levelrdKUconfigreNUstrict_visitorrfNUcloak_email_addressesrgUtrim_footnote_reference_spacerhUenvriNUdump_pseudo_xmlrjNUexpose_internalsrkNUsectsubtitle_xformrlU source_linkrmNUrfc_referencesrnNUoutput_encodingroUutf-8rpU source_urlrqNUinput_encodingrrU utf-8-sigrsU_disable_configrtNU id_prefixruUU tab_widthrvKUerror_encodingrwUUTF-8rxU_sourceryUO/var/build/user_builds/imbo/checkouts/1.1.1/docs/installation/configuration.rstrzUgettext_compactr{U generatorr|NUdump_internalsr}NU smart_quotesr~U pep_base_urlrUhttp://www.python.org/dev/peps/rUsyntax_highlightrUlongrUinput_encoding_error_handlerrj]Uauto_id_prefixrUidrUdoctitle_xformrUstrip_elements_with_classesrNU _config_filesr]Ufile_insertion_enabledrU raw_enabledrKU dump_settingsrNubUsymbol_footnote_startrKUidsr}r(j j jjj&j# jGjj]j_jjjjj jjjj\jSjj hhj j# j jhjjijej|jxj7j1jZjHjKjFj4j/jjjjhXh8jjj,j&jjjjhhjjhhjj_j%j!jjNjzjjjhhjjhjvjjjjj jjjjjjjj! j# jljhhOh8hj3j2j3jAj=j[jWjjjjj@j<jjjSjOjjjj~jmjjAj jXj_jjjjjYjUjFjBjj{jjuUsubstitution_namesr}rhEhQhG}r(hK]hI]hJ]Usourceh>hL]hM]uU footnotesr]rUrefidsr}r(j2]rj/aj ]rj ajX]rjUaj]rjaj]rjaj]rjaj]rj{aj]rjaj! ]rj ajz]rjwahO]rhCaj]]rjYaj]rjauub.PKrNDرSS1imbo-1.1.1/.doctrees/develop/contributing.doctreecdocutils.nodes document q)q}q(U nametypesq}q(X mit licenseqXtestsqNX documentationqNX requirementsq NX phpdocumentorq Xcontributing to imboq NXrakeq Xpearq X contributingqXphp code snifferqXphpunitqXcoding standardqNXbehatqX issue trackerqXsphinxqXavailable on githubqX build scriptqNuUsubstitution_defsq}qUparse_messagesq]qUcurrent_sourceqNU decorationqNUautofootnote_startqKUnameidsq}q(hU mit-licenseq hUtestsq!hU documentationq"h U requirementsq#h U phpdocumentorq$h Ucontributing-to-imboq%h Urakeq&h Upearq'hU contributingq(hUphp-code-snifferq)hUphpunitq*hUcoding-standardq+hUbehatq,hU issue-trackerq-hUsphinxq.hUavailable-on-githubq/hU build-scriptq0uUchildrenq1]q2(cdocutils.nodes target q3)q4}q5(U rawsourceq6X.. _contributing:Uparentq7hUsourceq8cdocutils.nodes reprunicode q9XI/var/build/user_builds/imbo/checkouts/1.1.1/docs/develop/contributing.rstq:q;}qU attributesq?}q@(UidsqA]UbackrefsqB]UdupnamesqC]UclassesqD]UnamesqE]UrefidqFh(uUlineqGKUdocumentqHhh1]ubcdocutils.nodes section qI)qJ}qK(h6Uh7hh8h;Uexpect_referenced_by_nameqL}qMhh4sh=UsectionqNh?}qO(hC]hD]hB]hA]qP(h%h(ehE]qQ(h heuhGKhHhUexpect_referenced_by_idqR}qSh(h4sh1]qT(cdocutils.nodes title qU)qV}qW(h6XContributing to ImboqXh7hJh8h;h=UtitleqYh?}qZ(hC]hD]hB]hA]hE]uhGKhHhh1]q[cdocutils.nodes Text q\XContributing to Imboq]q^}q_(h6hXh7hVubaubcdocutils.nodes paragraph q`)qa}qb(h6X.Imbo is an open source project licensed with the `MIT license `_. All contributions should ideally be sent in form of a pull request on GitHub. Please use features branches with descriptive names, and remember to send the pull request against the ``develop`` branch.qch7hJh8h;h=U paragraphqdh?}qe(hC]hD]hB]hA]hE]uhGKhHhh1]qf(h\X1Imbo is an open source project licensed with the qgqh}qi(h6X1Imbo is an open source project licensed with the h7haubcdocutils.nodes reference qj)qk}ql(h6X3`MIT license `_h?}qm(UnameX MIT licenseUrefuriqnX"http://opensource.org/licenses/MITqohA]hB]hC]hD]hE]uh7hah1]qph\X MIT licenseqqqr}qs(h6Uh7hkubah=U referenceqtubh3)qu}qv(h6X% U referencedqwKh7hah=h>h?}qx(UrefurihohA]qyh ahB]hC]hD]hE]qzhauh1]ubh\X. All contributions should ideally be sent in form of a pull request on GitHub. Please use features branches with descriptive names, and remember to send the pull request against the q{q|}q}(h6X. All contributions should ideally be sent in form of a pull request on GitHub. Please use features branches with descriptive names, and remember to send the pull request against the h7haubcdocutils.nodes literal q~)q}q(h6X ``develop``h?}q(hC]hD]hB]hA]hE]uh7hah1]qh\Xdevelopqq}q(h6Uh7hubah=Uliteralqubh\X branch.qq}q(h6X branch.h7haubeubh`)q}q(h6XuIf you have found a bug in Imbo, please leave an issue in the `issue tracker `_.qh7hJh8h;h=hdh?}q(hC]hD]hB]hA]hE]uhGKhHhh1]q(h\X>If you have found a bug in Imbo, please leave an issue in the qq}q(h6X>If you have found a bug in Imbo, please leave an issue in the h7hubhj)q}q(h6X6`issue tracker `_h?}q(UnameX issue trackerhnX#https://github.com/imbo/imbo/issuesqhA]hB]hC]hD]hE]uh7hh1]qh\X issue trackerqq}q(h6Uh7hubah=htubh3)q}q(h6X& hwKh7hh=h>h?}q(UrefurihhA]qh-ahB]hC]hD]hE]qhauh1]ubh\X.q}q(h6X.h7hubeubhI)q}q(h6Uh7hJh8h;h=hNh?}q(hC]hD]hB]hA]qh0ahE]qhauhGK hHhh1]q(hU)q}q(h6X Build scriptqh7hh8h;h=hYh?}q(hC]hD]hB]hA]hE]uhGK hHhh1]qh\X Build scriptqq}q(h6hh7hubaubh`)q}q(h6XImbo uses `Rake `_ for building, and if you have Rake installed you can simply run the ``rake`` command after cloning Imbo to run the complete build. You might need to install some additional tools for the whole build to complete successfully. If you need help getting the build script to work with no errors drop by the ``#imbo`` channel on IRC (Freenode) or simply add an issue in the issue tracker on GitHub.qh7hh8h;h=hdh?}q(hC]hD]hB]hA]hE]uhGK hHhh1]q(h\X Imbo uses qq}q(h6X Imbo uses h7hubhj)q}q(h6X$`Rake `_h?}q(UnameXRakehnXhttp://rake.rubyforge.org/qhA]hB]hC]hD]hE]uh7hh1]qh\XRakeqq}q(h6Uh7hubah=htubh3)q}q(h6X hwKh7hh=h>h?}q(UrefurihhA]qh&ahB]hC]hD]hE]qh auh1]ubh\XE for building, and if you have Rake installed you can simply run the qąq}q(h6XE for building, and if you have Rake installed you can simply run the h7hubh~)q}q(h6X``rake``h?}q(hC]hD]hB]hA]hE]uh7hh1]qh\Xrakeq˅q}q(h6Uh7hubah=hubh\X command after cloning Imbo to run the complete build. You might need to install some additional tools for the whole build to complete successfully. If you need help getting the build script to work with no errors drop by the q΅q}q(h6X command after cloning Imbo to run the complete build. You might need to install some additional tools for the whole build to complete successfully. If you need help getting the build script to work with no errors drop by the h7hubh~)q}q(h6X ``#imbo``h?}q(hC]hD]hB]hA]hE]uh7hh1]qh\X#imboqՅq}q(h6Uh7hubah=hubh\XQ channel on IRC (Freenode) or simply add an issue in the issue tracker on GitHub.q؅q}q(h6XQ channel on IRC (Freenode) or simply add an issue in the issue tracker on GitHub.h7hubeubh`)q}q(h6XRunning the complete suite is not necessary for all contributions. If you skip the build script and simply want to get Imbo up and running for contributing you can run the following commands in the directory where you cloned Imbo:qh7hh8h;h=hdh?}q(hC]hD]hB]hA]hE]uhGKhHhh1]qh\XRunning the complete suite is not necessary for all contributions. If you skip the build script and simply want to get Imbo up and running for contributing you can run the following commands in the directory where you cloned Imbo:qq}q(h6hh7hubaubcdocutils.nodes literal_block q)q}q(h6XIcurl -s https://getcomposer.org/installer | php php composer.phar installh7hh8h;h=U literal_blockqh?}q(UlinenosqUlanguageqXconsoleU xml:spaceqUpreserveqhA]hB]hC]hD]hE]uhGKhHhh1]qh\XIcurl -s https://getcomposer.org/installer | php php composer.phar installq텁q}q(h6Uh7hubaubh`)q}q(h6XRemember to **not** include the ``--no-dev`` argument to composer. If you include that argument the development requirements will not be installed.qh7hh8h;h=hdh?}q(hC]hD]hB]hA]hE]uhGKhHhh1]q(h\X Remember to qq}q(h6X Remember to h7hubcdocutils.nodes strong q)q}q(h6X**not**h?}q(hC]hD]hB]hA]hE]uh7hh1]qh\Xnotqq}q(h6Uh7hubah=Ustrongrubh\X include the rr}r(h6X include the h7hubh~)r}r(h6X ``--no-dev``h?}r(hC]hD]hB]hA]hE]uh7hh1]rh\X--no-devrr }r (h6Uh7jubah=hubh\Xg argument to composer. If you include that argument the development requirements will not be installed.r r }r (h6Xg argument to composer. If you include that argument the development requirements will not be installed.h7hubeubeubhI)r}r(h6Uh7hJh8h;h=hNh?}r(hC]hD]hB]hA]rh#ahE]rh auhGKhHhh1]r(hU)r}r(h6X Requirementsrh7jh8h;h=hYh?}r(hC]hD]hB]hA]hE]uhGKhHhh1]rh\X Requirementsrr}r(h6jh7jubaubh`)r}r(h6XmWhen contributing to Imbo (or any of the other related packages) there are some guidelines you should follow.rh7jh8h;h=hdh?}r(hC]hD]hB]hA]hE]uhGKhHhh1]r h\XmWhen contributing to Imbo (or any of the other related packages) there are some guidelines you should follow.r!r"}r#(h6jh7jubaubhI)r$}r%(h6Uh7jh8h;h=hNh?}r&(hC]hD]hB]hA]r'h+ahE]r(hauhGKhHhh1]r)(hU)r*}r+(h6XCoding standardr,h7j$h8h;h=hYh?}r-(hC]hD]hB]hA]hE]uhGKhHhh1]r.h\XCoding standardr/r0}r1(h6j,h7j*ubaubh`)r2}r3(h6XImbo has a coding standard that is partially defined as a `PHP Code Sniffer `_ standard. The standard is `available on GitHub `_ and is installable via `PEAR `_. There are some details that might not be covered by the standard, so if you send a PR you might notice some nitpicking from my part regarding stuff not covered by the standard. Browse existing code to understand the general look and feel.r4h7j$h8h;h=hdh?}r5(hC]hD]hB]hA]hE]uhGK hHhh1]r6(h\X:Imbo has a coding standard that is partially defined as a r7r8}r9(h6X:Imbo has a coding standard that is partially defined as a h7j2ubhj)r:}r;(h6XA`PHP Code Sniffer `_h?}r<(UnameXPHP Code SnifferhnX+http://pear.php.net/package/PHP_CodeSnifferr=hA]hB]hC]hD]hE]uh7j2h1]r>h\XPHP Code Snifferr?r@}rA(h6Uh7j:ubah=htubh3)rB}rC(h6X. hwKh7j2h=h>h?}rD(Urefurij=hA]rEh)ahB]hC]hD]hE]rFhauh1]ubh\X standard. The standard is rGrH}rI(h6X standard. The standard is h7j2ubhj)rJ}rK(h6XA`available on GitHub `_h?}rL(UnameXavailable on GitHubhnX(https://github.com/imbo/imbo-codesnifferrMhA]hB]hC]hD]hE]uh7j2h1]rNh\Xavailable on GitHubrOrP}rQ(h6Uh7jJubah=htubh3)rR}rS(h6X+ hwKh7j2h=h>h?}rT(UrefurijMhA]rUh/ahB]hC]hD]hE]rVhauh1]ubh\X and is installable via rWrX}rY(h6X and is installable via h7j2ubhj)rZ}r[(h6X`PEAR `_h?}r\(UnameXPEARhnXhttp://pear.php.netr]hA]hB]hC]hD]hE]uh7j2h1]r^h\XPEARr_r`}ra(h6Uh7jZubah=htubh3)rb}rc(h6X hwKh7j2h=h>h?}rd(Urefurij]hA]reh'ahB]hC]hD]hE]rfh auh1]ubh\X. There are some details that might not be covered by the standard, so if you send a PR you might notice some nitpicking from my part regarding stuff not covered by the standard. Browse existing code to understand the general look and feel.rgrh}ri(h6X. There are some details that might not be covered by the standard, so if you send a PR you might notice some nitpicking from my part regarding stuff not covered by the standard. Browse existing code to understand the general look and feel.h7j2ubeubeubhI)rj}rk(h6Uh7jh8h;h=hNh?}rl(hC]hD]hB]hA]rmh!ahE]rnhauhGK#hHhh1]ro(hU)rp}rq(h6XTestsrrh7jjh8h;h=hYh?}rs(hC]hD]hB]hA]hE]uhGK#hHhh1]rth\XTestsrurv}rw(h6jrh7jpubaubh`)rx}ry(h6XFWhen introducing new features you are required to add tests. Unit/integration tests (`PHPUnit `_) and/or `Behat `_ scenarios is sufficient. To run the PHPUnit test suite you can execute the following command in the project root directory after installing Imbo:rzh7jjh8h;h=hdh?}r{(hC]hD]hB]hA]hE]uhGK%hHhh1]r|(h\XUWhen introducing new features you are required to add tests. Unit/integration tests (r}r~}r(h6XUWhen introducing new features you are required to add tests. Unit/integration tests (h7jxubhj)r}r(h6X:`PHPUnit `_h?}r(UnameXPHPUnithnX-https://github.com/sebastianbergmann/phpunit/rhA]hB]hC]hD]hE]uh7jxh1]rh\XPHPUnitrr}r(h6Uh7jubah=htubh3)r}r(h6X0 hwKh7jxh=h>h?}r(UrefurijhA]rh*ahB]hC]hD]hE]rhauh1]ubh\X ) and/or rr}r(h6X ) and/or h7jxubhj)r}r(h6X`Behat `_h?}r(UnameXBehathnXhttp://behat.org/rhA]hB]hC]hD]hE]uh7jxh1]rh\XBehatrr}r(h6Uh7jubah=htubh3)r}r(h6X hwKh7jxh=h>h?}r(UrefurijhA]rh,ahB]hC]hD]hE]rhauh1]ubh\X scenarios is sufficient. To run the PHPUnit test suite you can execute the following command in the project root directory after installing Imbo:rr}r(h6X scenarios is sufficient. To run the PHPUnit test suite you can execute the following command in the project root directory after installing Imbo:h7jxubeubh)r}r(h6X./vendor/bin/phpunit -c testsh7jjh8h;h=hh?}r(hhXconsolehhhA]hB]hC]hD]hE]uhGK'hHhh1]rh\X./vendor/bin/phpunit -c testsrr}r(h6Uh7jubaubh`)r}r(h6X^If you want to generate code coverage as well you can run the test suite by using a Rake task:rh7jjh8h;h=hdh?}r(hC]hD]hB]hA]hE]uhGK+hHhh1]rh\X^If you want to generate code coverage as well you can run the test suite by using a Rake task:rr}r(h6jh7jubaubh)r}r(h6X rake phpunith7jjh8h;h=hh?}r(hhXconsolehhhA]hB]hC]hD]hE]uhGK-hHhh1]rh\X rake phpunitrr}r(h6Uh7jubaubh`)r}r(h6X6For the Behat test suite you can run similar commands:rh7jjh8h;h=hdh?}r(hC]hD]hB]hA]hE]uhGK1hHhh1]rh\X6For the Behat test suite you can run similar commands:rr}r(h6jh7jubaubh)r}r(h6X#./vendor/bin/behat --profile travish7jjh8h;h=hh?}r(hhXconsolehhhA]hB]hC]hD]hE]uhGK3hHhh1]rh\X#./vendor/bin/behat --profile travisrr}r(h6Uh7jubaubh`)r}r(h6Xto skip code coverage, orrh7jjh8h;h=hdh?}r(hC]hD]hB]hA]hE]uhGK7hHhh1]rh\Xto skip code coverage, orrr}r(h6jh7jubaubh)r}r(h6X rake behath7jjh8h;h=hh?}r(hhXconsolehhhA]hB]hC]hD]hE]uhGK9hHhh1]rh\X rake behatrr}r(h6Uh7jubaubh`)r}r(h6Xofor code coverage of the Behat tests. If you want to run both suites and collect code coverage you can execute:rh7jjh8h;h=hdh?}r(hC]hD]hB]hA]hE]uhGK=hHhh1]rh\Xofor code coverage of the Behat tests. If you want to run both suites and collect code coverage you can execute:rr}r(h6jh7jubaubh)r}r(h6X rake testh7jjh8h;h=hh?}r(hhXconsolehhhA]hB]hC]hD]hE]uhGK?hHhh1]rh\X rake testrr}r(h6Uh7jubaubh`)r}r(h6XYCode coverage is located in ``build/coverage`` and ``build/behat-coverage`` respectively.rh7jjh8h;h=hdh?}r(hC]hD]hB]hA]hE]uhGKChHhh1]r(h\XCode coverage is located in rr}r(h6XCode coverage is located in h7jubh~)r}r(h6X``build/coverage``h?}r(hC]hD]hB]hA]hE]uh7jh1]rh\Xbuild/coveragerr}r(h6Uh7jubah=hubh\X and rr}r(h6X and h7jubh~)r}r(h6X``build/behat-coverage``h?}r(hC]hD]hB]hA]hE]uh7jh1]rh\Xbuild/behat-coveragerr}r(h6Uh7jubah=hubh\X respectively.rr}r(h6X respectively.h7jubeubh`)r}r(h6XIf you find a bug that you want to fix please add a test first that confirms the bug, and then fix the bug, making the newly added test pass.rh7jjh8h;h=hdh?}r(hC]hD]hB]hA]hE]uhGKEhHhh1]rh\XIf you find a bug that you want to fix please add a test first that confirms the bug, and then fix the bug, making the newly added test pass.rr}r(h6jh7jubaubeubhI)r}r(h6Uh7jh8h;h=hNh?}r (hC]hD]hB]hA]r h"ahE]r hauhGKHhHhh1]r (hU)r }r(h6X Documentationrh7jh8h;h=hYh?}r(hC]hD]hB]hA]hE]uhGKHhHhh1]rh\X Documentationrr}r(h6jh7j ubaubh`)r}r(h6XsAPI documentation is written using `phpDocumentor `_, and can be generated via a Rake task:rh7jh8h;h=hdh?}r(hC]hD]hB]hA]hE]uhGKJhHhh1]r(h\X#API documentation is written using rr}r(h6X#API documentation is written using h7jubhj)r}r(h6X)`phpDocumentor `_h?}r(UnameX phpDocumentorhnXhttp://www.phpdoc.org/r hA]hB]hC]hD]hE]uh7jh1]r!h\X phpDocumentorr"r#}r$(h6Uh7jubah=htubh3)r%}r&(h6X hwKh7jh=h>h?}r'(Urefurij hA]r(h$ahB]hC]hD]hE]r)h auh1]ubh\X', and can be generated via a Rake task:r*r+}r,(h6X', and can be generated via a Rake task:h7jubeubh)r-}r.(h6X rake apidocsh7jh8h;h=hh?}r/(hhXconsolehhhA]hB]hC]hD]hE]uhGKLhHhh1]r0h\X rake apidocsr1r2}r3(h6Uh7j-ubaubh`)r4}r5(h6XEnd user documentation (the ones you are reading now) is written using `Sphinx `_ and is located in the ``docs/`` directory in the project root. To generate the HTML version of the docs you can execute the following command:r6h7jh8h;h=hdh?}r7(hC]hD]hB]hA]hE]uhGKPhHhh1]r8(h\XGEnd user documentation (the ones you are reading now) is written using r9r:}r;(h6XGEnd user documentation (the ones you are reading now) is written using h7j4ubhj)r<}r=(h6X"`Sphinx `_h?}r>(UnameXSphinxhnXhttp://sphinx-doc.org/r?hA]hB]hC]hD]hE]uh7j4h1]r@h\XSphinxrArB}rC(h6Uh7j<ubah=htubh3)rD}rE(h6X hwKh7j4h=h>h?}rF(Urefurij?hA]rGh.ahB]hC]hD]hE]rHhauh1]ubh\X and is located in the rIrJ}rK(h6X and is located in the h7j4ubh~)rL}rM(h6X ``docs/``h?}rN(hC]hD]hB]hA]hE]uh7j4h1]rOh\Xdocs/rPrQ}rR(h6Uh7jLubah=hubh\Xo directory in the project root. To generate the HTML version of the docs you can execute the following command:rSrT}rU(h6Xo directory in the project root. To generate the HTML version of the docs you can execute the following command:h7j4ubeubh)rV}rW(h6Xrake readthedocsh7jh8h;h=hh?}rX(hhXconsolehhhA]hB]hC]hD]hE]uhGKRhHhh1]rYh\Xrake readthedocsrZr[}r\(h6Uh7jVubaubh`)r]}r^(h6X/This task also includes a spell checking stage.r_h7jh8h;h=hdh?}r`(hC]hD]hB]hA]hE]uhGKVhHhh1]rah\X/This task also includes a spell checking stage.rbrc}rd(h6j_h7j]ubaubeubeubeubeh6UU transformerreNU footnote_refsrf}rgUrefnamesrh}riUsymbol_footnotesrj]rkUautofootnote_refsrl]rmUsymbol_footnote_refsrn]roU citationsrp]rqhHhU current_linerrNUtransform_messagesrs]rtcdocutils.nodes system_message ru)rv}rw(h6Uh?}rx(hC]UlevelKhA]hB]Usourceh;hD]hE]UlineKUtypeUINFOryuh1]rzh`)r{}r|(h6Uh?}r}(hC]hD]hB]hA]hE]uh7jvh1]r~h\X2Hyperlink target "contributing" is not referenced.rr}r(h6Uh7j{ubah=hdubah=Usystem_messagerubaUreporterrNUid_startrKU autofootnotesr]rU citation_refsr}rUindirect_targetsr]rUsettingsr(cdocutils.frontend Values ror}r(Ufootnote_backlinksrKUrecord_dependenciesrNU rfc_base_urlrUhttp://tools.ietf.org/html/rU tracebackrUpep_referencesrNUstrip_commentsrNU toc_backlinksrUentryrU language_coderUenrU datestamprNU report_levelrKU _destinationrNU halt_levelrKU strip_classesrNhYNUerror_encoding_error_handlerrUbackslashreplacerUdebugrNUembed_stylesheetrUoutput_encoding_error_handlerrUstrictrU sectnum_xformrKUdump_transformsrNU docinfo_xformrKUwarning_streamrNUpep_file_url_templaterUpep-%04drUexit_status_levelrKUconfigrNUstrict_visitorrNUcloak_email_addressesrUtrim_footnote_reference_spacerUenvrNUdump_pseudo_xmlrNUexpose_internalsrNUsectsubtitle_xformrU source_linkrNUrfc_referencesrNUoutput_encodingrUutf-8rU source_urlrNUinput_encodingrU utf-8-sigrU_disable_configrNU id_prefixrUU tab_widthrKUerror_encodingrUUTF-8rU_sourcerUI/var/build/user_builds/imbo/checkouts/1.1.1/docs/develop/contributing.rstrUgettext_compactrU generatorrNUdump_internalsrNU smart_quotesrU pep_base_urlrUhttp://www.python.org/dev/peps/rUsyntax_highlightrUlongrUinput_encoding_error_handlerrjUauto_id_prefixrUidrUdoctitle_xformrUstrip_elements_with_classesrNU _config_filesr]Ufile_insertion_enabledrU raw_enabledrKU dump_settingsrNubUsymbol_footnote_startrKUidsr}r(h/jRh)jBh!jjh"jh#jh$j%h%hJh&hh'jbh(hJh-hh*jh huh.jDh+j$h0hh,juUsubstitution_namesr}rh=hHh?}r(hC]hA]hB]Usourceh;hD]hE]uU footnotesr]rUrefidsr}rh(]rh4asub.PKrNDx4imbo-1.1.1/.doctrees/develop/event_listeners.doctreecdocutils.nodes document q)q}q(U nametypesq}q(XclosureqXwriting an event listenerqNXcustom-event-listenersqXthe event objectq NX use a closureq NX#use a class with an __invoke methodq NX<implement the imbo\eventlistener\listenerinterface interfaceq NX'working with events and event listenersq NXthe-event-objectqXeventsqNuUsubstitution_defsq}qUparse_messagesq]qcdocutils.nodes system_message q)q}q(U rawsourceqUUparentqcdocutils.nodes section q)q}q(hUhh)q}q(hUhh)q}q(hUhhUsourceq cdocutils.nodes reprunicode q!XL/var/build/user_builds/imbo/checkouts/1.1.1/docs/develop/event_listeners.rstq"q#}q$bUtagnameq%Usectionq&U attributesq'}q((Udupnamesq)]Uclassesq*]Ubackrefsq+]Uidsq,]q-U'working-with-events-and-event-listenersq.aUnamesq/]q0h auUlineq1KUdocumentq2hUchildrenq3]q4(cdocutils.nodes title q5)q6}q7(hX'Working with events and event listenersq8hhh h#h%Utitleq9h'}q:(h)]h*]h+]h,]h/]uh1Kh2hh3]q;cdocutils.nodes Text q}q?(hh8hh6ubaubcdocutils.nodes paragraph q@)qA}qB(hXImbo uses an event dispatcher to trigger certain events from inside the application that you can subscribe to by using event listeners. In this chapter you can find information regarding the events that are triggered, and how to be able to write your own event listeners for Imbo.qChhh h#h%U paragraphqDh'}qE(h)]h*]h+]h,]h/]uh1Kh2hh3]qFh`qkhhbh h#h%U list_itemqlh'}qm(h)]h*]h+]h,]h/]uh1Nh2hh3]qnh@)qo}qp(hhkhhih h#h%hDh'}qq(h)]h*]h+]h,]h/]uh1K h3]qrcsphinx.addnodes pending_xref qs)qt}qu(hhkhhoh h#h%U pending_xrefqvh'}qw(UreftypeXrefUrefwarnqxU reftargetqyXindex-resourceU refdomainXstdqzh,]h+]U refexplicith)]h*]h/]Urefdocq{Xdevelop/event_listenersq|uh1K h3]q}cdocutils.nodes emphasis q~)q}q(hhkh'}q(h)]h*]q(UxrefqhzXstd-refqeh+]h,]h/]uhhth3]qh`qhhbh h#h%hlh'}q(h)]h*]h+]h,]h/]uh1Nh2hh3]qh@)q}q(hhhhh h#h%hDh'}q(h)]h*]h+]h,]h/]uh1K h3]qhs)q}q(hhhhh h#h%hvh'}q(UreftypeXrefhxhyXstats-resourceU refdomainXstdqh,]h+]U refexplicith)]h*]h/]h{h|uh1K h3]qh~)q}q(hhh'}q(h)]h*]q(hhXstd-refqeh+]h,]h/]uhhh3]qh`qhhbh h#h%hlh'}q(h)]h*]h+]h,]h/]uh1Nh2hh3]qh@)q}q(hhhhh h#h%hDh'}q(h)]h*]h+]h,]h/]uh1K h3]qhs)q}q(hhhhh h#h%hvh'}q(UreftypeXrefhxhyXstatus-resourceU refdomainXstdqh,]h+]U refexplicith)]h*]h/]h{h|uh1K h3]qh~)q}q(hhh'}q(h)]h*]q(hhXstd-refqeh+]h,]h/]uhhh3]qh`qhhbh h#h%hlh'}q(h)]h*]h+]h,]h/]uh1Nh2hh3]qh@)q}q(hhhhh h#h%hDh'}q(h)]h*]h+]h,]h/]uh1Kh3]qhs)q}q(hhhhh h#h%hvh'}q(UreftypeXrefhxhyX user-resourceU refdomainXstdqh,]h+]U refexplicith)]h*]h/]h{h|uh1Kh3]qh~)q}q(hhh'}q(h)]h*]q(hhXstd-refqeh+]h,]h/]uhhh3]qh`qhhbh h#h%hlh'}q(h)]h*]h+]h,]h/]uh1Nh2hh3]qh@)q}q(hhhhh h#h%hDh'}q(h)]h*]h+]h,]h/]uh1Kh3]qhs)q}q(hhhhh h#h%hvh'}q(UreftypeXrefhxhyXimages-resourceU refdomainXstdqh,]h+]U refexplicith)]h*]h/]h{h|uh1Kh3]qh~)q}q(hhh'}q(h)]h*]q(hhXstd-refqeh+]h,]h/]uhhh3]qh`qhhbh h#h%hlh'}q(h)]h*]h+]h,]h/]uh1Nh2hh3]qh@)q}q(hhhhh h#h%hDh'}q(h)]h*]h+]h,]h/]uh1Kh3]qhs)q}q(hhhhh h#h%hvh'}q(UreftypeXrefhxhyXimage-resourceU refdomainXstdqh,]h+]U refexplicith)]h*]h/]h{h|uh1Kh3]qh~)q}q(hhh'}q(h)]h*]q(hhXstd-refqeh+]h,]h/]uhhh3]qh`qhhbh h#h%hlh'}r(h)]h*]h+]h,]h/]uh1Nh2hh3]rh@)r}r(hhhhh h#h%hDh'}r(h)]h*]h+]h,]h/]uh1Kh3]rhs)r}r(hhhjh h#h%hvh'}r(UreftypeXrefhxhyXshorturl-resourceU refdomainXstdr h,]h+]U refexplicith)]h*]h/]h{h|uh1Kh3]r h~)r }r (hhh'}r (h)]h*]r(hj Xstd-refreh+]h,]h/]uhjh3]rh` hhbh h#h%hlh'}r(h)]h*]h+]h,]h/]uh1Nh2hh3]rh@)r}r(hX#:ref:`metadata `rhjh h#h%hDh'}r(h)]h*]h+]h,]h/]uh1Kh3]rhs)r}r(hjhjh h#h%hvh'}r(UreftypeXrefhxhyXmetadata-resourceU refdomainXstdr h,]h+]U refexplicith)]h*]h/]h{h|uh1Kh3]r!h~)r"}r#(hjh'}r$(h)]h*]r%(hj Xstd-refr&eh+]h,]h/]uhjh3]r'h(h)]h*]h+]h,]h/]uh1Kh3]r?cdocutils.nodes literal r@)rA}rB(hj9h'}rC(h)]h*]h+]h,]h/]uhj<h3]rDh}r?(hj7h'}r@(h)]h*]h+]h,]h/]uhj:h3]rAhubah%jHubaubaubhh)rE}rF(hX``response.send`` hjh h#h%hlh'}rG(h)]h*]h+]h,]h/]uh1Nh2hh3]rHh@)rI}rJ(hX``response.send``rKhjEh h#h%hDh'}rL(h)]h*]h+]h,]h/]uh1K*h3]rMj@)rN}rO(hjKh'}rP(h)]h*]h+]h,]h/]uhjIh3]rQh` for an example on how to achieve this. hjh h#h%jh'}r (h)]h*]h+]h,]h/]uh1Kh2hh3]r (j)r }r (hX``getHandler()``r hjh h#h%jh'}r(h)]h*]h+]h,]h/]uh1Kh3]rj@)r}r(hj h'}r(h)]h*]h+]h,]h/]uhj h3]rh` for an example on how to achieve this.hjh h#h%hDh'}r(h)]h*]h+]h,]h/]uh1Kh3]r(h`r$hjh h#h%hvh'}r%(UreftypeXrefhxhyXcors-event-listenerU refdomainXstdr&h,]h+]U refexplicith)]h*]h/]h{h|uh1Kh3]r'h~)r(}r)(hj$h'}r*(h)]h*]r+(hj&Xstd-refr,eh+]h,]h/]uhj"h3]r-h(hj:h'}r?(h)]h*]h+]h,]h/]uhj8h3]r@h(h)]h*]h+]h,]h/]uh1Kh2hh3]r?(j)r@}rA(hX``getArgument()``rBhj<h h#h%jh'}rC(h)]h*]h+]h,]h/]uh1Kh3]rDj@)rE}rF(hjBh'}rG(h)]h*]h+]h,]h/]uhj@h3]rHh`_ hjxh h#h%hlh'}r(h)]h*]h+]h,]h/]uh1Nh2hh3]rh@)r}r(hX-Use a `Closure `_hjh h#h%hDh'}r(h)]h*]h+]h,]h/]uh1K`_h'}r(UnameXClosureUrefurirXhttp://www.php.net/closurerh,]h+]h)]h*]h/]uhjh3]rhU referencedrKhjh%jh'}r(Urefurijh,]rUclosurerah+]h)]h*]h/]rhauh3]ubeubaubeubh@)r}r(hX?Below you will find examples on the approaches mentioned above.rhhh h#h%hDh'}r(h)]h*]h+]h,]h/]uh1K>h2hh3]rh` section.rhhh h#h%Unoterh'}r(h)]h*]h+]h,]h/]uh1Nh2hh3]rh@)r}r(hjhjh h#h%hDh'}r(h)]h*]h+]h,]h/]uh1KAh3]r(h`rhjh h#h%hvh'}r(UreftypeXrefhxhyXconfiguration-event-listenersU refdomainXstdrh,]h+]U refexplicith)]h*]h/]h{h|uh1KAh3]rh~)r}r(hjh'}r(h)]h*]r(hjXstd-refreh+]h,]h/]uhjh3]rh * * For the full copyright and license information, please view the LICENSE file that was * distributed with this source code. */ namespace Imbo\EventListener; /** * Event listener interface * * @author Christer Edvartsen * @package Event\Listeners */ interface ListenerInterface { /** * Return an array with events to subscribe to * * Single callbacks can use the simplest method, defaulting to a priority of 0 * * return array( * 'event' => 'someMethod', * 'event2' => 'someOtherMethod', * ); * * If you want to specify multiple callbacks and/or a priority for the callback(s): * * return array( * 'event' => array( * 'someMethod', // Defaults to priority 0, same as 'someMethod' => 0 * 'someOtherMethod' => 10, // Will trigger before "someMethod" * 'someThirdMethod' => -10, // Will trigger after "someMethod" * ), * 'event2' => 'someOtherMethod', * ); * * @return array */ static function getSubscribedEvents(); } hjh h#h%U literal_blockr%h'}r&(Ulinenosr'Ulanguager(h!Xphpr)r*}r+bh)]U xml:spacer,Upreserver-h,]h+]UsourceX\/var/build/user_builds/imbo/checkouts/1.1.1/library/Imbo/EventListener/ListenerInterface.phph*]h/]uh1KHh2hh3]r.h * * For the full copyright and license information, please view the LICENSE file that was * distributed with this source code. */ namespace Imbo\EventListener; /** * Event listener interface * * @author Christer Edvartsen * @package Event\Listeners */ interface ListenerInterface { /** * Return an array with events to subscribe to * * Single callbacks can use the simplest method, defaulting to a priority of 0 * * return array( * 'event' => 'someMethod', * 'event2' => 'someOtherMethod', * ); * * If you want to specify multiple callbacks and/or a priority for the callback(s): * * return array( * 'event' => array( * 'someMethod', // Defaults to priority 0, same as 'someMethod' => 0 * 'someOtherMethod' => 10, // Will trigger before "someMethod" * 'someThirdMethod' => -10, // Will trigger after "someMethod" * ), * 'event2' => 'someOtherMethod', * ); * * @return array */ static function getSubscribedEvents(); } r/r0}r1(hUhj#ubaubh@)r2}r3(hX The only method you need to implement is called ``getSubscribedEvents`` and that method should return an array where the keys are event names, and the values are callbacks. You can have several callbacks to the same event, and they can all have specific priorities.r4hjh h#h%hDh'}r5(h)]h*]h+]h,]h/]uh1KLh2hh3]r6(hr?}r@(hUhj:ubah%jHubh 100); } return $callbacks; } public function authenticate(Imbo\EventManager\EventInterface $event) { // Code that handles all events this listener subscribes to } // ...hjh h#h%j%h'}rj(j'j(Xphpj,j-h,]h+]h)]h*]h/]uh1KPh2hh3]rkh 100); } return $callbacks; } public function authenticate(Imbo\EventManager\EventInterface $event) { // Code that handles all events this listener subscribes to } // ...rlrm}rn(hUhjhubaubh@)ro}rp(hXIn the snippet above the same method (``authenticate``) is attached to several events. The priority used is 100, which means it's triggered early in the application flow.rqhjh h#h%hDh'}rr(h)]h*]h+]h,]h/]uh1Kmh2hh3]rs(h` that it can work with. The fact that the above code only uses a single callback for all events is an implementation detail. You can use different callbacks for all events if you want to.rhjh h#h%hDh'}r(h)]h*]h+]h,]h/]uh1Koh2hh3]r(h`rhjh h#h%hvh'}r(UreftypeXrefhxhyXthe-event-objectU refdomainXstdrh,]h+]U refexplicith)]h*]h/]h{h|uh1Koh3]rh~)r}r(hjh'}r(h)]h*]r(hjXstd-refreh+]h,]h/]uhjh3]rh`_:rhhh h#h%hDh'}r(h)]h*]h+]h,]h/]uh1Kh2hh3]r(h`_h'}r(UnameXClosurejXhttp://www.php.net/closurerh,]h+]h)]h*]h/]uhjh3]rhjKhjh%jh'}r (Urefurijh,]r Uid1r ah+]h)]rXclosurerah*]h/]uh3]ubh array( 'customListener' => array( 'callback' => function(Imbo\EventManager\EventInterface $event) { // Custom code }, 'events' => array('image.get'), ), ), // ... );hhh h#h%j%h'}r(j'j(Xphpj,j-h,]h+]h)]h*]h/]uh1Kh2hh3]rh array( 'customListener' => array( 'callback' => function(Imbo\EventManager\EventInterface $event) { // Custom code }, 'events' => array('image.get'), ), ), // ... );rr}r(hUhjubaubh@)r}r(hX-The ``$event`` object passed to the function is the same as in the previous two examples. This approach should mostly be used for testing purposes and quick hacks. More information regarding this approach is available in the :ref:`event listener configuration ` section.rhhh h#h%hDh'}r(h)]h*]h+]h,]h/]uh1Kh2hh3]r(h`r-hjh h#h%hvh'}r.(UreftypeXrefhxhyXconfiguration-event-listenersU refdomainXstdr/h,]h+]U refexplicith)]h*]h/]h{h|uh1Kh3]r0h~)r1}r2(hj-h'}r3(h)]h*]r4(hj/Xstd-refr5eh+]h,]h/]uhj+h3]r6h(h)]UlevelKh,]h+]r?j aUsourceh#h*]h/]UlineKUtypeUINFOr@uh1Kh2hh3]rAh@)rB}rC(hUh'}rD(h)]h*]h+]h,]h/]uhhh3]rEh` and :ref:`Storage configuration ` sections for more information on how to enable different adapters in the configuration.q;hhhhhU paragraphq(h4X1If the adapters shipped with Imbo does not fit your needs you can implement your own set of database and/or storage adapters and have Imbo use them pretty easily. A set of interfaces exists for you to implement, and then all that's left to do is to enable the adapters in your configuration file. See the q?q@}qA(hX1If the adapters shipped with Imbo does not fit your needs you can implement your own set of database and/or storage adapters and have Imbo use them pretty easily. A set of interfaces exists for you to implement, and then all that's left to do is to enable the adapters in your configuration file. See the hh9ubcsphinx.addnodes pending_xref qB)qC}qD(hX5:ref:`Database confguration `qEhh9hhhU pending_xrefqFh!}qG(UreftypeXrefUrefwarnqHU reftargetqIXdatabase-configurationU refdomainXstdqJh&]h%]U refexplicith#]h$]h(]UrefdocqKXdevelop/custom_adaptersqLuh*Kh]qMcdocutils.nodes emphasis qN)qO}qP(hhEh!}qQ(h#]h$]qR(UxrefqShJXstd-refqTeh%]h&]h(]uhhCh]qUh4XDatabase confgurationqVqW}qX(hUhhOubahUemphasisqYubaubh4X and qZq[}q\(hX and hh9ubhB)q]}q^(hX4:ref:`Storage configuration `q_hh9hhhhFh!}q`(UreftypeXrefhHhIXstorage-configurationU refdomainXstdqah&]h%]U refexplicith#]h$]h(]hKhLuh*Kh]qbhN)qc}qd(hh_h!}qe(h#]h$]qf(hShaXstd-refqgeh%]h&]h(]uhh]h]qhh4XStorage configurationqiqj}qk(hUhhcubahhYubaubh4XX sections for more information on how to enable different adapters in the configuration.qlqm}qn(hXX sections for more information on how to enable different adapters in the configuration.hh9ubeubh8)qo}qp(hXCustom database adapters must implement the ``Imbo\Database\DatabaseInterface`` interface, and custom storage adapters must implement the ``Imbo\Storage\StorageInterface`` interface.qqhhhhhh`_.qhhhhhh`_h!}q(UnameXGitHubUrefuriqXhttps://github.com/imbo/imboqh&]h%]h#]h$]h(]uhhh]qh4XGitHubqq}q(hUhhubahU referencequbcdocutils.nodes target q)q}q(hX U referencedqKhhhUtargetqh!}q(Urefurihh&]qhah%]h#]h$]h(]qhauh]ubh4X.q}q(hX.hhubeubeubahUU transformerqNU footnote_refsq}qUrefnamesq}qUsymbol_footnotesq]qUautofootnote_refsq]qUsymbol_footnote_refsq]qU citationsq]qh+hU current_lineqNUtransform_messagesq]qUreporterqNUid_startqKU autofootnotesq]qU citation_refsq}qUindirect_targetsq]qUsettingsq(cdocutils.frontend Values qoq}q(Ufootnote_backlinksqKUrecord_dependenciesqNU rfc_base_urlqUhttp://tools.ietf.org/html/qU tracebackqʈUpep_referencesqNUstrip_commentsqNU toc_backlinksqUentryqU language_codeqUenqU datestampqNU report_levelqKU _destinationqNU halt_levelqKU strip_classesqNh1NUerror_encoding_error_handlerqUbackslashreplaceqUdebugqNUembed_stylesheetqىUoutput_encoding_error_handlerqUstrictqU sectnum_xformqKUdump_transformsqNU docinfo_xformqKUwarning_streamqNUpep_file_url_templateqUpep-%04dqUexit_status_levelqKUconfigqNUstrict_visitorqNUcloak_email_addressesqUtrim_footnote_reference_spaceqUenvqNUdump_pseudo_xmlqNUexpose_internalsqNUsectsubtitle_xformqU source_linkqNUrfc_referencesqNUoutput_encodingqUutf-8qU source_urlqNUinput_encodingqU utf-8-sigqU_disable_configqNU id_prefixqUU tab_widthqKUerror_encodingqUUTF-8qU_sourceqUL/var/build/user_builds/imbo/checkouts/1.1.1/docs/develop/custom_adapters.rstqUgettext_compactqU generatorqNUdump_internalsqNU smart_quotesqU pep_base_urlqUhttp://www.python.org/dev/peps/qUsyntax_highlightqUlongrUinput_encoding_error_handlerrhUauto_id_prefixrUidrUdoctitle_xformrUstrip_elements_with_classesrNU _config_filesr]Ufile_insertion_enabledrU raw_enabledrKU dump_settingsr NubUsymbol_footnote_startr KUidsr }r (hhhhuUsubstitution_namesr }rhh+h!}r(h#]h&]h%]Usourcehh$]h(]uU footnotesr]rUrefidsr}rub.PKrND/:imbo-1.1.1/.doctrees/develop/image_transformations.doctreecdocutils.nodes document q)q}q(U nametypesq}q(Xcustom-image-transformationsqX(implement your own image transformationsqNuUsubstitution_defsq}q Uparse_messagesq ]q Ucurrent_sourceq NU decorationq NUautofootnote_startqKUnameidsq}q(hUcustom-image-transformationsqhU(implement-your-own-image-transformationsquUchildrenq]q(cdocutils.nodes target q)q}q(U rawsourceqX!.. _custom-image-transformations:UparentqhUsourceqcdocutils.nodes reprunicode qXR/var/build/user_builds/imbo/checkouts/1.1.1/docs/develop/image_transformations.rstqq}qbUtagnameqUtargetq U attributesq!}q"(Uidsq#]Ubackrefsq$]Udupnamesq%]Uclassesq&]Unamesq']Urefidq(huUlineq)KUdocumentq*hh]ubcdocutils.nodes section q+)q,}q-(hUhhhhUexpect_referenced_by_nameq.}q/hhshUsectionq0h!}q1(h%]h&]h$]h#]q2(hheh']q3(hheuh)Kh*hUexpect_referenced_by_idq4}q5hhsh]q6(cdocutils.nodes title q7)q8}q9(hX(Implement your own image transformationsq:hh,hhhUtitleq;h!}q<(h%]h&]h$]h#]h']uh)Kh*hh]q=cdocutils.nodes Text q>X(Implement your own image transformationsq?q@}qA(hh:hh8ubaubcdocutils.nodes paragraph qB)qC}qD(hXImbo also supports custom image transformations. All you need to do is to create an event listener, and configure your transformation:qEhh,hhhU paragraphqFh!}qG(h%]h&]h$]h#]h']uh)Kh*hh]qHh>XImbo also supports custom image transformations. All you need to do is to create an event listener, and configure your transformation:qIqJ}qK(hhEhhCubaubcdocutils.nodes literal_block qL)qM}qN(hX= 'transform'); } public function transform($event) { $image = $event->getArgument('image'); $params = $event->getArgument('params'); // If the transformation allows params in the URL // ... } } return array( // .. 'eventListeners' => array( 'coolTransformation' => 'My\Custom\Transformation', ), // ... );hh,hhhU literal_blockqOh!}qP(UlinenosqQUlanguageqRXphpU xml:spaceqSUpreserveqTh#]h$]h%]h&]h']uh)Kh*hh]qUh>X= 'transform'); } public function transform($event) { $image = $event->getArgument('image'); $params = $event->getArgument('params'); // If the transformation allows params in the URL // ... } } return array( // .. 'eventListeners' => array( 'coolTransformation' => 'My\Custom\Transformation', ), // ... );qVqW}qX(hUhhMubaubhB)qY}qZ(hXWhenever someone requests an image using ``?t[]=coolTransformation:width=100,height=200`` Imbo will trigger the ``image.transformation.cooltransformation`` event, and assign the following value to the ``params`` argument of the event:q[hh,hhhhFh!}q\(h%]h&]h$]h#]h']uh)K"h*hh]q](h>X)Whenever someone requests an image using q^q_}q`(hX)Whenever someone requests an image using hhYubcdocutils.nodes literal qa)qb}qc(hX0``?t[]=coolTransformation:width=100,height=200``h!}qd(h%]h&]h$]h#]h']uhhYh]qeh>X,?t[]=coolTransformation:width=100,height=200qfqg}qh(hUhhbubahUliteralqiubh>X Imbo will trigger the qjqk}ql(hX Imbo will trigger the hhYubha)qm}qn(hX+``image.transformation.cooltransformation``h!}qo(h%]h&]h$]h#]h']uhhYh]qph>X'image.transformation.cooltransformationqqqr}qs(hUhhmubahhiubh>X. event, and assign the following value to the qtqu}qv(hX. event, and assign the following value to the hhYubha)qw}qx(hX ``params``h!}qy(h%]h&]h$]h#]h']uhhYh]qzh>Xparamsq{q|}q}(hUhhwubahhiubh>X argument of the event:q~q}q(hX argument of the event:hhYubeubhL)q}q(hX5array( 'width' => '100', 'height' => '200', )hh,hhhhOh!}q(hQhRXphphShTh#]h$]h%]h&]h']uh)K$h*hh]qh>X5array( 'width' => '100', 'height' => '200', )qq}q(hUhhubaubhB)q}q(hXTTake a look at the existing transformations included with Imbo for more information.qhh,hhhhFh!}q(h%]h&]h$]h#]h']uh)K+h*hh]qh>XTTake a look at the existing transformations included with Imbo for more information.qq}q(hhhhubaubeubehUU transformerqNU footnote_refsq}qUrefnamesq}qUsymbol_footnotesq]qUautofootnote_refsq]qUsymbol_footnote_refsq]qU citationsq]qh*hU current_lineqNUtransform_messagesq]qcdocutils.nodes system_message q)q}q(hUh!}q(h%]UlevelKh#]h$]Usourcehh&]h']UlineKUtypeUINFOquh]qhB)q}q(hUh!}q(h%]h&]h$]h#]h']uhhh]qh>XBHyperlink target "custom-image-transformations" is not referenced.qq}q(hUhhubahhFubahUsystem_messagequbaUreporterqNUid_startqKU autofootnotesq]qU citation_refsq}qUindirect_targetsq]qUsettingsq(cdocutils.frontend Values qoq}q(Ufootnote_backlinksqKUrecord_dependenciesqNU rfc_base_urlqUhttp://tools.ietf.org/html/qU tracebackqUpep_referencesqNUstrip_commentsqNU toc_backlinksqUentryqU language_codeqUenqU datestampqNU report_levelqKU _destinationqNU halt_levelqKU strip_classesqNh;NUerror_encoding_error_handlerqUbackslashreplaceqUdebugqNUembed_stylesheetq͉Uoutput_encoding_error_handlerqUstrictqU sectnum_xformqKUdump_transformsqNU docinfo_xformqKUwarning_streamqNUpep_file_url_templateqUpep-%04dqUexit_status_levelqKUconfigqNUstrict_visitorqNUcloak_email_addressesqوUtrim_footnote_reference_spaceqډUenvqNUdump_pseudo_xmlqNUexpose_internalsqNUsectsubtitle_xformqމU source_linkqNUrfc_referencesqNUoutput_encodingqUutf-8qU source_urlqNUinput_encodingqU utf-8-sigqU_disable_configqNU id_prefixqUU tab_widthqKUerror_encodingqUUTF-8qU_sourceqUR/var/build/user_builds/imbo/checkouts/1.1.1/docs/develop/image_transformations.rstqUgettext_compactqU generatorqNUdump_internalsqNU smart_quotesqU pep_base_urlqUhttp://www.python.org/dev/peps/qUsyntax_highlightqUlongqUinput_encoding_error_handlerqhUauto_id_prefixqUidqUdoctitle_xformqUstrip_elements_with_classesqNU _config_filesq]qUfile_insertion_enabledqU raw_enabledqKU dump_settingsqNubUsymbol_footnote_startqKUidsr}r(hh,hh,uUsubstitution_namesr}rhh*h!}r(h%]h#]h$]Usourcehh&]h']uU footnotesr]rUrefidsr}rh]r hasub.PKrNDqECC3imbo-1.1.1/.doctrees/develop/cache_adapters.doctreecdocutils.nodes document q)q}q(U nametypesq}q(Xmemcached-cacheqX implement a custom cache adapterqNXcache adaptersqNXgithubq Xapcq NX apc-cacheq X memcachedq Xcustom-cache-adapterq XapcuquUsubstitution_defsq}qUparse_messagesq]qcdocutils.nodes system_message q)q}q(U rawsourceqUUparentqcdocutils.nodes section q)q}q(hUU referencedqKhh)q}q(hUhhUsourceqcdocutils.nodes reprunicode qXK/var/build/user_builds/imbo/checkouts/1.1.1/docs/develop/cache_adapters.rstq q!}q"bUtagnameq#Usectionq$U attributesq%}q&(Udupnamesq']Uclassesq(]Ubackrefsq)]Uidsq*]q+Ucache-adaptersq,aUnamesq-]q.hauUlineq/KUdocumentq0hUchildrenq1]q2(cdocutils.nodes title q3)q4}q5(hXCache adaptersq6hhhh!h#Utitleq7h%}q8(h']h(]h)]h*]h-]uh/Kh0hh1]q9cdocutils.nodes Text q:XCache adaptersq;q<}q=(hh6hh4ubaubcdocutils.nodes paragraph q>)q?}q@(hXeIf you want to leverage caching in a custom event listener, Imbo ships with some different solutions:qAhhhh!h#U paragraphqBh%}qC(h']h(]h)]h*]h-]uh/Kh0hh1]qDh:XeIf you want to leverage caching in a custom event listener, Imbo ships with some different solutions:qEqF}qG(hhAhh?ubaubcdocutils.nodes target qH)qI}qJ(hX.. _apc-cache:hhhh!h#UtargetqKh%}qL(h*]h)]h']h(]h-]UrefidqMU apc-cacheqNuh/Kh0hh1]ubh)qO}qP(hUhhhh!Uexpect_referenced_by_nameqQ}qRh hIsh#h$h%}qS(h']h(]h)]h*]qT(UapcqUhNeh-]qV(h h euh/K h0hUexpect_referenced_by_idqW}qXhNhIsh1]qY(h3)qZ}q[(hXAPCq\hhOhh!h#h7h%}q](h']h(]h)]h*]h-]uh/K h0hh1]q^h:XAPCq_q`}qa(hh\hhZubaubh>)qb}qc(hXThis adapter uses the `APCu `_ extension for caching. If your Imbo installation consists of a single httpd this is a good choice. The adapter has the following parameters:qdhhOhh!h#hBh%}qe(h']h(]h)]h*]h-]uh/K h0hh1]qf(h:XThis adapter uses the qgqh}qi(hXThis adapter uses the hhbubcdocutils.nodes reference qj)qk}ql(hX"`APCu `_h%}qm(UnameXAPCuUrefuriqnXhttp://pecl.php.net/apcuqoh*]h)]h']h(]h-]uhhbh1]qph:XAPCuqqqr}qs(hUhhkubah#U referenceqtubhH)qu}qv(hX hKhhbh#hKh%}qw(Urefurihoh*]qxUapcuqyah)]h']h(]h-]qzhauh1]ubh:X extension for caching. If your Imbo installation consists of a single httpd this is a good choice. The adapter has the following parameters:q{q|}q}(hX extension for caching. If your Imbo installation consists of a single httpd this is a good choice. The adapter has the following parameters:hhbubeubcdocutils.nodes definition_list q~)q}q(hUhhOhh!h#Udefinition_listqh%}q(h']h(]h)]h*]h-]uh/Nh0hh1]qcdocutils.nodes definition_list_item q)q}q(hXR``$namespace`` (optional) A namespace for your cached items. For instance: "imbo" hhhh!h#Udefinition_list_itemqh%}q(h']h(]h)]h*]h-]uh/Kh1]q(cdocutils.nodes term q)q}q(hX``$namespace`` (optional)qhhhh!h#Utermqh%}q(h']h(]h)]h*]h-]uh/Kh1]q(cdocutils.nodes literal q)q}q(hX``$namespace``h%}q(h']h(]h)]h*]h-]uhhh1]qh:X $namespaceqq}q(hUhhubah#Uliteralqubh:X (optional)qq}q(hX (optional)hhubeubcdocutils.nodes definition q)q}q(hUh%}q(h']h(]h)]h*]h-]uhhh1]qh>)q}q(hX7A namespace for your cached items. For instance: "imbo"qhhhh!h#hBh%}q(h']h(]h)]h*]h-]uh/Kh1]qh:X7A namespace for your cached items. For instance: "imbo"qq}q(hhhhubaubah#U definitionqubeubaubh>)q}q(hXExample:qhhOhh!h#hBh%}q(h']h(]h)]h*]h-]uh/Kh0hh1]qh:XExample:qq}q(hhhhubaubcdocutils.nodes literal_block q)q}q(hXset('key', 'value'); echo $adapter->get('key'); // outputs "value" echo apc_fetch('imbo:key'); // outputs "value"hhOhh!h#U literal_blockqh%}q(UlinenosqUlanguageqXphpU xml:spaceqUpreserveqh*]h)]h']h(]h-]uh/Kh0hh1]qh:Xset('key', 'value'); echo $adapter->get('key'); // outputs "value" echo apc_fetch('imbo:key'); // outputs "value"qq}q(hUhhubaubhH)q}q(hX.. _memcached-cache:hhOhh!h#hKh%}q(h*]h)]h']h(]h-]hMUmemcached-cachequh/Kh0hh1]ubeubhh)q}q(hUhhhh!hQ}qh hH)q}q(hX.. _custom-cache-adapter:hhhh!h#hKh%}q(h*]h)]h']h(]h-]hMUcustom-cache-adapterquh/K6h0hh1]ubsh#h$h%}q(h']h(]h)]h*]q(U implement-a-custom-cache-adapterqheh-]q(hh euh/K9h0hhW}qhhsh1]q(h3)q}q(hX Implement a custom cache adapterqhhhh!h#h7h%}q(h']h(]h)]h*]h-]uh/K9h0hh1]qh:X Implement a custom cache adapterqօq}q(hhhhubaubh>)q}q(hXwIf you want to use some other cache mechanism an interface exists (``Imbo\Cache\CacheInterface``) for you to implement:qhhhh!h#hBh%}q(h']h(]h)]h*]h-]uh/K;h0hh1]q(h:XCIf you want to use some other cache mechanism an interface exists (qޅq}q(hXCIf you want to use some other cache mechanism an interface exists (hhubh)q}q(hX``Imbo\Cache\CacheInterface``h%}q(h']h(]h)]h*]h-]uhhh1]qh:XImbo\Cache\CacheInterfaceq允q}q(hUhhubah#hubh:X) for you to implement:q腁q}q(hX) for you to implement:hhubeubh)q}q(hX * * For the full copyright and license information, please view the LICENSE file that was * distributed with this source code. */ namespace Imbo\Cache; /** * Cache adapter interface * * An interface for cache adapters. * * @author Christer Edvartsen * @package Cache */ interface CacheInterface { /** * Get a cached value by a key * * @param string $key The key to get * @return mixed Returns the cached value or null if key does not exist */ function get($key); /** * Store a value in the cache * * @param string $key The key to associate with the item * @param mixed $value The value to store * @param int $expire Number of seconds to keep the item in the cache * @return boolean True on success, false otherwise */ function set($key, $value, $expire = 0); /** * Delete an item from the cache * * @param string $key The key to remove * @return boolean True on success, false otherwise */ function delete($key); /** * Increment a value * * @param string $key The key to use * @param int $amount The amount to increment with * @return int|boolean Returns new value on success or false on failure */ function increment($key, $amount = 1); /** * Decrement a value * * @param string $key The key to use * @param int $amount The amount to decrement with * @return int|boolean Returns new value on success or false on failure */ function decrement($key, $amount = 1); } hhhh!h#hh%}q(hhhXphpqq}qbh']hhh*]h)]UsourceXQ/var/build/user_builds/imbo/checkouts/1.1.1/library/Imbo/Cache/CacheInterface.phph(]h-]uh/K=h0hh1]qh:X * * For the full copyright and license information, please view the LICENSE file that was * distributed with this source code. */ namespace Imbo\Cache; /** * Cache adapter interface * * An interface for cache adapters. * * @author Christer Edvartsen * @package Cache */ interface CacheInterface { /** * Get a cached value by a key * * @param string $key The key to get * @return mixed Returns the cached value or null if key does not exist */ function get($key); /** * Store a value in the cache * * @param string $key The key to associate with the item * @param mixed $value The value to store * @param int $expire Number of seconds to keep the item in the cache * @return boolean True on success, false otherwise */ function set($key, $value, $expire = 0); /** * Delete an item from the cache * * @param string $key The key to remove * @return boolean True on success, false otherwise */ function delete($key); /** * Increment a value * * @param string $key The key to use * @param int $amount The amount to increment with * @return int|boolean Returns new value on success or false on failure */ function increment($key, $amount = 1); /** * Decrement a value * * @param string $key The key to use * @param int $amount The amount to decrement with * @return int|boolean Returns new value on success or false on failure */ function decrement($key, $amount = 1); } qq}q(hUhhubaubh>)q}q(hXIf you choose to implement this interface you can also use your custom cache adapter for all the event listeners Imbo ships with that leverages a cache.qhhhh!h#hBh%}q(h']h(]h)]h*]h-]uh/KAh0hh1]qh:XIf you choose to implement this interface you can also use your custom cache adapter for all the event listeners Imbo ships with that leverages a cache.qq}q(hhhhubaubh>)q}q(hXIf you implement an adapter that you think should be a part of Imbo feel free to send a pull request on `GitHub `_.qhhhh!h#hBh%}r(h']h(]h)]h*]h-]uh/KCh0hh1]r(h:XhIf you implement an adapter that you think should be a part of Imbo feel free to send a pull request on rr}r(hXhIf you implement an adapter that you think should be a part of Imbo feel free to send a pull request on hhubhj)r}r(hX(`GitHub `_h%}r(UnameXGitHubhnXhttps://github.com/imbo/imborh*]h)]h']h(]h-]uhhh1]r h:XGitHubr r }r (hUhjubah#htubhH)r }r(hX hKhhh#hKh%}r(Urefurijh*]rUgithubrah)]h']h(]h-]rh auh1]ubh:X.r}r(hX.hhubeubeubeubhh!hQ}rhhsh#h$h%}r(h']rX memcachedrah(]h)]h*]r(U memcachedrheh-]rhauh/Kh0hhW}rhhsh1]r(h3)r}r(hX Memcachedr hhhh!h#h7h%}r!(h']h(]h)]h*]h-]uh/Kh0hh1]r"h:X Memcachedr#r$}r%(hj hjubaubh>)r&}r'(hX.This adapter uses `Memcached `_ for caching. If you have multiple httpd instances running Imbo this adapter lets you share the cache between all instances automatically by letting the adapter connect to the same Memcached daemon. The adapter has the following parameters:r(hhhh!h#hBh%}r)(h']h(]h)]h*]h-]uh/K h0hh1]r*(h:XThis adapter uses r+r,}r-(hXThis adapter uses hj&ubhj)r.}r/(hX,`Memcached `_h%}r0(UnameX MemcachedhnXhttp://pecl.php.net/memcachedr1h*]h)]h']h(]h-]uhj&h1]r2h:X Memcachedr3r4}r5(hUhj.ubah#htubhH)r6}r7(hX hKhj&h#hKh%}r8(Urefurij1h*]r9Uid1r:ah)]h']h(]h-]r;jauh1]ubh:X for caching. If you have multiple httpd instances running Imbo this adapter lets you share the cache between all instances automatically by letting the adapter connect to the same Memcached daemon. The adapter has the following parameters:r<r=}r>(hX for caching. If you have multiple httpd instances running Imbo this adapter lets you share the cache between all instances automatically by letting the adapter connect to the same Memcached daemon. The adapter has the following parameters:hj&ubeubh~)r?}r@(hUhhhh!h#hh%}rA(h']h(]h)]h*]h-]uh/Nh0hh1]rB(h)rC}rD(hX8``$memcached`` An instance of the pecl/memcached class. hj?hh!h#hh%}rE(h']h(]h)]h*]h-]uh/K#h1]rF(h)rG}rH(hX``$memcached``rIhjChh!h#hh%}rJ(h']h(]h)]h*]h-]uh/K#h1]rKh)rL}rM(hjIh%}rN(h']h(]h)]h*]h-]uhjGh1]rOh:X $memcachedrPrQ}rR(hUhjLubah#hubaubh)rS}rT(hUh%}rU(h']h(]h)]h*]h-]uhjCh1]rVh>)rW}rX(hX(An instance of the pecl/memcached class.rYhjShh!h#hBh%}rZ(h']h(]h)]h*]h-]uh/K#h1]r[h:X(An instance of the pecl/memcached class.r\r]}r^(hjYhjWubaubah#hubeubh)r_}r`(hXS``$namespace`` (optional) A namespace for your cached items. For instance: "imbo". hj?hh!h#hh%}ra(h']h(]h)]h*]h-]uh/K&h0hh1]rb(h)rc}rd(hX``$namespace`` (optional)rehj_hh!h#hh%}rf(h']h(]h)]h*]h-]uh/K&h1]rg(h)rh}ri(hX``$namespace``h%}rj(h']h(]h)]h*]h-]uhjch1]rkh:X $namespacerlrm}rn(hUhjhubah#hubh:X (optional)rorp}rq(hX (optional)hjcubeubh)rr}rs(hUh%}rt(h']h(]h)]h*]h-]uhj_h1]ruh>)rv}rw(hX8A namespace for your cached items. For instance: "imbo".rxhjrhh!h#hBh%}ry(h']h(]h)]h*]h-]uh/K&h1]rzh:X8A namespace for your cached items. For instance: "imbo".r{r|}r}(hjxhjvubaubah#hubeubeubh>)r~}r(hXExample:rhhhh!h#hBh%}r(h']h(]h)]h*]h-]uh/K(h0hh1]rh:XExample:rr}r(hjhj~ubaubh)r}r(hX addServer('hostname', 11211); $adapter = new Imbo\Cache\Memcached($memcached, 'imbo'); $adapter->set('key', 'value'); echo $adapter->get('key'); // outputs "value" echo $memcached->get('imbo:key'); // outputs "value"hhhh!h#hh%}r(hhXphphhh*]h)]h']h(]h-]uh/K*h0hh1]rh:X addServer('hostname', 11211); $adapter = new Imbo\Cache\Memcached($memcached, 'imbo'); $adapter->set('key', 'value'); echo $adapter->get('key'); // outputs "value" echo $memcached->get('imbo:key'); // outputs "value"rr}r(hUhjubaubheubhh!h#Usystem_messagerh%}r(h']UlevelKh*]h)]rj:aUsourceh!h(]h-]UlineKUtypeUINFOruh/K!h0hh1]rh>)r}r(hUh%}r(h']h(]h)]h*]h-]uhhh1]rh:X,Duplicate implicit target name: "memcached".rr}r(hUhjubah#hBubaubaUcurrent_sourcerNU decorationrNUautofootnote_startrKUnameidsr}r(hhhhhh,h jh hUh hNh j:h hhhyuh1]rhahUU transformerrNU footnote_refsr}rUrefnamesr}rUsymbol_footnotesr]rUautofootnote_refsr]rUsymbol_footnote_refsr]rU citationsr]rh0hU current_linerNUtransform_messagesr]r(h)r}r(hUh%}r(h']UlevelKh*]h)]Usourceh!h(]h-]UlineKUtypejuh1]rh>)r}r(hUh%}r(h']h(]h)]h*]h-]uhjh1]rh:X/Hyperlink target "apc-cache" is not referenced.rr}r(hUhjubah#hBubah#jubh)r}r(hUh%}r(h']UlevelKh*]h)]Usourceh!h(]h-]UlineKUtypejuh1]rh>)r}r(hUh%}r(h']h(]h)]h*]h-]uhjh1]rh:X5Hyperlink target "memcached-cache" is not referenced.rr}r(hUhjubah#hBubah#jubh)r}r(hUh%}r(h']UlevelKh*]h)]Usourceh!h(]h-]UlineK6Utypejuh1]rh>)r}r(hUh%}r(h']h(]h)]h*]h-]uhjh1]rh:X:Hyperlink target "custom-cache-adapter" is not referenced.rr}r(hUhjubah#hBubah#jubeUreporterrNUid_startrKU autofootnotesr]rU citation_refsr}rUindirect_targetsr]rUsettingsr(cdocutils.frontend Values ror}r(Ufootnote_backlinksrKUrecord_dependenciesrNU rfc_base_urlrUhttp://tools.ietf.org/html/rU tracebackrUpep_referencesrNUstrip_commentsrNU toc_backlinksrUentryrU language_coderUenrU datestamprNU report_levelrKU _destinationrNU halt_levelrKU strip_classesrNh7NUerror_encoding_error_handlerrUbackslashreplacerUdebugrNUembed_stylesheetrUoutput_encoding_error_handlerrUstrictrU sectnum_xformrKUdump_transformsrNU docinfo_xformrKUwarning_streamrNUpep_file_url_templaterUpep-%04drUexit_status_levelrKUconfigrNUstrict_visitorrNUcloak_email_addressesrUtrim_footnote_reference_spacerUenvrNUdump_pseudo_xmlrNUexpose_internalsrNUsectsubtitle_xformrU source_linkrNUrfc_referencesrNUoutput_encodingrUutf-8rU source_urlrNUinput_encodingrU utf-8-sigrU_disable_configrNU id_prefixr UU tab_widthr KUerror_encodingr UUTF-8r U_sourcer UK/var/build/user_builds/imbo/checkouts/1.1.1/docs/develop/cache_adapters.rstrUgettext_compactrU generatorrNUdump_internalsrNU smart_quotesrU pep_base_urlrUhttp://www.python.org/dev/peps/rUsyntax_highlightrUlongrUinput_encoding_error_handlerrjUauto_id_prefixrUidrUdoctitle_xformrUstrip_elements_with_classesrNU _config_filesr]rUfile_insertion_enabledrU raw_enabledrKU dump_settingsr NubUsymbol_footnote_startr!KUidsr"}r#(hhh,hj:j6jj hhhUhOhNhOjhhhhyhuuUsubstitution_namesr$}r%h#h0h%}r&(h']h*]h)]Usourceh!h(]h-]uU footnotesr']r(Urefidsr)}r*(hN]r+hIah]r,hah]r-hauub.PKsNDEE)imbo-1.1.1/installation/installation.html Installation — Imbo 1.1.1 documentation

Installation

To install Imbo on the server you can choose between two different methods, Composer (recommended) or git clone.

Using composer

The recommended way of installing Imbo is by creating a composer.json file for your installation, and then install Imbo and optional 3rd party plug-ins via Composer. You will need the following directory structure for this method to work:

/path/to/install/composer.json
/path/to/install/config/

where the composer.json file can contain:

{
  "name": "yourname/imbo",
  "require": {
    "imbo/imbo": "dev-master"
  }
}

and the config/ directory contains one or more configuration files that will be merged with the default configuration. Imbo will load all .php files in this directory, and the ones returning an array will be used as configuration.

If you want to install 3rd party plug-ins and/or for instance the Doctrine DBAL library simply add these to the require object in your composer.json:

{
  "name": "yourname/imbo",
  "require": {
    "imbo/imbo": "dev-master",
    "rexxars/imbo-hipsta": "dev-master",
    "doctrine/dbal": "2.*"
  }
}

If some of the 3rd party plug-ins provide configuration files, you can link to these in the config/ directory to have Imbo automatically load them:

cd /path/to/install/config
ln -s ../vendor/rexxars/imbo-hipsta/config/config.php 01-imbo-hipsta.php

To be able to control the order that Imbo will use when loading the configuration files you should prefix them with a number, like 01 in the example above. Lower numbers will be loaded first, meaning that configuration files with higher numbers will override settings set in configuration files with a lower number.

Regarding the Imbo version you are about to install you can use dev-master for the latest released version, or you can use a specific version if you want to. Head over to Packagist to see the available versions. If you’re more of a YOLO type of person you can use dev-develop for the latest development version. If you choose to use the dev-develop branch, expect things to break from time to time.

Imbo strives to keep full BC in minor and patch releases, so you should be able to use Composer’s Next Significant Release feature when specifying which Imbo version you want to install. Reading the ChangeLog and other related sources of information before upgrading an installation is always recommended.

When you have created the composer.json file you can install Imbo with Composer:

curl -s https://getcomposer.org/installer | php
php composer.phar install -o --no-dev

After composer has finished installing Imbo and optional dependencies the Imbo installation will reside in /path/to/install/vendor/imbo/imbo. The correct web server document root in this case would be /path/to/install/vendor/imbo/imbo/public.

If you later want to update Imbo you can bump the version number you have specified in composer.json and run:

php composer.phar update -o --no-dev

Using git clone

You can also install Imbo directly via git, and then use Composer to install the dependencies:

mkdir /path/to/install; cd /path/to/install
git clone https://github.com/imbo/imbo.git
cd imbo
curl -s https://getcomposer.org/installer | php
php composer.phar install -o --no-dev

In this case the correct web server document root would be /path/to/install/imbo/public. Remember to checkout the correct branch after cloning the repository to get the version you want, for instance git checkout master. If you use this method of installation you will have to modify Imbo’s composer.json to install 3rd party libraries. You will also have to place your own config.php configuration file in the same directory as the default Imbo configuration file, which in the above example would be the /path/to/install/imbo/config directory.

If you want to contribute to Imbo, this is the obvious installation method. Read more about this in the Contributing to Imbo chapter.

Web server configuration

After installing Imbo by using one of the methods mentioned above you will have to configure the web server you want to use. Imbo ships with sample configuration files for Apache and Nginx that can be used with a few minor adjustments. Both configuration files assume the httpd runs on port 80. If you use Varnish or some other HTTP accelerator simply change the port number to the port that your httpd listens to.

Apache

You will need to enable mod_rewrite if you want to use Imbo with Apache. Below is an example on how to configure Apache for Imbo:

<VirtualHost *:80>
    # Servername of the virtual host
    ServerName imbo

    # Define aliases to use multiple hosts
    # ServerAlias imbo1 imbo2 imbo3

    # Document root where the index.php file is located
    DocumentRoot /path/to/install/vendor/imbo/imbo/public

    # Logging
    # CustomLog /var/log/apache2/imbo.access_log combined
    # ErrorLog /var/log/apache2/imbo.error_log

    # Rewrite rules that rewrite all requests to the index.php script
    <Directory /path/to/install/vendor/imbo/imbo/public>
        RewriteEngine on
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteRule .* index.php
    </Directory>
</VirtualHost>

You will need to update ServerName to match the host name you will use for Imbo. If you want to use several host names you can update the ServerAlias line as well. You must also update DocumentRoot and Directory to point to the public directory in the Imbo installation. If you want to enable logging update the CustomLog and ErrorLog lines. RewriteCond and RewriteRule should be left alone.

Nginx

Below is an example on how to configure Nginx for Imbo. This example uses PHP via FastCGI:

server {
    # Listen on port 80
    listen 80;

    # Define the server name
    server_name imbo;

    # Use the line below instead of the server_name above if you want to use multiple host names
    # server_name imbo imbo1 imbo2 imbo3;

    # Path to the public directory where index.php is located
    root /path/to/install/vendor/imbo/imbo/public;
    index index.php;

    # Logs
    # error_log /var/log/nginx/imbo.error_log;
    # access_log /var/log/nginx/imbo.access_log main;

    location / {
        try_files $uri $uri/ /index.php?$args;
        location ~ \.php$ {
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME /path/to/install/vendor/imbo/imbo/public/index.php;
            include fastcgi_params;
        }
    }
}

You will need to update server_name to match the host name you will use for Imbo. If you want to use several host names simply put several host names on that line. root must point to the public directory in the Imbo installation. If you want to enable logging update the error_log and access_log lines. You must also update the fastcgi_param SCRIPT_FILENAME line to point to the public/index.php file in the Imbo installation.

Lighttpd

Below is an example on how to configure Lighttpd for Imbo. Running PHP through FastCGI is recommended (not covered here).

# Use the line below instead of the next one if you want to use multiple host names
# $HTTP["host"] =~ "^(imbo|imbo1|imbo2|imbo3)$" {

$HTTP["host"] == "imbo" {
    # Listen on port 80
    server.port = 80

    # Path to the public directory where index.php is located
    server.document-root = "/path/to/install/vendor/imbo/imbo/public"

    # Logs
    # server.errorlog = "/var/log/lighttpd/imbo.error_log"
    # accesslog.filename = "/var/log/lighttpd/imbo.access_log"

    # Rewrite all to index.php
    url.rewrite-if-not-file = ("^/[^\?]*(\?.*)?$" => "index.php/$1")
}

You will need to set the correct host name(s) used with $HTTP["host"] and update the server.document-root to point to the correct path. If you want to enable logging remove the comments on the lines with server.errorlog and accesslog.filename and set the correct paths. If you want to specify a custom access log path you will need to enable the mod_accesslog module.

This example requires the mod_rewrite module to be loaded.

Varnish

Imbo strives to follow the HTTP Protocol, and can because of this easily leverage Varnish.

The only required configuration you need in your VCL is a default backend:

backend default {
    .host = "127.0.0.1";
    .port = "81";
}

where .host and .port is where Varnish can reach your web server.

If you use the same host name (or a sub-domain) for your Imbo installation as other services, that in turn uses Cookies, you might want the VCL to ignore these Cookies for the requests made against your Imbo installation (unless you have implemented event listeners for Imbo that uses Cookies). To achieve this you can put the following snippet into your VCL file:

sub vcl_recv {
    if (req.http.host == "imbo.example.com") {
        unset req.http.Cookie;
    }
}

or, if you have Imbo installed in some path:

sub vcl_recv {
    if (req.http.host ~ "^(www.)?example.com$" && req.url ~ "^/imbo/") {
        unset req.http.Cookie;
    }
}

if your Imbo installation is available on [www.]example.com/imbo.

Database setup

If you choose to use a RDBMS to store data in, you will need to manually create a database, a user and the tables Imbo stores information in. Below you will find schemas for different RDBMSs. You will find information regarding how to authenticate against the RDBMS of you choice in the Configuration topic.

MySQL

CREATE TABLE IF NOT EXISTS `imageinfo` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `publicKey` varchar(255) COLLATE utf8_danish_ci NOT NULL,
    `imageIdentifier` char(32) COLLATE utf8_danish_ci NOT NULL,
    `size` int(10) unsigned NOT NULL,
    `extension` varchar(5) COLLATE utf8_danish_ci NOT NULL,
    `mime` varchar(20) COLLATE utf8_danish_ci NOT NULL,
    `added` int(10) unsigned NOT NULL,
    `updated` int(10) unsigned NOT NULL,
    `width` int(10) unsigned NOT NULL,
    `height` int(10) unsigned NOT NULL,
    `checksum` char(32) COLLATE utf8_danish_ci NOT NULL,
    PRIMARY KEY (`id`),
    UNIQUE KEY `image` (`publicKey`,`imageIdentifier`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_danish_ci AUTO_INCREMENT=1 ;

CREATE TABLE IF NOT EXISTS `metadata` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `imageId` int(10) unsigned NOT NULL,
    `tagName` varchar(255) COLLATE utf8_danish_ci NOT NULL,
    `tagValue` varchar(255) COLLATE utf8_danish_ci NOT NULL,
    PRIMARY KEY (`id`),
    KEY `imageId` (`imageId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_danish_ci AUTO_INCREMENT=1 ;

CREATE TABLE IF NOT EXISTS `shorturl` (
    `shortUrlId` char(7) COLLATE utf8_danish_ci NOT NULL,
    `publicKey` varchar(255) COLLATE utf8_danish_ci NOT NULL,
    `imageIdentifier` char(32) COLLATE utf8_danish_ci NOT NULL,
    `extension` char(3) COLLATE utf8_danish_ci DEFAULT NULL,
    `query` text COLLATE utf8_danish_ci NOT NULL,
    PRIMARY KEY (`shortUrlId`),
    KEY `params` (`publicKey`,`imageIdentifier`,`extension`,`query`(255))
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_danish_ci;

CREATE TABLE IF NOT EXISTS `storage_images` (
    `publicKey` varchar(255) COLLATE utf8_danish_ci NOT NULL,
    `imageIdentifier` char(32) COLLATE utf8_danish_ci NOT NULL,
    `data` blob NOT NULL,
    `updated` int(10) unsigned NOT NULL,
    PRIMARY KEY (`publicKey`,`imageIdentifier`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_danish_ci;

The storage_images table is only needed if you plan on storing the actual images in the database as well.

SQLite

CREATE TABLE IF NOT EXISTS imageinfo (
    id INTEGER PRIMARY KEY NOT NULL,
    publicKey TEXT NOT NULL,
    imageIdentifier TEXT NOT NULL,
    size INTEGER NOT NULL,
    extension TEXT NOT NULL,
    mime TEXT NOT NULL,
    added INTEGER NOT NULL,
    updated INTEGER NOT NULL,
    width INTEGER NOT NULL,
    height INTEGER NOT NULL,
    checksum TEXT NOT NULL,
    UNIQUE (publicKey,imageIdentifier)
);

CREATE TABLE IF NOT EXISTS metadata (
    id INTEGER PRIMARY KEY NOT NULL,
    imageId KEY INTEGER NOT NULL,
    tagName TEXT NOT NULL,
    tagValue TEXT NOT NULL
);

CREATE TABLE IF NOT EXISTS shorturl (
    shortUrlId TEXT PRIMARY KEY NOT NULL,
    publicKey TEXT NOT NULL,
    imageIdentifier TEXT NOT NULL,
    extension TEXT,
    query TEXT NOT NULL
);

CREATE INDEX shorturlparams ON shorturl (
    publicKey,
    imageIdentifier,
    extension,
    query
);

CREATE TABLE IF NOT EXISTS storage_images (
    publicKey TEXT NOT NULL,
    imageIdentifier TEXT NOT NULL,
    data BLOB NOT NULL,
    updated INTEGER NOT NULL,
    PRIMARY KEY (publicKey,imageIdentifier)
);

The storage_images table is only needed if you plan on storing the actual images in the database as well.

Read the Docs v: 1.1.1
Versions
latest
develop
1.1.1
1.0.1
0.3.3
Downloads
PDF
HTML
Epub
On Read the Docs
Project Home
Builds

Free document hosting provided by Read the Docs.
PKsNDdUvgvg*imbo-1.1.1/installation/configuration.html Configuration — Imbo 1.1.1 documentation

Configuration

Imbo ships with a default configuration file that will be automatically loaded. You will have to create one or more configuration files of your own that will be automatically merged with the default configuration by Imbo. The location of these files depends on the installation method you choose. You should never have to edit the default configuration file provided by Imbo.

The configuration file(s) you need to create should simply return arrays with configuration data. All available configuration options are covered in this chapter.

Imbo users - auth

Every user that wants to store images in Imbo needs a public and private key pair. These keys are stored in the auth part of your configuration file:

<?php
return array(
    // ...

    'auth' => array(
        'username'  => '95f02d701b8dc19ee7d3710c477fd5f4633cec32087f562264e4975659029af7',
        'otheruser' => 'b312ff29d5da23dcd230b61ff4db1e2515c862b9fb0bb59e7dd54ce1e4e94a53',
    ),

    // ...
);

The public keys can consist of the following characters:

  • a-z (only lowercase is allowed)
  • 0-9
  • _ and -

and must be at least 3 characters long.

For the private keys you can for instance use a SHA-256 hash of a random value. The private key is used by clients to sign requests, and if you accidentally give away your private key users can use it to delete all your images. Make sure not to generate a private key that is easy to guess (like for instance the MD5 or SHA-256 hash of the public key). Imbo does not require the private key to be in a specific format, so you can also use regular passwords if you want. The key itself will never be a part of the payload sent to/from the server.

Imbo ships with a small command line tool that can be used to generate private keys for you using the openssl_random_pseudo_bytes function. The script is located in the scripts directory of the Imbo installation and does not require any arguments:

$ php scripts/generatePrivateKey.php
3b98dde5f67989a878b8b268d82f81f0858d4f1954597cc713ae161cdffcc84a

The private key can be changed whenever you want as long as you remember to change it in both the server configuration and in the client you use. The public key can not be changed easily as database and storage adapters use it when storing/fetching images and metadata.

Database configuration - database

The database adapter you decide to use is responsible for storing metadata and basic image information, like width and height for example, along with the generated short URLs. Imbo ships with some different database adapters that you can use. Remember that you will not be able to switch the adapter whenever you want and expect all data to be automatically transferred. Choosing a database adapter should be a long term commitment unless you have migration scripts available.

In the default configuration file the MongoDB database adapter is used. You can choose to override this in your configuration file by specifying a different adapter. You can either specify an instance of a database adapter directly, or specify a closure that will return an instance of a database adapter when executed. Which database adapter to use is specified in the database key in the configuration array:

<?php
return array(
    // ...

    'database' => function() {
        return new Imbo\Database\MongoDB(array(
            'databaseName' => 'imbo',
        ));
    },

    // or

    'database' => new Imbo\Database\MongoDB(array(
        'databaseName' => 'imbo',
    )),

    // ...
);

Below you will find documentation on the different database adapters Imbo ships with.

Doctrine

This adapter uses the Doctrine Database Abstraction Layer. The options you pass to the constructor of this adapter is passed to the underlying classes, so have a look at the Doctrine DBAL documentation over at doctrine-project.org. When using this adapter you need to create the required tables in the RDBMS first, as specified in the Database setup section.

Examples

Here are some examples on how to use the Doctrine adapter in the configuration file:

  1. Use a PDO instance to connect to a SQLite database:
<?php
return array(
    // ...

    'database' => function() {
        return new Imbo\Database\Doctrine(array(
            'pdo' => new PDO('sqlite:/path/to/database'),
        ));
    },

    // ...
);
  1. Connect to a MySQL database using PDO:
<?php
return array(
    // ...

    'database' => function() {
        return new Imbo\Database\Doctrine(array(
            'dbname'   => 'database',
            'user'     => 'username',
            'password' => 'password',
            'host'     => 'hostname',
            'driver'   => 'pdo_mysql',
        ));
    },

    // ...
);

MongoDB

This adapter uses PHP’s mongo extension to store data in MongoDB. The following parameters are supported:

databaseName
Name of the database to use. Defaults to imbo.
server
The server string to use when connecting. Defaults to mongodb://localhost:27017.
options
Options passed to the underlying adapter. Defaults to array('connect' => true, 'timeout' => 1000). See the manual for the MongoClient constructor for available options.

Examples

  1. Connect to a local MongoDB instance using the default databaseName:
<?php
return array(
    // ...

    'database' => function() {
        return new Imbo\Database\MongoDB();
    },

    // ...
);
  1. Connect to a replica set:
<?php
return array(
    // ...

    'database' => function() {
        return new Imbo\Database\MongoDB(array(
            'server' => 'mongodb://server1,server2,server3',
            'options' => array(
                'replicaSet' => 'nameOfReplicaSet',
            ),
        ));
    },

    // ...
);

Custom database adapter

If you need to create your own database adapter you need to create a class that implements the Imbo\Database\DatabaseInterface interface, and then specify that adapter in the configuration:

<?php
return array(
    // ...

    'database' => function() {
        return new My\Custom\Adapter(array(
            'some' => 'option',
        ));
    },

    // ...
);

You can read more about how to achieve this in the Implement your own database and/or storage adapter chapter.

Storage configuration - storage

Storage adapters are responsible for storing the original images you put into Imbo. As with the database adapter it is not possible to simply switch the adapter without having migration scripts available to move the stored images. Choose an adapter with care.

In the default configuration file the GridFS storage adapter is used. You can choose to override this in your configuration file by specifying a different adapter. You can either specify an instance of a storage adapter directly, or specify a closure that will return an instance of a storage adapter when executed. Which storage adapter to use is specified in the storage key in the configuration array:

<?php
return array(
    // ...

    'storage' => function() {
        return new Imbo\Storage\Filesystem(array(
            'dataDir' => '/path/to/images',
        ));
    },

    // or

    'storage' => new Imbo\Storage\Filesystem(array(
        'dataDir' => '/path/to/images',
    )),

    // ...
);

Below you will find documentation on the different storage adapters Imbo ships with.

Amazon Simple Storage Service

This adapter stores your images in a bucket in the Amazon Simple Storage Service (S3). The parameters are:

key
Your AWS access key
secret
Your AWS secret key
bucket
The name of the bucket you want to store your images in. Imbo will not create this for you.

This adapter creates subdirectories in the bucket in the same fashion as the Filesystem storage adapter stores the files on the local filesystem.

Examples

<?php
return array(
    // ...

    'storage' => function() {
        new Imbo\Storage\S3(array(
            'key' => '<aws access key>'
            'secret' => '<aws secret key>',
            'bucket' => 'my-imbo-bucket',
        ));
    },

    // ...
);

Doctrine

This adapter uses the Doctrine Database Abstraction Layer. The options you pass to the constructor of this adapter is passed to the underlying classes, so have a look at the Doctrine DBAL documentation over at doctrine-project.org. When using this adapter you need to create the required tables in the RDBMS first, as specified in the Database setup section.

Examples

Here are some examples on how to use the Doctrine adapter in the configuration file:

  1. Use a PDO instance to connect to a SQLite database:
<?php
return array(
    // ...

    'storage' => function() {
        return new Imbo\Storage\Doctrine(array(
            'pdo' => new PDO('sqlite:/path/to/database'),
        ));
    },

    // ...
);
  1. Connect to a MySQL database using PDO:
<?php
return array(
    // ...

    'storage' => function() {
        return new Imbo\Storage\Doctrine(array(
            'dbname'   => 'database',
            'user'     => 'username',
            'password' => 'password',
            'host'     => 'hostname',
            'driver'   => 'pdo_mysql',
        ));
    },

    // ...
);

Filesystem

This adapter simply stores all images on the file system. It has a single parameter, and that is the base directory of where you want your images stored:

dataDir
The base path where the images are stored.

This adapter is configured to create subdirectories inside of dataDir based on the public key of the user and the checksum of the images added to Imbo. The algorithm that generates the path simply takes the three first characters of the public key and creates directories for each of them, then the full public key, then a directory of each of the first characters in the image identifier, and lastly it stores the image in a file with a filename equal to the image identifier itself.

Examples

  1. Store images in /path/to/images:
<?php
return array(
    // ...

    'storage' => function() {
        new Imbo\Storage\Filesystem(array(
            'dataDir' => '/path/to/images',
        ));
    },

    // ...
);

GridFS

The GridFS adapter is used to store the images in MongoDB using the GridFS specification. This adapter has the following parameters:

databaseName
The name of the database to store the images in. Defaults to imbo_storage.
server
The server string to use when connecting to MongoDB. Defaults to mongodb://localhost:27017
options
Options passed to the underlying adapter. Defaults to array('connect' => true, 'timeout' => 1000). See the manual for the MongoClient constructor for available options.

Examples

  1. Connect to a local MongoDB instance using the default databaseName:
<?php
return array(
    // ...

    'storage' => function() {
        return new Imbo\Storage\GridFS();
    },

    // ...
);
  1. Connect to a replica set:
<?php
return array(
    // ...

    'storage' => function() {
        return new Imbo\Storage\GridFS(array(
            'server' => 'mongodb://server1,server2,server3',
            'options' => array(
                'replicaSet' => 'nameOfReplicaSet',
            ),
        ));
    },

    // ...
);

Custom storage adapter

If you need to create your own storage adapter you need to create a class that implements the Imbo\Storage\StorageInterface interface, and then specify that adapter in the configuration:

<?php
return array(
    // ...

    'storage' => function() {
        return new My\Custom\Adapter(array(
            'some' => 'option',
        ));
    },

    // ...
);

You can read more about how to achieve this in the Implement your own database and/or storage adapter chapter.

Event listeners - eventListeners

Imbo support event listeners that you can use to hook into Imbo at different phases without having to edit Imbo itself. An event listener is simply a piece of code that will be executed when a certain event is triggered from Imbo. Event listeners are added to the eventListeners part of the configuration array as associative arrays. If you want to disable some of the default event listeners simply specify the same key in your configuration file and set the value to null or false. Keep in mind that not all event listeners should be disabled.

Event listeners can be configured in the following ways:

  1. A string representing a class name of a class implementing the Imbo\EventListener\ListenerInteface interface:
<?php
return array(
    // ...

    'eventListeners' => array(
        'accessToken' => 'Imbo\EventListener\AccessToken',
    ),

    // ...
);
  1. Use an instance of a class implementing the Imbo\EventListener\ListenerInterface interface:
<?php
return array(
    // ...

    'eventListeners' => array(
        'accessToken' => new Imbo\EventListener\AccessToken(),
    ),

    // ...
);
  1. A closure returning an instance of a class implementing the Imbo\EventListener\ListenerInterface interface:
<?php
return array(
    // ...

    'eventListeners' => array(
        'accessToken' => function() {
            return new Imbo\EventListener\AccessToken();
        },
    ),

    // ...
);
  1. Use a class implementing the Imbo\EventListener\ListenerInterface interface together with an optional public key filter:
<?php
return array(
    // ...

    'eventListeners' => array(
        'maxImageSize' => array(
            'listener' => new Imbo\EventListener\MaxImageSize(1024, 768),
            'publicKeys' => array(
                'whitelist' => array('user'),
                // 'blacklist' => array('someotheruser'),
            ),
            // 'params' => array( ... )
        ),
    ),

    // ...
);

where listener is one of the following:

  1. a string representing a class name of a class implementing the Imbo\EventListener\ListenerInterface interface
  2. an instance of the Imbo\EventListener\ListenerInterface interface
  3. a closure returning an instance Imbo\EventListener\ListenerInterface

The publicKeys element is an array that you can use if you want your listener to only be triggered for some users (public keys). The value of this is an array with two elements, whitelist and blacklist, where whitelist is an array of public keys you want your listener to trigger for, and blacklist is an array of public keys you don’t want your listener to trigger for. publicKeys is optional, and per default the listener will trigger for all users.

There also exists a params key that can be used to specify parameters for the event listener, if you choose to specify the listener as a string in the listener key:

<?php
return array(
    // ...

    'eventListeners' => array(
        'maxImageSize' => array(
            'listener' => 'Imbo\EventListener\MaxImageSize',
            'publicKeys' => array(
                'whitelist' => array('user'),
                // 'blacklist' => array('someotheruser'),
            ),
            'params' => array(
                'width' => 1024,
                'height' => 768,
            )
        ),
    ),

    // ...
);

The value of the params array will be sent to the constructor of the event listener class.

  1. Use a closure directly:
<?php
return array(
    // ...

    'eventListeners' => array(
        'customListener' => array(
            'callback' => function(Imbo\EventManager\EventInterface $event) {
                // Custom code
            },
            'events' => array('image.get'),
            'priority' => 1,
            'publicKeys' => array(
                'whitelist' => array('user'),
                // 'blacklist' => array('someotheruser'),
            ),
        ),
    ),

    // ...
);

where callback is the code you want executed, and events is an array of the events you want it triggered for. priority is the priority of the listener and defaults to 0. The higher the number, the earlier in the chain your listener will be triggered. This number can also be negative. Imbo’s internal event listeners uses numbers between 0 and 100. publicKeys uses the same format as described above. If you use this method, and want your callback to trigger for multiple events with different priorities, specify an associative array in the events element, where the keys are the event names, and the values are the priorities for the different events. This way of attaching event listeners should mostly be used for quick and temporary solutions.

All event listeners will receive an event object (which implements Imbo\EventManager\EventInterface), that is described in detail in the The event object section.

Listeners added by default

The default configuration file includes some event listeners by default:

as well as event listeners for image transformations:

Read more about these listeners (and more) in the Customize your Imbo installation with event listeners and Transforming images on the fly chapters. If you want to disable any of these you could do so in your configuration file in the following way:

<?php
return array(
    // ...

    'eventListeners' => array(
        'accessToken' => null,
        'auth' => null,
        'statsAccess' => null,
    ),

    // ...
);

Warning

Do not disable the event listeners used in the example above unless you are absolutely sure about the consequences. Your images can potentially be deleted by anyone.

Warning

Disabling image transformation event listeners is not recommended.

Event listener initializers - eventListenerInitializers

Some event listeners might require custom initialization, and if you don’t want to do this in-line in the configuration, Imbo supports event listener initializer classes. This is handled via the eventListenerInitializers key. The value of this element is an associative array where the keys identify the initializers (only used in the configuration itself), and the values are strings representing class names, or implementations of the Imbo\EventListener\Initializer\InitializerInterface interface. If you specify strings the classes you refer to must also implement this interface.

The interface has a single method called initialize and receives instances of event listeners implementing the Imbo\EventListener\ListenerInterface interface. This method is called once for each event listener instantiated by Imbo’s event manager. Example:

<?php
// Some event listener
class Listener implements Imbo\EventListener\ListenerInterface {
    public function setDependency($dependency) {
        // ...
    }

    // ...
}

class OtherListener implements Imbo\EventListener\ListenerInterface {
    public function setDependency($dependency) {
        // ...
    }

    // ...
}

// Event listener initializer
class Initializer implements Imbo\EventListener\Initializer\InitializerInterface {
    private $dependency;

    public function __construct() {
        $this->dependency = new SomeDependency();
    }

    public function initialize(Imbo\EventListener\ListenerInterface $listener) {
        if ($listener instanceof Listener || $listener instanceof OtherListener) {
            $listener->setDependency($this->dependency);
        }
    }
}

// Configuration
return array(
    'eventListeners' => array(
        'customListener' => 'Listener',
        'otherCustomListener' => 'OtherListener',
    ),

    'eventListenerInitializers' => array(
        'initializerForCustomListener' => 'Initializer',
    ),
);

In the above example the Initializer class will be instantiated by Imbo, and in the __construct method it will create an instance of some dependency. When the event manager creates the instances of the two event listeners these will in turn be sent to the initialize method, and the same dependency will be injected into both listeners. An alternative way to accomplish this by using Closures in the configuration could look something like this:

<?php
$dependency = new SomeDependency();

return array(
    'eventListeners' => array(
        'customListener' => function() use ($dependency) {
            $listener = new Listener();
            $listener->setDependency($dependency);

            return $listener;
        },
        'otherCustomListener' => function() use ($dependency) {
            $listener = new OtherListener();
            $listener->setDependency($dependency);

            return $listener;
        },
    ),
);

Imbo itself includes an event listener initializer in the default configuration that is used to inject the same instance of Imagick to all image transformations.

Note

Only event listeners specified as strings (class names) in the configuration will be instantiated by Imbo, so event listeners instantiated in the configuration array, either directly or via a Closures, will not be initialized by the configured event listener initializers.

Image transformation presets - transformationPresets

Through the configuration you can also combine image transformations to make presets (transformation chains). This is done via the transformationPresets key:

<?php
return array(
    // ...

    'transformationPresets' => array(
        'graythumb' => array(
            'thumbnail',
            'desaturate',
        ),
        // ...
    ),

    // ...
);

where the keys are the names of the transformations as specified in the URL, and the values are arrays containing other transformation names (as used in the eventListeners part of the configuration). You can also specify hard coded parameters for the presets if some of the transformations in the chain supports parameters:

<?php
return array(
    // ...

    'transformationPresets' => array(
        'fixedGraythumb' => array(
            'thumbnail' => array(
                'width' => 50,
                'height' => 50,
            ),
            'desaturate',
        ),
        // ...
    ),

    // ...
);

By doing this the thumbnail part of the fixedGraythumb preset will ignore the width and height query parameters, if present. By only specifying for instance 'width' => 50 in the configuration the height of the thumbnail can be adjusted via the query parameter, but the width is fixed.

Note

The URL’s will stay the same if you change the transformation chain in a preset. Keep this in mind if you use for instance Varnish or some other HTTP accelerator in front of your web server(s).

Custom resources and routes - resources and routes

Warning

Custom resources and routes is an experimental and advanced way of extending Imbo, and requires extensive knowledge of how Imbo works internally. This feature can potentially be removed in future releases, so only use this for testing purposes.

If you need to create a custom route you can attach a route and a custom resource class using the configuration. Two keys exists for this purpose: resources and routes:

<?php
return array(
    // ...

    'resources' => array(
        'users' => new ImboUsers();

        // or

        'users' => function() {
            return new ImboUsers();
        },

        // or

        'users' => 'ImboUsers',
    ),

    'routes' => array(
        'users' => '#^/users(\.(?<extension>json|xml))?$#',
    ),

    // ...
);

In the above example we are creating a route for Imbo using a regular expression, called users. The route itself will match the following three requests:

  • /users
  • /users.json
  • /users.xml

When a request is made against any of these endpoints Imbo will try to access a resource that is specified with the same key (users). The value specified for this entry in the resources array can be:

  1. a string representing the name of the resource class
  2. an instance of a resource class
  3. an anonymous function that, when executed, returns an instance of a resource class

The resource class must implement the Imbo\Resource\ResourceInterface interface to be able to response to a request.

Below is an example implementation of the ImboUsers resource used in the above configuration:

<?php
use Imbo\Resource\ResourceInterface,
    Imbo\EventManager\EventInterface,
    Imbo\Model\ListModel;

class ImboUsers implements ResourceInterface {
    public function getAllowedMethods() {
        return array('GET');
    }

    public static function getSubscribedEvents() {
        return array(
            'users.get' => 'get',
        );
    }

    public function get(EventInterface $event) {
        $model = new ListModel();
        $model->setList('users', 'user', array_keys($event->getConfig()['auth']));
        $event->getResponse()->setModel($model);
    }
}

This resource informs Imbo that it supports HTTP GET, and specifies a callback for the users.get event. The name of the event is the name specified for the resource in the configuration above, along with the HTTP method, separated with a dot.

In the get() method we are simply creating a list model for Imbo’s response formatter, and we are supplying the keys from the auth part of your configuration file as data. When formatted as JSON the response looks like this:

{
  "users": [
    "someuser",
    "someotheruser"
  ]
}

and the XML representation looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<imbo>
  <users>
    <user>someuser</user>
    <user>someotheruser</user>
  </users>
</imbo>

Feel free to experiment with this feature. If you end up creating a resource that you think should be a part of Imbo, send a pull request on GitHub.

Read the Docs v: 1.1.1
Versions
latest
develop
1.1.1
1.0.1
0.3.3
Downloads
PDF
HTML
Epub
On Read the Docs
Project Home
Builds

Free document hosting provided by Read the Docs.
PKsND5 =O=O)imbo-1.1.1/installation/requirements.html Requirements — Imbo 1.1.1 documentation

Requirements

Imbo requires a web server (for instance Apache, Nginx or Lighttpd) running PHP >= 5.4 and the Imagick extension for PHP.

You will also need a backend for storing image information, like for instance MongoDB or MySQL. If you want to use MongoDB as a database and/or GridFS for storage, you will need to install the Mongo PECL extension, and if you want to use a RDBMS like MySQL, you will need to install the Doctrine Database Abstraction Layer.

Read the Docs v: 1.1.1
Versions
latest
develop
1.1.1
1.0.1
0.3.3
Downloads
PDF
HTML
Epub
On Read the Docs
Project Home
Builds

Free document hosting provided by Read the Docs.
PKsNDl7m,imbo-1.1.1/installation/event_listeners.html Customize your Imbo installation with event listeners — Imbo 1.1.1 documentation

Customize your Imbo installation with event listeners

Imbo ships with a collection of event listeners for you to use. Some of them are enabled in the default configuration file. Image transformations are also technically event listeners, but will not be covered in this chapter. Read the Transforming images on the fly chapter for more information regarding the image transformations.

Access token

This event listener enforces the usage of access tokens on all read requests against user-specific resources. You can read more about how the actual access tokens work in the Access tokens part of the Imbo’s API chapter.

To enforce the access token check this event listener subscribes to the following events:

  • user.get
  • user.head
  • images.get
  • images.head
  • image.get
  • image.head
  • metadata.get
  • metadata.head

This event listener has a single parameter that can be used to whitelist and/or blacklist certain image transformations, used when the current request is against an image resource. The parameter is an array with a single key: transformations. This is another array with two keys: whitelist and blacklist. These two values are arrays where you specify which transformation(s) to whitelist or blacklist. The names of the transformations are the same as the ones used in the request. See Transforming images on the fly for a complete list of the supported transformations.

Use whitelist if you want the listener to skip the access token check for certain transformations, and blacklist if you want it to only check certain transformations:

array(
    'transformations' => array(
        'whitelist' => array(
            'border',
        ),
    ),
)

means that the access token will not be enforced for the border transformation.

array(
    'transformations' => array(
        'blacklist' => array(
            'border',
        ),
    ),
)

means that the access token will be enforced only for the border transformation.

If both whitelist and blacklist are specified all transformations will require an access token unless it’s included in whitelist.

This event listener is included in the default configuration file without specifying any transformation filters:

<?php
return array(
    // ...

    'eventListeners' => array(
        'accessToken' => 'Imbo\EventListener\AccessToken',
    ),

    // ...
);

Disable this event listener with care. Installations with no access token check is open for DoS attacks.

Authenticate

This event listener enforces the usage of signatures on all write requests against user-specific resources. You can read more about how the actual signature check works in the Signing write requests section in the Imbo’s API chapter.

To enforce the signature check for all write requests supported by Imbo this event listener subscribes to the following events:

  • images.post
  • image.delete
  • metadata.put
  • metadata.post
  • metadata.delete

This event listener does not support any parameters and is enabled per default like this:

<?php
return array(
    // ...

    'eventListeners' => array(
        'authenticate' => 'Imbo\EventListener\Authenticate',
    ),

    // ...
);

Disable this event listener with care. User agents can delete all your images and metadata if this listener is disabled.

Auto rotate image

This event listener will auto rotate new images based on metadata embedded in the image itself (EXIF).

The listener does not support any parameters and can be enabled like this:

<?php
return array(
    // ...

    'eventListeners' => array(
        'autoRotateListener' => 'Imbo\EventListener\AutoRotateImage',
    ),

    // ...
);

If you enable this listener all new images added to Imbo will be auto rotated based on the EXIF data. This might also cause the image identifier sent in the response to be different from the one used in the URI when storing the image. This can happen with all event listeners which can possibly modify the image before storing it.

CORS (Cross-Origin Resource Sharing)

This event listener can be used to allow clients such as web browsers to use Imbo when the client is located on a different origin/domain than the Imbo server is. This is implemented by sending a set of CORS-headers on specific requests, if the origin of the request matches a configured domain.

The event listener can be configured on a per-resource and per-method basis, and will therefore listen to any related events. If enabled without any specific configuration, the listener will allow and respond to the GET, HEAD and OPTIONS methods on all resources. Note however that no origins are allowed by default and that a client will still need to provide a valid access token, unless the Access token listener is disabled.

Here is an example on how to enable the CORS listener:

<?php
return array(
    // ...

    'eventListeners' => array(
        'cors' => array(
            'listener' => 'Imbo\EventListener\Cors',
            'params' => array(
                'allowedOrigins' => array('http://some.origin'),
                'allowedMethods' => array(
                    'image'  => array('GET', 'HEAD'),
                    'images' => array('GET', 'HEAD', 'POST'),
                ),
                'maxAge' => 3600,
            ),
        ),
    ),

    // ...
);

Below all supported parameters are listed:

allowedOrigins
is an array of allowed origins. Specifying * as a value in the array will allow any origin.
allowedMethods
is an associative array where the keys represent the resource (shorturl, status, stats, user, images, image and metadata) and the values are arrays of HTTP methods you wish to open up.
maxAge
specifies how long the response of an OPTIONS-request can be cached for, in seconds. Defaults to 3600 (one hour).

EXIF metadata

This event listener can be used to fetch the EXIF-tags from uploaded images and adding them as metadata. Enabling this event listener will not populate metadata for images already added to Imbo.

The event listener subscribes to the following events:

  • images.post
  • db.image.insert

and the parameters given to the event listener supports a single element:

allowedTags
The tags you want to be populated as metadata. Defaults to exif:*. When specified it will override the default value, so if you want to register all exif and date tags for example, you will need to specify them both.

and is enabled like this:

<?php
return array(
    // ...

    'eventListeners' => array(
        'exifMetadata' => array(
            'listener' => 'Imbo\EventListener\ExifMetadata',
            'params' => array(
                'allowedTags' => array('exif:*', 'date:*', 'png:gAMA'),
            ),
        ),
    ),

    // ...
);

which would allow all exif and date properties as well as the png:gAMA property. If you want to store all tags as metadata, use array('*') as filter.

Image transformation cache

This event listener enables caching of image transformations. Read more about image transformations in the Transforming images on the fly section.

To achieve this the listener subscribes to the following events:

  • image.get
  • response.send
  • image.delete

The parameters for the event listener supports a single element:

path
Root path where the cached images will be stored.

and is enabled like this:

<?php
return array(
    // ...

    'eventListeners' => array(
        'imageTransformationCache' => array(
            'listener' => 'Imbo\EventListener\ImageTransformationCache',
            'params' => array(
                'path' => '/path/to/cache',
            ),
        ),
    ),

    // ...
);

Note

This event listener uses a similar algorithm when generating file names as the Filesystem storage adapter.

Warning

It can be wise to purge old files from the cache from time to time. If you have a large amount of images and present many different variations of these the cache will use up quite a lot of storage.

An example on how to accomplish this:

$ find /path/to/cache -ctime +7 -type f -delete

The above command will delete all files in /path/to/cache older than 7 days and can be used with for instance crontab.

Imagick

This event listener is required by the image transformations that is included in Imbo, and there is no configuration options for it. Unless you plan on exchanging all the internal image transformations with your own (for instance implemented using Gmagick or GD) you are better off leaving this as-is.

Max image size

This event listener can be used to enforce a maximum size (height and width, not byte size) of new images. Enabling this event listener will not change images already added to Imbo.

The event listener subscribes to the following event:

  • images.post

and the parameters includes the following elements:

width
The max width in pixels of new images. If a new image exceeds this limit it will be downsized.
height
The max height in pixels of new images. If a new image exceeds this limit it will be downsized.

and is enabled like this:

<?php
return array(
    // ...

    'eventListeners' => array(
        'maxImageSizeListener' => array(
            'listener' => 'Imbo\EventListener\MaxImageSize',
            'params' => array(
                'width' => 1024,
                'height' => 768,
            ),
        ),
    ),

    // ...
);

which would effectively downsize all images exceeding a width of 1024 or a height of 768. The aspect ratio will be kept.

Metadata cache

This event listener enables caching of metadata fetched from the backend so other requests won’t need to go all the way to the metadata backend to fetch it. To achieve this the listener subscribes to the following events:

  • db.metadata.load
  • db.metadata.delete
  • db.metadata.update
  • db.image.delete

and the parameters supports a single element:

cache
An instance of a cache adapter. Imbo ships with APC and Memcached adapters, and both can be used for this event listener. If you want to use another form of caching you can simply implement the Imbo\Cache\CacheInterface interface and pass an instance of the custom adapter to the constructor of the event listener. See the Implement a custom cache adapter section for more information regarding this. Here is an example that uses the APC adapter for caching:
<?php
return array(
    // ...

    'eventListeners' => array(
        'metadataCache' => array(
            'listener' => 'Imbo\EventListener\MetadataCache',
            'params' => array(
                'cache' => new Imbo\Cache\APC('imbo'),
            ),
        ),
    ),

    // ...
);

Stats access

This event listener controls the access to the stats resource by using white listing of IPv4 and/or IPv6 addresses. CIDR-notations are also supported.

This listener is enabled per default, and only allows 127.0.0.1 and ::1 to access the statistics:

<?php
return array(
    // ...

    'eventListeners' => array(
        'statsAccess' => array(
            'listener' => 'Imbo\EventListener\StatsAccess',
            'params' => array(
                'allow' => array('127.0.0.1', '::1'),
            ),
        ),
    ),

    // ...
);

The event listener also supports a notation for “allowing all”, simply by placing '*' somewhere in the list:

<?php
return array(
    // ...

    'eventListeners' => array(
        'statsAccess' => array(
            'listener' => 'Imbo\EventListener\StatsAccess',
            'params' => array(
                array(
                    'allow' => array('*'),
                )
            ),
        ),
    ),

    // ...
);

The above example will allow all clients access to the statistics.

Varnish HashTwo

This event listener can be enabled if you want Imbo to include HashTwo headers in responses to image requests. These headers can be used by Varnish for more effective cache invalidation strategies. The listener, when enabled, subscribes to the following events:

  • image.get
  • image.head

The parameters supports a single element:

headerName
Set the header name to use. Defaults to X-HashTwo.
<?php
return array(
    // ...

    'eventListeners' => array(
        'hashTwo' => 'Imbo\EventListener\VarnishHashTwo',
    ),

    // ...
);

or, if you want to use a non-default header name:

<?php
return array(
    // ...

    'eventListeners' => array(
        'hashTwo' => array(
            'listener' => 'Imbo\EventListener\VarnishHashTwo',
            'params' => array(
                'headerName' => 'X-Custom-HashTwo-Header-Name',
            ),
        ),
    ),

    // ...
);

The header appears multiple times in the response, with slightly different values:

X-HashTwo: imbo;image;<publicKey>;<imageIdentifier>
X-HashTwo: imbo;user;<publicKey>
Read the Docs v: 1.1.1
Versions
latest
develop
1.1.1
1.0.1
0.3.3
Downloads
PDF
HTML
Epub
On Read the Docs
Project Home
Builds

Free document hosting provided by Read the Docs.
PKHNDaimbo-1.1.1/_static/plus.pngPNG  IHDR &q pHYs  tIME 1l9tEXtComment̖RIDATcz(BpipPc |IENDB`PKtND$zRRimbo-1.1.1/_static/pygments.css.highlight .hll { background-color: #ffffcc } .highlight { background: #ffffff; }PKHNDDUkkimbo-1.1.1/_static/up.pngPNG  IHDRasRGBbKGDC pHYs B(xtIME!.<̓EIDAT8͓NABP\EG{%<|xc  cr6@t;b$;3&)h1!﫳Hzz@=)p 3۵e2/ߴ ( %^ND^ }3H1DoǪISFұ?, G`{v^X[b]&HC3{:sO& ?,[eL#IENDB`PKFEDVR>>imbo-1.1.1/_static/rtd.css/* * rtd.css * ~~~~~~~~~~~~~~~ * * Sphinx stylesheet -- sphinxdoc theme. Originally created by * Armin Ronacher for Werkzeug. * * Customized for ReadTheDocs by Eric Pierce & Eric Holscher * * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ /* RTD colors * light blue: #e8ecef * medium blue: #8ca1af * dark blue: #465158 * dark grey: #444444 * * white hover: #d1d9df; * medium blue hover: #697983; * green highlight: #8ecc4c * light blue (project bar): #e8ecef */ @import url("basic.css"); /* PAGE LAYOUT -------------------------------------------------------------- */ body { font: 100%/1.5 "ff-meta-web-pro-1","ff-meta-web-pro-2",Arial,"Helvetica Neue",sans-serif; text-align: center; color: black; background-color: #465158; padding: 0; margin: 0; } div.document { text-align: left; background-color: #e8ecef; } div.bodywrapper { background-color: #ffffff; border-left: 1px solid #ccc; border-bottom: 1px solid #ccc; margin: 0 0 0 16em; } div.body { margin: 0; padding: 0.5em 1.3em; min-width: 20em; } div.related { font-size: 1em; background-color: #465158; } div.documentwrapper { float: left; width: 100%; background-color: #e8ecef; } /* HEADINGS --------------------------------------------------------------- */ h1 { margin: 0; padding: 0.7em 0 0.3em 0; font-size: 1.5em; line-height: 1.15; color: #111; clear: both; } h2 { margin: 2em 0 0.2em 0; font-size: 1.35em; padding: 0; color: #465158; } h3 { margin: 1em 0 -0.3em 0; font-size: 1.2em; color: #6c818f; } div.body h1 a, div.body h2 a, div.body h3 a, div.body h4 a, div.body h5 a, div.body h6 a { color: black; } h1 a.anchor, h2 a.anchor, h3 a.anchor, h4 a.anchor, h5 a.anchor, h6 a.anchor { display: none; margin: 0 0 0 0.3em; padding: 0 0.2em 0 0.2em; color: #aaa !important; } h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, h5:hover a.anchor, h6:hover a.anchor { display: inline; } h1 a.anchor:hover, h2 a.anchor:hover, h3 a.anchor:hover, h4 a.anchor:hover, h5 a.anchor:hover, h6 a.anchor:hover { color: #777; background-color: #eee; } /* LINKS ------------------------------------------------------------------ */ /* Normal links get a pseudo-underline */ a { color: #444; text-decoration: none; border-bottom: 1px solid #ccc; } /* Links in sidebar, TOC, index trees and tables have no underline */ .sphinxsidebar a, .toctree-wrapper a, .indextable a, #indices-and-tables a { color: #444; text-decoration: none; /* border-bottom: none; */ } /* Search box size */ div.sphinxsidebar #searchbox input[type="submit"] { width: 50px; } /* Most links get an underline-effect when hovered */ a:hover, div.toctree-wrapper a:hover, .indextable a:hover, #indices-and-tables a:hover { color: #111; text-decoration: none; border-bottom: 1px solid #111; } /* Footer links */ div.footer a { color: #86989B; text-decoration: none; border: none; } div.footer a:hover { color: #a6b8bb; text-decoration: underline; border: none; } /* Permalink anchor (subtle grey with a red hover) */ div.body a.headerlink { color: #ccc; font-size: 1em; margin-left: 6px; padding: 0 4px 0 4px; text-decoration: none; border: none; } div.body a.headerlink:hover { color: #c60f0f; border: none; } /* NAVIGATION BAR --------------------------------------------------------- */ div.related ul { height: 2.5em; } div.related ul li { margin: 0; padding: 0.65em 0; float: left; display: block; color: white; /* For the >> separators */ font-size: 0.8em; } div.related ul li.right { float: right; margin-right: 5px; color: transparent; /* Hide the | separators */ } /* "Breadcrumb" links in nav bar */ div.related ul li a { order: none; background-color: inherit; font-weight: bold; margin: 6px 0 6px 4px; line-height: 1.75em; color: #ffffff; padding: 0.4em 0.8em; border: none; border-radius: 3px; } /* previous / next / modules / index links look more like buttons */ div.related ul li.right a { margin: 0.375em 0; background-color: #697983; text-shadow: 0 1px rgba(0, 0, 0, 0.5); border-radius: 3px; -webkit-border-radius: 3px; -moz-border-radius: 3px; } /* All navbar links light up as buttons when hovered */ div.related ul li a:hover { background-color: #8ca1af; color: #ffffff; text-decoration: none; border-radius: 3px; -webkit-border-radius: 3px; -moz-border-radius: 3px; } /* Take extra precautions for tt within links */ a tt, div.related ul li a tt { background: inherit !important; color: inherit !important; } /* SIDEBAR ---------------------------------------------------------------- */ div.sphinxsidebarwrapper { padding: 0; } div.sphinxsidebar { margin: 0; margin-left: -100%; float: left; top: 3em; left: 0; padding: 0 1em; width: 14em; font-size: 1em; text-align: left; background-color: #e8ecef; } div.sphinxsidebar img { max-width: 12em; } div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p.logo { margin: 1.2em 0 0.3em 0; font-size: 1em; padding: 0; color: #222222; font-family: "ff-meta-web-pro-1", "ff-meta-web-pro-2", "Arial", "Helvetica Neue", sans-serif; } div.sphinxsidebar h3 a { color: #444444; } div.sphinxsidebar ul, div.sphinxsidebar p { margin-top: 0; padding-left: 0; line-height: 130%; background-color: #e8ecef; } /* No bullets for nested lists, but a little extra indentation */ div.sphinxsidebar ul ul { list-style-type: none; margin-left: 1.5em; padding: 0; } /* A little top/bottom padding to prevent adjacent links' borders * from overlapping each other */ div.sphinxsidebar ul li { padding: 1px 0; } /* A little left-padding to make these align with the ULs */ div.sphinxsidebar p.topless { padding-left: 0 0 0 1em; } /* Make these into hidden one-liners */ div.sphinxsidebar ul li, div.sphinxsidebar p.topless { white-space: nowrap; overflow: hidden; } /* ...which become visible when hovered */ div.sphinxsidebar ul li:hover, div.sphinxsidebar p.topless:hover { overflow: visible; } /* Search text box and "Go" button */ #searchbox { margin-top: 2em; margin-bottom: 1em; background: #ddd; padding: 0.5em; border-radius: 6px; -moz-border-radius: 6px; -webkit-border-radius: 6px; } #searchbox h3 { margin-top: 0; } /* Make search box and button abut and have a border */ input, div.sphinxsidebar input { border: 1px solid #999; float: left; } /* Search textbox */ input[type="text"] { margin: 0; padding: 0 3px; height: 20px; width: 144px; border-top-left-radius: 3px; border-bottom-left-radius: 3px; -moz-border-radius-topleft: 3px; -moz-border-radius-bottomleft: 3px; -webkit-border-top-left-radius: 3px; -webkit-border-bottom-left-radius: 3px; } /* Search button */ input[type="submit"] { margin: 0 0 0 -1px; /* -1px prevents a double-border with textbox */ height: 22px; color: #444; background-color: #e8ecef; padding: 1px 4px; font-weight: bold; border-top-right-radius: 3px; border-bottom-right-radius: 3px; -moz-border-radius-topright: 3px; -moz-border-radius-bottomright: 3px; -webkit-border-top-right-radius: 3px; -webkit-border-bottom-right-radius: 3px; } input[type="submit"]:hover { color: #ffffff; background-color: #8ecc4c; } div.sphinxsidebar p.searchtip { clear: both; padding: 0.5em 0 0 0; background: #ddd; color: #666; font-size: 0.9em; } /* Sidebar links are unusual */ div.sphinxsidebar li a, div.sphinxsidebar p a { background: #e8ecef; /* In case links overlap main content */ border-radius: 3px; -moz-border-radius: 3px; -webkit-border-radius: 3px; border: 1px solid transparent; /* To prevent things jumping around on hover */ padding: 0 5px 0 5px; } div.sphinxsidebar li a:hover, div.sphinxsidebar p a:hover { color: #111; text-decoration: none; border: 1px solid #888; } div.sphinxsidebar p.logo a { border: 0; } /* Tweak any link appearing in a heading */ div.sphinxsidebar h3 a { } /* OTHER STUFF ------------------------------------------------------------ */ cite, code, tt { font-family: 'Consolas', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace; font-size: 0.95em; letter-spacing: 0.01em; } tt { background-color: #f2f2f2; color: #444; } tt.descname, tt.descclassname, tt.xref { border: 0; } hr { border: 1px solid #abc; margin: 2em; } pre, #_fontwidthtest { font-family: 'Consolas', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace; margin: 1em 2em; font-size: 0.95em; letter-spacing: 0.015em; line-height: 120%; padding: 0.5em; border: 1px solid #ccc; background-color: #eee; border-radius: 6px; -moz-border-radius: 6px; -webkit-border-radius: 6px; } pre a { color: inherit; text-decoration: underline; } td.linenos pre { margin: 1em 0em; } td.code pre { margin: 1em 0em; } div.quotebar { background-color: #f8f8f8; max-width: 250px; float: right; padding: 2px 7px; border: 1px solid #ccc; } div.topic { background-color: #f8f8f8; } table { border-collapse: collapse; margin: 0 -0.5em 0 -0.5em; } table td, table th { padding: 0.2em 0.5em 0.2em 0.5em; } /* ADMONITIONS AND WARNINGS ------------------------------------------------- */ /* Shared by admonitions, warnings and sidebars */ div.admonition, div.warning, div.sidebar { font-size: 0.9em; margin: 2em; padding: 0; /* border-radius: 6px; -moz-border-radius: 6px; -webkit-border-radius: 6px; */ } div.admonition p, div.warning p, div.sidebar p { margin: 0.5em 1em 0.5em 1em; padding: 0; } div.admonition pre, div.warning pre, div.sidebar pre { margin: 0.4em 1em 0.4em 1em; } div.admonition p.admonition-title, div.warning p.admonition-title, div.sidebar p.sidebar-title { margin: 0; padding: 0.1em 0 0.1em 0.5em; color: white; font-weight: bold; font-size: 1.1em; text-shadow: 0 1px rgba(0, 0, 0, 0.5); } div.admonition ul, div.admonition ol, div.warning ul, div.warning ol, div.sidebar ul, div.sidebar ol { margin: 0.1em 0.5em 0.5em 3em; padding: 0; } /* Admonitions and sidebars only */ div.admonition, div.sidebar { border: 1px solid #609060; background-color: #e9ffe9; } div.admonition p.admonition-title, div.sidebar p.sidebar-title { background-color: #70A070; border-bottom: 1px solid #609060; } /* Warnings only */ div.warning { border: 1px solid #900000; background-color: #ffe9e9; } div.warning p.admonition-title { background-color: #b04040; border-bottom: 1px solid #900000; } /* Sidebars only */ div.sidebar { max-width: 30%; } div.versioninfo { margin: 1em 0 0 0; border: 1px solid #ccc; background-color: #DDEAF0; padding: 8px; line-height: 1.3em; font-size: 0.9em; } .viewcode-back { font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva', 'Verdana', sans-serif; } div.viewcode-block:target { background-color: #f4debf; border-top: 1px solid #ac9; border-bottom: 1px solid #ac9; } dl { margin: 1em 0 2.5em 0; } dl dt { font-style: italic; } dl dd { color: rgb(68, 68, 68); font-size: 0.95em; } /* Highlight target when you click an internal link */ dt:target { background: #ffe080; } /* Don't highlight whole divs */ div.highlight { background: transparent; } /* But do highlight spans (so search results can be highlighted) */ span.highlight { background: #ffe080; } div.footer { background-color: #465158; color: #eeeeee; padding: 0 2em 2em 2em; clear: both; font-size: 0.8em; text-align: center; } p { margin: 0.8em 0 0.5em 0; } .section p img.math { margin: 0; } .section p img { margin: 1em 2em; } table.docutils td, table.docutils th { padding: 1px 8px 1px 5px; } /* MOBILE LAYOUT -------------------------------------------------------------- */ @media screen and (max-width: 600px) { h1, h2, h3, h4, h5 { position: relative; } ul { padding-left: 1.25em; } div.bodywrapper a.headerlink, #indices-and-tables h1 a { color: #e6e6e6; font-size: 80%; float: right; line-height: 1.8; position: absolute; right: -0.7em; visibility: inherit; } div.bodywrapper h1 a.headerlink, #indices-and-tables h1 a { line-height: 1.5; } pre { font-size: 0.7em; overflow: auto; word-wrap: break-word; white-space: pre-wrap; } div.related ul { height: 2.5em; padding: 0; text-align: left; } div.related ul li { clear: both; color: #465158; padding: 0.2em 0; } div.related ul li:last-child { border-bottom: 1px dotted #8ca1af; padding-bottom: 0.4em; margin-bottom: 1em; width: 100%; } div.related ul li a { color: #465158; padding-right: 0; } div.related ul li a:hover { background: inherit; color: inherit; } div.related ul li.right { clear: none; padding: 0.65em 0; margin-bottom: 0.5em; } div.related ul li.right a { color: #fff; padding-right: 0.8em; } div.related ul li.right a:hover { background-color: #8ca1af; } div.body { clear: both; min-width: 0; word-wrap: break-word; } div.bodywrapper { margin: 0 0 0 0; } div.sphinxsidebar { float: none; margin: 0; width: auto; } div.sphinxsidebar input[type="text"] { height: 2em; line-height: 2em; width: 70%; } div.sphinxsidebar input[type="submit"] { height: 2em; margin-left: 0.5em; width: 20%; } div.sphinxsidebar p.searchtip { background: inherit; margin-bottom: 1em; } div.sphinxsidebar ul li, div.sphinxsidebar p.topless { white-space: normal; } .bodywrapper img { display: block; margin-left: auto; margin-right: auto; max-width: 100%; } div.documentwrapper { float: none; } div.admonition, div.warning, pre, blockquote { margin-left: 0em; margin-right: 0em; } .body p img { margin: 0; } #searchbox { background: transparent; } .related:not(:first-child) li { display: none; } .related:not(:first-child) li.right { display: block; } div.footer { padding: 1em; } .rtd_doc_footer .rtd-badge { float: none; margin: 1em auto; position: static; } .rtd_doc_footer .rtd-badge.revsys-inline { margin-right: auto; margin-bottom: 2em; } table.indextable { display: block; width: auto; } .indextable tr { display: block; } .indextable td { display: block; padding: 0; width: auto !important; } .indextable td dt { margin: 1em 0; } ul.search { margin-left: 0.25em; } ul.search li div.context { font-size: 90%; line-height: 1.1; margin-bottom: 1; margin-left: 0; } } PKHND;l/l/ imbo-1.1.1/_static/underscore.js// Underscore.js 1.3.1 // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore is freely distributable under the MIT license. // Portions of Underscore are inspired or borrowed from Prototype, // Oliver Steele's Functional, and John Resig's Micro-Templating. // For all details and documentation: // http://documentcloud.github.com/underscore (function(){function q(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case "[object String]":return a==String(c);case "[object Number]":return a!=+a?c!=+c:a==0?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source== c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&q(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&q(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c, h)&&!f--)break;g=!f}}d.pop();return g}var r=this,G=r._,n={},k=Array.prototype,o=Object.prototype,i=k.slice,H=k.unshift,l=o.toString,I=o.hasOwnProperty,w=k.forEach,x=k.map,y=k.reduce,z=k.reduceRight,A=k.filter,B=k.every,C=k.some,p=k.indexOf,D=k.lastIndexOf,o=Array.isArray,J=Object.keys,s=Function.prototype.bind,b=function(a){return new m(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else r._=b;b.VERSION="1.3.1";var j=b.each= b.forEach=function(a,c,d){if(a!=null)if(w&&a.forEach===w)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e2;a== null&&(a=[]);if(y&&a.reduce===y)return e&&(c=b.bind(c,e)),f?a.reduce(c,d):a.reduce(c);j(a,function(a,b,i){f?d=c.call(e,d,a,b,i):(d=a,f=true)});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(z&&a.reduceRight===z)return e&&(c=b.bind(c,e)),f?a.reduceRight(c,d):a.reduceRight(c);var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect= function(a,c,b){var e;E(a,function(a,g,h){if(c.call(b,a,g,h))return e=a,true});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(A&&a.filter===A)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(B&&a.every===B)return a.every(c,b);j(a,function(a,g,h){if(!(e= e&&c.call(b,a,g,h)))return n});return e};var E=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(C&&a.some===C)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return n});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;return p&&a.indexOf===p?a.indexOf(c)!=-1:b=E(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck= function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;bd?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a, c,d){d||(d=b.identity);for(var e=0,f=a.length;e>1;d(a[g])=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1));return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e=0;d--)b=[a[d].apply(this,b)];return b[0]}}; b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=J||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.defaults=function(a){j(i.call(arguments, 1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return q(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=o||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)}; b.isArguments=function(a){return l.call(a)=="[object Arguments]"};if(!b.isArguments(arguments))b.isArguments=function(a){return!(!a||!b.has(a,"callee"))};b.isFunction=function(a){return l.call(a)=="[object Function]"};b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"}; b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,b){return I.call(a,b)};b.noConflict=function(){r._=G;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};b.mixin=function(a){j(b.functions(a), function(c){K(c,b[c]=a[c])})};var L=0;b.uniqueId=function(a){var b=L++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var t=/.^/,u=function(a){return a.replace(/\\\\/g,"\\").replace(/\\'/g,"'")};b.template=function(a,c){var d=b.templateSettings,d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.escape||t,function(a,b){return"',_.escape("+ u(b)+"),'"}).replace(d.interpolate||t,function(a,b){return"',"+u(b)+",'"}).replace(d.evaluate||t,function(a,b){return"');"+u(b).replace(/[\r\n\t]/g," ")+";__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",e=new Function("obj","_",d);return c?e(c,b):function(a){return e.call(this,a,b)}};b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var v=function(a,c){return c?b(a).chain():a},K=function(a,c){m.prototype[a]= function(){var a=i.call(arguments);H.call(a,this._wrapped);return v(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return v(d,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];m.prototype[a]=function(){return v(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain= true;return this};m.prototype.value=function(){return this._wrapped}}).call(this); PKtNDq%imbo-1.1.1/_static/readthedocs-ext.js // Intenionally left blank PKHND<>"imbo-1.1.1/_static/ajax-loader.gifGIF89aU|NU|l!Created with ajaxload.info! ! NETSCAPE2.0,30Ikc:Nf E1º.`q-[9ݦ9 JkH! ,4N!  DqBQT`1 `LE[|ua C%$*! ,62#+AȐ̔V/cNIBap ̳ƨ+Y2d! ,3b%+2V_ ! 1DaFbR]=08,Ȥr9L! ,2r'+JdL &v`\bThYB)@<&,ȤR! ,3 9tڞ0!.BW1  sa50 m)J! ,2 ٜU]qp`a4AF0` @1Α! ,20IeBԜ) q10ʰPaVڥ ub[;PKHNDPu u imbo-1.1.1/_static/comment.pngPNG  IHDRa OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3-bKGD pHYs  tIME 1;VIDAT8ukU?sg4h`G1 RQܸp%Bn"bЍXJ .4V iZ##T;m!4bP~7r>ιbwc;m;oӍAΆ ζZ^/|s{;yR=9(rtVoG1w#_ө{*E&!(LVuoᲵ‘D PG4 :&~*ݳreu: S-,U^E&JY[P!RB ŖޞʖR@_ȐdBfNvHf"2T]R j'B1ddAak/DIJD D2H&L`&L $Ex,6|~_\P $MH`I=@Z||ttvgcЕWTZ'3rje"ܵx9W> mb|byfFRx{w%DZC$wdցHmWnta(M<~;9]C/_;Տ#}o`zSڷ_>:;x컓?yݩ|}~wam-/7=0S5RP"*֯ IENDB`PKHNDhkkimbo-1.1.1/_static/down.pngPNG  IHDRasRGBbKGDC pHYs B(xtIME"U{IDAT8ҡNCAJ, ++@4>/U^,~T&3M^^^PM6ٹs*RJa)eG*W<"F Fg78G>q OIp:sAj5GنyD^+yU:p_%G@D|aOs(yM,"msx:.b@D|`Vٟ۲иeKſ/G!IENDB`PKHND+0imbo-1.1.1/_static/file.pngPNG  IHDRabKGD pHYs  tIME  )TIDAT8˭J@Ir('[ "&xYZ X0!i|_@tD] #xjv YNaEi(əy@D&`6PZk$)5%"z.NA#Aba`Vs_3c,2mj [klvy|!Iմy;v "߮a?A7`c^nk?Bg}TЙD# "RD1yER*6MJ3K_Ut8F~IENDB`PKHND[{gtt!imbo-1.1.1/_static/up-pressed.pngPNG  IHDRasRGBbKGDC pHYs B(xtIME ,ZeIDAT8͓jA*WKk-,By@- و/`cXYh!6jf GrOlXvvfk2!p!GOOԲ &zf 6|M~%`]* ΛM]K ZĆ1Er%ȶcm1`= 0 && !jQuery(node.parentNode).hasClass(className)) { var span = document.createElement("span"); span.className = className; span.appendChild(document.createTextNode(val.substr(pos, text.length))); node.parentNode.insertBefore(span, node.parentNode.insertBefore( document.createTextNode(val.substr(pos + text.length)), node.nextSibling)); node.nodeValue = val.substr(0, pos); } } else if (!jQuery(node).is("button, select, textarea")) { jQuery.each(node.childNodes, function() { highlight(this); }); } } return this.each(function() { highlight(this); }); }; /** * Small JavaScript module for the documentation. */ var Documentation = { init : function() { this.fixFirefoxAnchorBug(); this.highlightSearchWords(); this.initIndexTable(); }, /** * i18n support */ TRANSLATIONS : {}, PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; }, LOCALE : 'unknown', // gettext and ngettext don't access this so that the functions // can safely bound to a different name (_ = Documentation.gettext) gettext : function(string) { var translated = Documentation.TRANSLATIONS[string]; if (typeof translated == 'undefined') return string; return (typeof translated == 'string') ? translated : translated[0]; }, ngettext : function(singular, plural, n) { var translated = Documentation.TRANSLATIONS[singular]; if (typeof translated == 'undefined') return (n == 1) ? singular : plural; return translated[Documentation.PLURALEXPR(n)]; }, addTranslations : function(catalog) { for (var key in catalog.messages) this.TRANSLATIONS[key] = catalog.messages[key]; this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); this.LOCALE = catalog.locale; }, /** * add context elements like header anchor links */ addContextElements : function() { $('div[id] > :header:first').each(function() { $('\u00B6'). attr('href', '#' + this.id). attr('title', _('Permalink to this headline')). appendTo(this); }); $('dt[id]').each(function() { $('\u00B6'). attr('href', '#' + this.id). attr('title', _('Permalink to this definition')). appendTo(this); }); }, /** * workaround a firefox stupidity */ fixFirefoxAnchorBug : function() { if (document.location.hash && $.browser.mozilla) window.setTimeout(function() { document.location.href += ''; }, 10); }, /** * highlight the search words provided in the url in the text */ highlightSearchWords : function() { var params = $.getQueryParameters(); var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; if (terms.length) { var body = $('div.body'); window.setTimeout(function() { $.each(terms, function() { body.highlightText(this.toLowerCase(), 'highlighted'); }); }, 10); $('') .appendTo($('#searchbox')); } }, /** * init the domain index toggle buttons */ initIndexTable : function() { var togglers = $('img.toggler').click(function() { var src = $(this).attr('src'); var idnum = $(this).attr('id').substr(7); $('tr.cg-' + idnum).toggle(); if (src.substr(-9) == 'minus.png') $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); else $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); }).css('display', ''); if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { togglers.click(); } }, /** * helper function to hide the search marks again */ hideSearchWords : function() { $('#searchbox .highlight-link').fadeOut(300); $('span.highlighted').removeClass('highlighted'); }, /** * make the url absolute */ makeURL : function(relativeURL) { return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; }, /** * get the current relative url */ getCurrentURL : function() { var path = document.location.pathname; var parts = path.split(/\//); $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { if (this == '..') parts.pop(); }); var url = parts.join('/'); return path.substring(url.lastIndexOf('/') + 1, path.length - 1); } }; // quick alias for translations _ = Documentation.gettext; $(document).ready(function() { Documentation.init(); }); PKtND(xEE!imbo-1.1.1/_static/searchtools.js/* * searchtools.js_t * ~~~~~~~~~~~~~~~~ * * Sphinx JavaScript utilties for the full-text search. * * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ /** * Porter Stemmer */ var Stemmer = function() { var step2list = { ational: 'ate', tional: 'tion', enci: 'ence', anci: 'ance', izer: 'ize', bli: 'ble', alli: 'al', entli: 'ent', eli: 'e', ousli: 'ous', ization: 'ize', ation: 'ate', ator: 'ate', alism: 'al', iveness: 'ive', fulness: 'ful', ousness: 'ous', aliti: 'al', iviti: 'ive', biliti: 'ble', logi: 'log' }; var step3list = { icate: 'ic', ative: '', alize: 'al', iciti: 'ic', ical: 'ic', ful: '', ness: '' }; var c = "[^aeiou]"; // consonant var v = "[aeiouy]"; // vowel var C = c + "[^aeiouy]*"; // consonant sequence var V = v + "[aeiou]*"; // vowel sequence var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 var s_v = "^(" + C + ")?" + v; // vowel in stem this.stemWord = function (w) { var stem; var suffix; var firstch; var origword = w; if (w.length < 3) return w; var re; var re2; var re3; var re4; firstch = w.substr(0,1); if (firstch == "y") w = firstch.toUpperCase() + w.substr(1); // Step 1a re = /^(.+?)(ss|i)es$/; re2 = /^(.+?)([^s])s$/; if (re.test(w)) w = w.replace(re,"$1$2"); else if (re2.test(w)) w = w.replace(re2,"$1$2"); // Step 1b re = /^(.+?)eed$/; re2 = /^(.+?)(ed|ing)$/; if (re.test(w)) { var fp = re.exec(w); re = new RegExp(mgr0); if (re.test(fp[1])) { re = /.$/; w = w.replace(re,""); } } else if (re2.test(w)) { var fp = re2.exec(w); stem = fp[1]; re2 = new RegExp(s_v); if (re2.test(stem)) { w = stem; re2 = /(at|bl|iz)$/; re3 = new RegExp("([^aeiouylsz])\\1$"); re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); if (re2.test(w)) w = w + "e"; else if (re3.test(w)) { re = /.$/; w = w.replace(re,""); } else if (re4.test(w)) w = w + "e"; } } // Step 1c re = /^(.+?)y$/; if (re.test(w)) { var fp = re.exec(w); stem = fp[1]; re = new RegExp(s_v); if (re.test(stem)) w = stem + "i"; } // Step 2 re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; if (re.test(w)) { var fp = re.exec(w); stem = fp[1]; suffix = fp[2]; re = new RegExp(mgr0); if (re.test(stem)) w = stem + step2list[suffix]; } // Step 3 re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; if (re.test(w)) { var fp = re.exec(w); stem = fp[1]; suffix = fp[2]; re = new RegExp(mgr0); if (re.test(stem)) w = stem + step3list[suffix]; } // Step 4 re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; re2 = /^(.+?)(s|t)(ion)$/; if (re.test(w)) { var fp = re.exec(w); stem = fp[1]; re = new RegExp(mgr1); if (re.test(stem)) w = stem; } else if (re2.test(w)) { var fp = re2.exec(w); stem = fp[1] + fp[2]; re2 = new RegExp(mgr1); if (re2.test(stem)) w = stem; } // Step 5 re = /^(.+?)e$/; if (re.test(w)) { var fp = re.exec(w); stem = fp[1]; re = new RegExp(mgr1); re2 = new RegExp(meq1); re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) w = stem; } re = /ll$/; re2 = new RegExp(mgr1); if (re.test(w) && re2.test(w)) { re = /.$/; w = w.replace(re,""); } // and turn initial Y back to y if (firstch == "y") w = firstch.toLowerCase() + w.substr(1); return w; } } /** * Simple result scoring code. */ var Scorer = { // Implement the following function to further tweak the score for each result // The function takes a result array [filename, title, anchor, descr, score] // and returns the new score. /* score: function(result) { return result[4]; }, */ // query matches the full name of an object objNameMatch: 11, // or matches in the last dotted part of the object name objPartialMatch: 6, // Additive scores depending on the priority of the object objPrio: {0: 15, // used to be importantResults 1: 5, // used to be objectResults 2: -5}, // used to be unimportantResults // Used when the priority is not in the mapping. objPrioDefault: 0, // query found in title title: 15, // query found in terms term: 5 }; /** * Search Module */ var Search = { _index : null, _queued_query : null, _pulse_status : -1, init : function() { var params = $.getQueryParameters(); if (params.q) { var query = params.q[0]; $('input[name="q"]')[0].value = query; this.performSearch(query); } }, loadIndex : function(url) { $.ajax({type: "GET", url: url, data: null, dataType: "script", cache: true, complete: function(jqxhr, textstatus) { if (textstatus != "success") { document.getElementById("searchindexloader").src = url; } }}); }, setIndex : function(index) { var q; this._index = index; if ((q = this._queued_query) !== null) { this._queued_query = null; Search.query(q); } }, hasIndex : function() { return this._index !== null; }, deferQuery : function(query) { this._queued_query = query; }, stopPulse : function() { this._pulse_status = 0; }, startPulse : function() { if (this._pulse_status >= 0) return; function pulse() { var i; Search._pulse_status = (Search._pulse_status + 1) % 4; var dotString = ''; for (i = 0; i < Search._pulse_status; i++) dotString += '.'; Search.dots.text(dotString); if (Search._pulse_status > -1) window.setTimeout(pulse, 500); } pulse(); }, /** * perform a search for something (or wait until index is loaded) */ performSearch : function(query) { // create the required interface elements this.out = $('#search-results'); this.title = $('

' + _('Searching') + '

').appendTo(this.out); this.dots = $('').appendTo(this.title); this.status = $('

').appendTo(this.out); this.output = $('