Practice: Using JSZip to Download Current Week's Images in Blogger

The Task
There is a blogger: its main content is pictures and photos, client wants to allow users to download today, this week and this month's pictures.

The Solution
The basic idea is to send a request to Blogger feed url, parse its json response to get all image links, then use JSZip and JQuery Deferred pattern to download all remote images.
Using GAE to Serve JavaScript Files
After download JSZip and JSZip-Utils, we need put them somewhere, so the blogger can load them. So we create one GAE application, and put them in the webapp/js/jszip folders.

We only want to load these scripts if the pageType is item: mean current page is a post page. So we add the following code under <b:includable id='post' var='post'>:

<b:includable id='post' var='post'>
<b:if cond='data:blog.pageType == "item"'>
<script src='//youapp.appspot.com/js/jszip/jszip.min.js'/>
<script src='//youapp.appspot.com/js/jszip/jszip-utils.min.js'/>
<script src='//youapp.appspot.com/js/jszip/FileSaver.js'/>
</b:if>

Add Download Links to Item Page
<div class='blog-pager' id='blog-pager'>
 <b:if cond='data:blog.pageType == "item"'>
  <div class='blog-pager' id='blog-pager'>
     <div id='blog-pager-newer-link'>
    <a class='blog-pager-newer-link' href='' id='downloadToday'>Download Today's Images</a>
   </div>

   <div id='blog-pager-older-link'>
    <a class='blog-pager-newer-link' href='' id='downloadMonth'>Download This Month's Images</a>
   </div>

  <div id='blog-pager-home-link'>
    <a class='blog-pager-newer-link' href='' id='downloadWeek'>Download This Week's Images</a>
  </div>

  </div>
 </b:if>
...
</div>
The Complete JavaScript Code
Using Blogger Feeds URL to Get Post in Range
Using JSZip and JQuery Deferred Pattern to Download Multiple Remote Images
<b:includable id='post' var='post'>
<b:if cond='data:blog.pageType == "item"'>
<script src='//lifelongprogrammertools.appspot.com/js/jszip/jszip.min.js'/>
<script src='//lifelongprogrammertools.appspot.com/js/jszip/jszip-utils.min.js'/>
<script src='//lifelongprogrammertools.appspot.com/js/jszip/FileSaver.js'/>
<script>
  var dateHeader= '<data:post.dateHeader/>';
  var parts = dateHeader.split('-');
  var postDate = new Date(parts[0], parts[1]-1, parts[2]);
  console.log("postDate:" + postDate);  
//<![CDATA[

$(function($) {
  if(JSZip.support.blob) {
   $("#downloadToday").click(function (e) {
   getTodayAllImages(dateHeader);
         e.preventDefault();
         return false;
   });
   $("#downloadWeek").click(function (e) {
   getWeekAllImages(postDate);
         e.preventDefault();
         return false;
   });
   $("#downloadMonth").click(function (e) {
   getMonthAllImages(postDate);
         e.preventDefault();
         return false;
   });

  }
});

function addToZip(zip, link, postUrl, i) {
var deferred = $.Deferred();

 JSZipUtils.getBinaryContent(link, function (err, data) {
    if(err) {
      alert("Problem happened when download image from " + postUrl + ", img link: " + link);
      console.error("Problem happened when download image from " + postUrl + ", img link: " + link);
      deferred.resolve(zip); // ignore this error: just logging
      // deferred.reject(zip);
    } else {
      zip.file("picture"+i+".jpg", data, {binary:true});
      deferred.resolve(zip);
    }
 });
return deferred;
}

function parseImagesRsp(root){
    var feed = root.feed;
  var parser = new DOMParser();  
  var zip = new JSZip();
  var deferreds = [];
  for(var i=0; i<feed.entry.length; i++)
  {
   var e=feed.entry[i];
   var doc = parser.parseFromString(e.content.$t, "text/html");
   var img = doc.querySelector("img");
   var pageUrl = e.link[2].href;
   if(!img)
   {       
     console.error("No img tag in " + pageUrl);  
   }
   else{
     var imgLink = img.src;
     console.log("img link: " + imgLink);
     deferreds.push( addToZip(zip, imgLink, pageUrl, i) );
   }
  }

$.when.apply(window, deferreds).done(generateZip);
}
function generateZip(zip)
{
 var content = zip.generate({type:"blob"});
 // see FileSaver.js
 saveAs(content, "downloadImages.zip");
}
function doDownload(startDate, endDate){
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = '/feeds/posts/default?published-min=' + startDate + '&published-max='+endDate+'&alt=json-in-script&max-results=1000&callback=parseImagesRsp';
    document.getElementsByTagName('head')[0].appendChild(script);
}
function getTodayAllImages(dateStr){
 var startDate = dateStr + "T00:00:01", endDate = dateStr + "T23:59:59";
    console.log("Download images from " + startDate + " to " + endDate);
    doDownload(startDate, endDate);
    return false;
}
function getMonthAllImages(dateObj){
 var startDate = yymmdd(getFirstDayOfCurrentMonth(dateObj)) + "T00:00:01", endDate = yymmdd(getLastDayOfCurrentMonth(dateObj))  + "T23:59:59";
    doDownload(startDate, endDate);
    return false;
}
function getWeekAllImages(dateObj){
 var startDate = yymmdd(getMondayOfCurrentWeek(dateObj)) + "T00:00:01", endDate = yymmdd(getSundayOfCurrentWeek(dateObj))  + "T23:59:59";
    doDownload(startDate, endDate);
    return false;
}
function yymmdd(dataObj){
  var month = (dataObj.getMonth()+1);
  var monthStr = month<10? ('0' + month): month;
  var dateStr = dataObj.getDate()< 10? ('0' + dataObj.getDate()): dataObj.getDate();
  return dataObj.getFullYear() + "-" + monthStr + "-" + dateStr;
}
function getMondayOfCurrentWeek(d)
{
    var day = d.getDay();
    return new Date(d.getFullYear(), d.getMonth(), d.getDate()-day + (day == 0 ? -6:1));
}
function getSundayOfCurrentWeek(d)
{
    var day = d.getDay();
    return new Date(d.getFullYear(), d.getMonth(), d.getDate()-day + (day == 0 ? 0:7));
}
function getFirstDayOfCurrentMonth(d){
  return new Date(d.getFullYear(), d.getMonth(), 1);
}
function getLastDayOfCurrentMonth(d){
  return new Date(d.getFullYear(), d.getMonth()+1, 0);
}
//]]>
</script>
</b:if>

Post a Comment

Labels

Java (159) Lucene-Solr (110) All (60) Interview (59) J2SE (53) Algorithm (37) Eclipse (35) Soft Skills (35) Code Example (31) Linux (26) JavaScript (23) Spring (22) Windows (22) Web Development (20) Tools (19) Nutch2 (18) Bugs (17) Debug (15) Defects (14) Text Mining (14) J2EE (13) Network (13) PowerShell (11) Chrome (9) Continuous Integration (9) How to (9) Learning code (9) Performance (9) UIMA (9) html (9) Design (8) Dynamic Languages (8) Http Client (8) Maven (8) Security (8) Trouble Shooting (8) bat (8) blogger (8) Big Data (7) Google (7) Guava (7) JSON (7) Problem Solving (7) ANT (6) Coding Skills (6) Database (6) Scala (6) Shell (6) css (6) Algorithm Series (5) Cache (5) IDE (5) Lesson Learned (5) Miscs (5) Programmer Skills (5) System Design (5) Tips (5) adsense (5) xml (5) AIX (4) Code Quality (4) GAE (4) Git (4) Good Programming Practices (4) Jackson (4) Memory Usage (4) OpenNLP (4) Project Managment (4) Python (4) Spark (4) Testing (4) ads (4) regular-expression (4) Android (3) Apache Spark (3) Become a Better You (3) Concurrency (3) Eclipse RCP (3) English (3) Firefox (3) Happy Hacking (3) IBM (3) J2SE Knowledge Series (3) JAX-RS (3) Jetty (3) Restful Web Service (3) Script (3) regex (3) seo (3) .Net (2) Android Studio (2) Apache (2) Apache Procrun (2) Architecture (2) Batch (2) Build (2) Building Scalable Web Sites (2) C# (2) C/C++ (2) CSV (2) Career (2) Cassandra (2) Distributed (2) Fiddler (2) Google Drive (2) Gson (2) Html Parser (2) Http (2) Image Tools (2) JQuery (2) Jersey (2) LDAP (2) Life (2) Logging (2) Software Issues (2) Storage (2) Text Search (2) xml parser (2) AOP (1) Application Design (1) AspectJ (1) Bit Operation (1) Chrome DevTools (1) Cloud (1) Codility (1) Data Mining (1) Data Structure (1) ExceptionUtils (1) Exif (1) Feature Request (1) FindBugs (1) Greasemonkey (1) HTML5 (1) Httpd (1) I18N (1) IBM Java Thread Dump Analyzer (1) JDK Source Code (1) JDK8 (1) JMX (1) Lazy Developer (1) Mac (1) Machine Learning (1) Mobile (1) My Plan for 2010 (1) Netbeans (1) Notes (1) Operating System (1) Perl (1) Problems (1) Product Architecture (1) Programming Life (1) Quality (1) Redhat (1) Redis (1) Review (1) RxJava (1) Solutions logs (1) Team Management (1) Thread Dump Analyzer (1) Troubleshooting (1) Visualization (1) boilerpipe (1) htm (1) ongoing (1) procrun (1) rss (1)

Popular Posts