The Problem
Recently I listed bunch of stuff on a local web listing site. Unfortunately they keep the ads for 30 days. After this period the adds are gone. I got frustrated by the fact I have to spend time to re-list all the stuff again. It gets worse if I wanted to list the stuff in other sites as well.What if I can do it with one click...
The Solution
Here comes the little meteor app I came up with to do exactly this. All I have to do is to upload the photos, add the text and press the button. The way it works is simple - the pictures are stored on AWS S3 with metadata on MongoDB collection, the ad titles, text and other related information is stored in another MongoDB collection. Then for each 'submitter' I have a separate meteor package, which posts the ad.Images orientation
The html img tag shows the photo as it is taken, keeping the original orientation, but when the photo is opened by the browser itself, or by image viewer software it is rotated according the EXIF orientation flag. When the image is shown, the user can change its orientation from the web interface. It's done just by adding one of the classes and some CSS:CSS:The image orientation selected by the user is also stored in the Files MongoBD collection along with the image other metadata. In order to get the right user selected orientation I use ImageMagic to rotate the image and strip all additional metadata from the image itself (like EXIF in JPEGs) as soon as the image is downloaded. I use Fibers/Future block the execution until all the images have been downloaded and rotated.
div.show-image img.img90 {
-ms-transform: rotate(90deg); /* IE 9 */
-webkit-transform: rotate(90deg); /* Chrome, Safari, Opera */
transform: rotate(90deg);
}
div.show-image img.img180 {
-ms-transform: rotate(180deg); /* IE 9 */
-webkit-transform: rotate(180deg); /* Chrome, Safari, Opera */
transform: rotate(180deg);
}
div.show-image img.img270 {
-ms-transform: rotate(270deg); /* IE 9 */
-webkit-transform: rotate(270deg); /* Chrome, Safari, Opera */
transform: rotate(270deg);
}
futures = _.map(files, function(file) { // Set up a future for the current job var future = new Future(); // A callback so the job can signal completion var onComplete = future.resolver(); /// Make async http call Meteor.call("downloadImage", file.url, dirPath, null, function(x){ var imgPath = dirPath+"/"+x; s.paths.photos.push(imgPath); var rot = 0; if(file.rot) rot = file.rot; console.log("-rotate " + rot); if(rot > 0){ im.convert([imgPath, '-strip', '-rotate', rot, imgPath], onComplete); } else { // Inform the future that we're done with it onComplete(null, ""); } }, function(e, r){}); // Return the future return future; }); Future.wait(futures); console.log(_.invoke(futures, 'get'));
Once this is done, then all the submitters are executed. Each submitter has a collection, where a site relevant information is stored, like username, categories, price, etc. Currently I have only one submit package, for DoneDeal.ie site. It is even not fully complete as it adds only free listings and doesn't handle most of the site features.
The source code is published to https://bitbucket.org/nchokoev/adapp under the MIT license.