<commit_before>/**
 *
 * Copyright 2013-2014 <NAME>
 * 
 * This file is part of AkashaCMS-embeddables (http://akashacms.com/).
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

var path     = require('path');
var util     = require('util');
var url      = require('url');
var async    = require('async');
var request  = require('request');

var YouTube = require('youtube-node');
var youtube = new YouTube();

var logger;
var akasha;

var ytVidz = [];
var ytVidInfo = function(id, done) {
    if (ytVidz[id]) {
        done(ytVidz[id]);
    } else {
        youtube.getById(id, function(resultData) {
            ytVidz[id] = resultData;
            done(resultData);
        });
    }
};

var ytGetId = function($, elemYT) {
    var id;
    if (elemYT && $(elemYT).attr('id')) {
        id = $(elemYT).attr('id');
    } else if (elemYT && $(elemYT).attr('href')) {
        var _yturl = $(elemYT).attr('href');
        var yturl = url.parse(_yturl, true);
        if (yturl.query && yturl.query.v) {
            id = yturl.query.v
        }
    }
    return id;
};

var ytBestThumbnail = function(thumbs) {
    if (thumbs && thumbs.standard && thumbs.standard.url) {
        return thumbs.standard.url;
    } else if (thumbs && thumbs.high && thumbs.high.url) {
        return thumbs.high.url;
    } else if (thumbs && thumbs.medium && thumbs.medium.url) {
        return thumbs.medium.url;
    } else if (thumbs && thumbs["default"] && thumbs["default"].url) {
        return thumbs["default"].url;
    } else {
        return "";
    }
};

var vimeoCache = [];
var vimeoData = function(url2request, done) {
	// logger.trace('vimeoData '+ url2request);
	if (vimeoCache[url2request]) {
		done(undefined, vimeoCache[url2request]);
	} else {
		request(url.format({
			protocol: 'http',
			host: 'vimeo.com',
			pathname: '/api/oembed.json',
			query: {
				url: url2request
			}
		}),
		function(err, res, body) {
			if (err) { logger.error(err); done(err); }
			else {
				// logger.trace(body);
				vimeoCache[url2request] = JSON.parse(body);
				done(undefined, vimeoCache[url2request]);
			}
		});
	}
};

/**
 * Add ourselves to the config data.
 **/
module.exports.config = function(_akasha, config) {
	akasha = _akasha;
	logger = akasha.getLogger("embeddables");
    config.root_partials.push(path.join(__dirname, 'partials'));
    config.root_assets.unshift(path.join(__dirname, 'assets'));
    
    if (config.embeddables && config.embeddables.youtubeKey) {
        youtube.setKey(config.embeddables.youtubeKey);
    }
    
    if (config.mahabhuta) {
        config.mahabhuta.push(function($, metadata, dirty, done) {
            // <youtube-video href=".."/>  TBD: autoplay, thumbnail+lightbox
            var elemsYT = [];
            $('youtube-video').each(function(i, elem) { elemsYT.push(elem); });
            $('youtube-video-embed').each(function(i, elem) { elemsYT.push(elem); });
            $('youtube-thumbnail').each(function(i, elem) { elemsYT.push(elem); });
            // util.log(util.inspect(elemsYT));
            async.eachSeries(elemsYT, function(elemYT, next) {
                // util.log(util.inspect(elemYT));
                
                logger.trace(elemYT.name);
                var id = ytGetId($, elemYT);
                if (!id) {
                    next(new Error("No Youtube ID"));
                } else {
                    ytVidInfo(id, function(resultData) {
                        var result = resultData;
                        var item = result.items[0];
                        // var thumbs = item.snippet.thumbnails;
                        
                        if (item) {
                        
							var width = $(elemYT).attr('width')
								? $(elemYT).attr('width')
								: undefined;
							var height = $(elemYT).attr('height')
								? $(elemYT).attr('height')
								: undefined;
							var _class = $(elemYT).attr('class')
								? $(elemYT).attr('class')
								: undefined;
							var style = $(elemYT).attr('style')
								? $(elemYT).attr('style')
								: undefined;
						
							var player;
							if (elemYT.name === 'youtube-video' || elemYT.name === 'youtube-video-embed') {
								if (!width && !height) {
									width = "480";
									height = "270";
								}
							
								var yturl = {
									protocol: "http",
									hostname: "www.youtube.com",
									pathname: "/embed/"+ id,
									query: []
								};
							
								/* 
								TODO update akashacms.com
								TODO add a page of youtube embed examples
							
								TODO add new section to akashacms.com - layout examples - first is the youtube layout
								*/
								
								// These options are explained here: https://developers.google.com/youtube/player_parameters

								if ($(elemYT).attr('autohide'))
									yturl.query['autohide'] = $(elemYT).attr('autohide');
								if ($(elemYT).attr('autoplay'))
									yturl.query['autoplay'] = $(elemYT).attr('autoplay');
								if ($(elemYT).attr('cc_load_policy'))
									yturl.query['cc_load_policy'] = $(elemYT).attr('cc_load_policy');
								if ($(elemYT).attr('color'))
									yturl.query['color'] = $(elemYT).attr('color');
								if ($(elemYT).attr('controls'))
									yturl.query['controls'] = $(elemYT).attr('controls');
								if ($(elemYT).attr('disablekb'))
									yturl.query['disablekb'] = $(elemYT).attr('disablekb');
								if ($(elemYT).attr('enablejsapi'))
									yturl.query['enablejsapi'] = $(elemYT).attr('enablejsapi');
								if ($(elemYT).attr('end'))
									yturl.query['end'] = $(elemYT).attr('end');
								if ($(elemYT).attr('fs'))
									yturl.query['fs'] = $(elemYT).attr('fs');
								if ($(elemYT).attr('hl'))
									yturl.query['hl'] = $(elemYT).attr('hl');
								if ($(elemYT).attr('iv_load_policy'))
									yturl.query['iv_load_policy'] = $(elemYT).attr('iv_load_policy');
								if ($(elemYT).attr('list'))
									yturl.query['list'] = $(elemYT).attr('list');
								if ($(elemYT).attr('listType'))
									yturl.query['listType'] = $(elemYT).attr('listType');
								if ($(elemYT).attr('loop'))
									yturl.query['loop'] = $(elemYT).attr('loop');
								if ($(elemYT).attr('modestbranding'))
									yturl.query['modestbranding'] = $(elemYT).attr('modestbranding');
								if ($(elemYT).attr('origin'))
									yturl.query['origin'] = $(elemYT).attr('origin');
								if ($(elemYT).attr('playerapiid'))
									yturl.query['playerapiid'] = $(elemYT).attr('playerapiid');
								if ($(elemYT).attr('playlist'))
									yturl.query['playlist'] = $(elemYT).attr('playlist');
								if ($(elemYT).attr('playsinline'))
									yturl.query['playsinline'] = $(elemYT).attr('playsinline');
								if ($(elemYT).attr('rel'))
									yturl.query['rel'] = $(elemYT).attr('rel');
								if ($(elemYT).attr('showinfo'))
									yturl.query['showinfo'] = $(elemYT).attr('showinfo');
								if ($(elemYT).attr('start'))
									yturl.query['start'] = $(elemYT).attr('start');
								if ($(elemYT).attr('theme'))
									yturl.query['theme'] = $(elemYT).attr('theme');
							
								player = akasha.partialSync("youtube-embed-code.html.ejs", {
									idYouTube: id,
									width: width,
									height: height,
									ytclass: _class,
									style: style,
									frameborder: "0",
									yturl: url.format(yturl)
								});
							}
						
							if (elemYT.name /* .prop('tagName') */ === 'youtube-video') {
								akasha.partial("youtube-embed.html.ejs", {
									title: item ? item.snippet.title : "",
									html: player,
									author_url: item ? ("http://youtube.com/user/"+ item.snippet.channelTitle +"/videos") : "",
									author_name: item ? item.snippet.channelTitle : ""
								}, function(err, embed) {
									if (err) { logger.error(err); next(err); }
									else {
										$(elemYT).replaceWith(embed);
										next();
									}
								});
							} else if (elemYT.name /* .prop('tagName') */ === 'youtube-video-embed') {
								$(elemYT).replaceWith(player);
								next();
							} else if (elemYT.name /* .prop('tagName') */ === 'youtube-thumbnail') {
								var thumbs = item ? item.snippet.thumbnails : undefined;
								// if (_class === 'embed-yt-video') _class = 'embed-yt-thumb';
								var align = $(elemYT).attr('align')
									? $(elemYT).attr('align')
									: undefined;
								if (!width) width = "100%";
								
								akasha.partial("youtube-thumb.html.ejs", {
									imgwidth: width,
									imgalign: align,
									imgclass: _class,
									style: style,
									imgurl: ytBestThumbnail(thumbs)
								}, function(err, thumb) {
									if (err) { logger.error(err); next(err); }
									else {
										// logger.trace('youtube-thumb '+ thumb);
										$(elemYT).replaceWith(thumb);
										next();
									}
								});
							} else next(new Error("didn't match -video or -video-embed or -thumbnail "+ elemYT.name));
                        } else next(new Error("No match for youtube id="+ id));
                    });
                }
            }, function(err) {
                if (err) done(err);
                else done();
            });
        });
        
        config.mahabhuta.push(function($, metadata, dirty, done) {
            // <youtube-metadata id="" href=".."/>  
            var elemsYT = [];
            $('youtube-metadata').each(function(i, elem) { elemsYT[i] = elem; });
            async.eachSeries(elemsYT, function(elemYT, next) {
                logger.trace(elemYT.name);
                var id = ytGetId($, elemYT);
                if (!id) {
                    next(new Error("No Youtube ID"));
                } else {
                    ytVidInfo(id, function(resultData) {
                        var result = resultData;
                        var item = result.items[0];
                        var thumbs = item ? item.snippet.thumbnails : undefined;
                        if (!item) {
                        	next(new Error("Youtube didn't get anything for id="+ id));
                        } else if ($('head').get(0)) {
                            // Only do this substitution if we are on a completely rendered page
                            $('head').append(
                                '<meta property="og:image" content="'+ ytBestThumbnail(thumbs) +'"/>\n' +
                                '<meta name="twitter:image" content="'+ ytBestThumbnail(thumbs) +'"/>\n'
                            );
                            $(elemYT).replaceWith('');
                            next();
                        } else next();
                    });
                }
            }, function(err) {
                if (err) done(err);
                else done();
            });
        });
        config.mahabhuta.push(function($, metadata, dirty, done) {
            // <youtube-title id="" href=".."/>  
            var elemsYT = [];
            $('youtube-title').each(function(i, elem) { elemsYT.push(elem); });
            $('youtube-author').each(function(i, elem) { elemsYT.push(elem); });
            $('youtube-description').each(function(i, elem) { elemsYT.push(elem); });
            $('youtube-publ-date').each(function(i, elem) { elemsYT.push(elem); });
            async.eachSeries(elemsYT, function(elemYT, next) {
                logger.trace(elemYT.name);
                var id = ytGetId($, elemYT);
                if (!id) {
                    next(new Error("No Youtube ID"));
                } else {
                    ytVidInfo(id, function(resultData) {
                        var result = resultData;
                        var item = result.items[0];
                        
                        if (item) {
							if (elemYT.name /* .prop('tagName') */ === 'youtube-title') {
								$(elemYT).replaceWith(item.snippet.title);
								next();
							} else if (elemYT.name /* .prop('tagName') */ === 'youtube-author') {
								$(elemYT).replaceWith(item.snippet.channelTitle);
								next();
							} else if (elemYT.name /* .prop('tagName') */ === 'youtube-description') {
								$(elemYT).replaceWith(item.snippet.description);
								next();
							} else if (elemYT.name /* .prop('tagName') */ === 'youtube-publ-date') {
								// TODO fix this to parse & print nicely
								$(elemYT).replaceWith(item.snippet.publishedAt);
								next();
							} else next(new Error("failed to match -title or -author or -description "+ $(elemYT).name));
						} else next(new Error("nothing found for youtube id="+ id));
                    });
                }
            }, function(err) {
                if (err) done(err);
                else done();
            });
        });
        
        config.mahabhuta.push(function($, metadata, dirty, done) {
        	// <vimeo-player url="..." />
        	// <vimeo-thumb url="..." />
        	// <vimeo-title url="..." />
        	// <vimeo-author url="..." />
        	// <vimeo-description url="..." />
        	
            var elements = [];
            $('vimeo-player').each(function(i, elem) { elements.push(elem); });
            $('vimeo-thumbnail').each(function(i, elem) { elements.push(elem); });
            $('vimeo-title').each(function(i, elem) { elements.push(elem); });
            $('vimeo-author').each(function(i, elem) { elements.push(elem); });
            $('vimeo-description').each(function(i, elem) { elements.push(elem); });
            async.eachSeries(elements, function(element, next) {
            	logger.trace(element.name);
            	vimeoData($(element).attr('url'), function(err, vdata) {
            		if (err) next(err);
            		else {
            			if (element.name === 'vimeo-player') {
            				$(element).replaceWith(vdata.html);
            				next();
            			} else if (element.name === 'vimeo-thumbnail') {
            				
							var width = $(element).attr('width')
								? $(element).attr('width')
								: undefined;
							var height = $(element).attr('height')
								? $(element).attr('height')
								: undefined;
							var _class = $(element).attr('class')
								? $(element).attr('class')
								: undefined;
							var style = $(element).attr('style')
								? $(element).attr('style')
								: undefined;
							var align = $(element).attr('align')
								? $(element).attr('align')
								: undefined;
								
							akasha.partial("youtube-thumb.html.ejs", {
								imgwidth: width,
								imgalign: align,
								imgclass: _class,
								style: style,
								imgurl: vdata.thumbnail_url
							}, function(err, thumb) {
								if (err) { logger.error(err); next(err); }
								else {
									// logger.trace('vimeo-thumbnail '+ thumb);
									$(element).replaceWith(thumb);
									next();
								}
							});
            			} else if (element.name === 'vimeo-title') {
            				$(element).replaceWith(vdata.title);
            				next();
            			} else if (element.name === 'vimeo-author') {
            				$(element).replaceWith(vdata.author_name);
            				next();
            			} else if (element.name === 'vimeo-description') {
            				$(element).replaceWith(vdata.description);
            				next();
            			} else {
            				next();
            			}
            		}
            	});
            },
            function(err) {
            	if (err) done(err); else done();
            });
        });
        
        config.mahabhuta.push(function($, metadata, dirty, done) {
            // <oembed href="..." optional: template="..."/>
            logger.trace('oembed');
            var elemsOE = [];
            $('oembed').each(function(i, elem) { elemsOE[i] = elem; });
            // util.log(util.inspect(elemsOE));
            async.eachSeries(elemsOE, function(elemOE, cb) {
                // util.log(util.inspect(elemOE));
                akasha.oembedRender({
                    template: $(elemOE).attr('template'),
                    url: $(elemOE).attr("href")
                }, function(err, html) {
                    if (err) cb(err);
                    else { 
                        $(elemOE).replaceWith(html);
                        cb();
                    }
                });
            }, function(err) {
                if (err) done(err);
                else done();
            });
        });<commit_msg>Small changes<commit_after>/**
 *
 * Copyright 2013-2014 <NAME>
 * 
 * This file is part of AkashaCMS-embeddables (http://akashacms.com/).
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

var path     = require('path');
var util     = require('util');
var url      = require('url');
var async    = require('async');
var request  = require('request');

var YouTube = require('youtube-node');
var youtube = new YouTube();

var logger;
var akasha;

var ytVidz = [];
var ytVidInfo = function(id, done) {
    if (ytVidz[id]) {
        done(ytVidz[id]);
    } else {
        youtube.getById(id, function(resultData) {
            ytVidz[id] = resultData;
            done(resultData);
        });
    }
};

var ytGetId = function($, elemYT) {
    var id;
    if (elemYT && $(elemYT).attr('id')) {
        id = $(elemYT).attr('id');
    } else if (elemYT && $(elemYT).attr('href')) {
        var _yturl = $(elemYT).attr('href');
        var yturl = url.parse(_yturl, true);
        if (yturl.query && yturl.query.v) {
            id = yturl.query.v
        }
    }
    return id;
};

var ytBestThumbnail = function(thumbs) {
    if (thumbs && thumbs.standard && thumbs.standard.url) {
        return thumbs.standard.url;
    } else if (thumbs && thumbs.high && thumbs.high.url) {
        return thumbs.high.url;
    } else if (thumbs && thumbs.medium && thumbs.medium.url) {
        return thumbs.medium.url;
    } else if (thumbs && thumbs["default"] && thumbs["default"].url) {
        return thumbs["default"].url;
    } else {
        return "";
    }
};

var vimeoCache = [];
var vimeoData = function(url2request, done) {
	// logger.trace('vimeoData '+ url2request);
	if (vimeoCache[url2request]) {
		done(undefined, vimeoCache[url2request]);
	} else {
		request(url.format({
			protocol: 'http',
			host: 'vimeo.com',
			pathname: '/api/oembed.json',
			query: {
				url: url2request
			}
		}),
		function(err, res, body) {
			if (err) { logger.error(err); done(err); }
			else {
				// logger.trace(body);
				vimeoCache[url2request] = JSON.parse(body);
				done(undefined, vimeoCache[url2request]);
			}
		});
	}
};

/**
 * Add ourselves to the config data.
 **/
module.exports.config = function(_akasha, config) {
	akasha = _akasha;
	logger = akasha.getLogger("embeddables");
    config.root_partials.push(path.join(__dirname, 'partials'));
    config.root_assets.unshift(path.join(__dirname, 'assets'));
    
    if (config.embeddables && config.embeddables.youtubeKey) {
        youtube.setKey(config.embeddables.youtubeKey);
    }
    
    if (config.mahabhuta) {
        config.mahabhuta.push(function($, metadata, dirty, done) {
            // <youtube-video href=".."/>  TBD: autoplay, thumbnail+lightbox
            var elemsYT = [];
            $('youtube-video').each(function(i, elem) { elemsYT.push(elem); });
            $('youtube-video-embed').each(function(i, elem) { elemsYT.push(elem); });
            $('youtube-thumbnail').each(function(i, elem) { elemsYT.push(elem); });
            // util.log(util.inspect(elemsYT));
            async.eachSeries(elemsYT, function(elemYT, next) {
                // util.log(util.inspect(elemYT));
                
                logger.trace(elemYT.name);
                var id = ytGetId($, elemYT);
                if (!id) {
                    next(new Error("No Youtube ID"));
                } else {
                    ytVidInfo(id, function(resultData) {
                        var result = resultData;
                        var item = result.items[0];
                        // var thumbs = item.snippet.thumbnails;
                        
                        if (item) {
                        
							var width = $(elemYT).attr('width')
								? $(elemYT).attr('width')
								: undefined;
							var height = $(elemYT).attr('height')
								? $(elemYT).attr('height')
								: undefined;
							var _class = $(elemYT).attr('class')
								? $(elemYT).attr('class')
								: undefined;
							var style = $(elemYT).attr('style')
								? $(elemYT).attr('style')
								: undefined;
						
							var player;
							if (elemYT.name === 'youtube-video' || elemYT.name === 'youtube-video-embed') {
								if (!width && !height) {
									width = "480";
									height = "270";
								}
							
								var yturl = {
									protocol: "http",
									hostname: "www.youtube.com",
									pathname: "/embed/"+ id,
									query: []
								};
							
								/* 
								TODO update akashacms.com
								TODO add a page of youtube embed examples
							
								TODO add new section to akashacms.com - layout examples - first is the youtube layout
								*/
								
								// These options are explained here: https://developers.google.com/youtube/player_parameters

								if ($(elemYT).attr('autohide'))
									yturl.query['autohide'] = $(elemYT).attr('autohide');
								if ($(elemYT).attr('autoplay'))
									yturl.query['autoplay'] = $(elemYT).attr('autoplay');
								if ($(elemYT).attr('cc_load_policy'))
									yturl.query['cc_load_policy'] = $(elemYT).attr('cc_load_policy');
								if ($(elemYT).attr('color'))
									yturl.query['color'] = $(elemYT).attr('color');
								if ($(elemYT).attr('controls'))
									yturl.query['controls'] = $(elemYT).attr('controls');
								if ($(elemYT).attr('disablekb'))
									yturl.query['disablekb'] = $(elemYT).attr('disablekb');
								if ($(elemYT).attr('enablejsapi'))
									yturl.query['enablejsapi'] = $(elemYT).attr('enablejsapi');
								if ($(elemYT).attr('end'))
									yturl.query['end'] = $(elemYT).attr('end');
								if ($(elemYT).attr('fs'))
									yturl.query['fs'] = $(elemYT).attr('fs');
								if ($(elemYT).attr('hl'))
									yturl.query['hl'] = $(elemYT).attr('hl');
								if ($(elemYT).attr('iv_load_policy'))
									yturl.query['iv_load_policy'] = $(elemYT).attr('iv_load_policy');
								if ($(elemYT).attr('list'))
									yturl.query['list'] = $(elemYT).attr('list');
								if ($(elemYT).attr('listType'))
									yturl.query['listType'] = $(elemYT).attr('listType');
								if ($(elemYT).attr('loop'))
									yturl.query['loop'] = $(elemYT).attr('loop');
								if ($(elemYT).attr('modestbranding'))
									yturl.query['modestbranding'] = $(elemYT).attr('modestbranding');
								if ($(elemYT).attr('origin'))
									yturl.query['origin'] = $(elemYT).attr('origin');
								if ($(elemYT).attr('playerapiid'))
									yturl.query['playerapiid'] = $(elemYT).attr('playerapiid');
								if ($(elemYT).attr('playlist'))
									yturl.query['playlist'] = $(elemYT).attr('playlist');
								if ($(elemYT).attr('playsinline'))
									yturl.query['playsinline'] = $(elemYT).attr('playsinline');
								if ($(elemYT).attr('rel'))
									yturl.query['rel'] = $(elemYT).attr('rel');
								if ($(elemYT).attr('showinfo'))
									yturl.query['showinfo'] = $(elemYT).attr('showinfo');
								if ($(elemYT).attr('start'))
									yturl.query['start'] = $(elemYT).attr('start');
								if ($(elemYT).attr('theme'))
									yturl.query['theme'] = $(elemYT).attr('theme');
							
								player = akasha.partialSync("youtube-embed-code.html.ejs", {
									idYouTube: id,
									width: width,
									height: height,
									ytclass: _class,
									style: style,
									frameborder: "0",
									yturl: url.format(yturl)
								});
							}
						
							if (elemYT.name /* .prop('tagName') */ === 'youtube-video') {
								akasha.partial("youtube-embed.html.ejs", {
									title: item ? item.snippet.title : "",
									html: player,
									author_url: item 
											? ("http://youtube.com/user/"+ item.snippet.channelTitle +"/videos") 
											: "",
									author_name: item ? item.snippet.channelTitle : ""
								}, function(err, embed) {
									if (err) { logger.error(err); next(err); }
									else {
										$(elemYT).replaceWith(embed);
										next();
									}
								});
							} else if (elemYT.name /* .prop('tagName') */ === 'youtube-video-embed') {
								$(elemYT).replaceWith(player);
								next();
							} else if (elemYT.name /* .prop('tagName') */ === 'youtube-thumbnail') {
								var thumbs = item ? item.snippet.thumbnails : undefined;
								// if (_class === 'embed-yt-video') _class = 'embed-yt-thumb';
								var align = $(elemYT).attr('align')
									? $(elemYT).attr('align')
									: undefined;
								if (!width) width = "100%";
								
								akasha.partial("youtube-thumb.html.ejs", {
									imgwidth: width,
									imgalign: align,
									imgclass: _class,
									style: style,
									imgurl: ytBestThumbnail(thumbs)
								}, function(err, thumb) {
									if (err) { logger.error(err); next(err); }
									else {
										// logger.trace('youtube-thumb '+ thumb);
										$(elemYT).replaceWith(thumb);
										next();
									}
								});
							} else next(new Error("didn't match -video or -video-embed or -thumbnail "+ elemYT.name));
                        } else next(new Error("No match for youtube id="+ id));
                    });
                }
            }, function(err) {
                if (err) done(err);
                else done();
            });
        });
        
        config.mahabhuta.push(function($, metadata, dirty, done) {
            // <youtube-metadata id="" href=".."/>  
            var elemsYT = [];
            $('youtube-metadata').each(function(i, elem) { elemsYT[i] = elem; });
            async.eachSeries(elemsYT, function(elemYT, next) {
                logger.trace(elemYT.name);
                var id = ytGetId($, elemYT);
                if (!id) {
                    next(new Error("No Youtube ID"));
                } else {
                    ytVidInfo(id, function(resultData) {
                        var result = resultData;
                        var item = result.items[0];
                        var thumbs = item ? item.snippet.thumbnails : undefined;
                        if (!item) {
                        	next(new Error("Youtube didn't get anything for id="+ id));
                        } else if ($('head').get(0)) {
                            // Only do this substitution if we are on a completely rendered page
                            $('head').append(
                                '<meta property="og:image" content="'+ ytBestThumbnail(thumbs) +'"/>\n' +
                                '<meta name="twitter:image" content="'+ ytBestThumbnail(thumbs) +'"/>\n'
                            );
                            $(elemYT).replaceWith('');
                            next();
                        } else next();
                    });
                }
            }, function(err) {
                if (err) done(err);
                else done();
            });
        });
        config.mahabhuta.push(function($, metadata, dirty, done) {
            // <youtube-title id="" href=".."/>  
            var elemsYT = [];
            $('youtube-title').each(function(i, elem) { elemsYT.push(elem); });
            $('youtube-author').each(function(i, elem) { elemsYT.push(elem); });
            $('youtube-description').each(function(i, elem) { elemsYT.push(elem); });
            $('youtube-publ-date').each(function(i, elem) { elemsYT.push(elem); });
            async.eachSeries(elemsYT, function(elemYT, next) {
                logger.trace(elemYT.name);
                var id = ytGetId($, elemYT);
                if (!id) {
                    next(new Error("No Youtube ID"));
                } else {
                    ytVidInfo(id, function(resultData) {
                        var result = resultData;
                        var item = result.items[0];
                        
                        if (item) {
							if (elemYT.name /* .prop('tagName') */ === 'youtube-title') {
								$(elemYT).replaceWith(item.snippet.title);
								next();
							} else if (elemYT.name /* .prop('tagName') */ === 'youtube-author') {
								$(elemYT).replaceWith(item.snippet.channelTitle);
								next();
							} else if (elemYT.name /* .prop('tagName') */ === 'youtube-description') {
								$(elemYT).replaceWith(item.snippet.description);
								next();
							} else if (elemYT.name /* .prop('tagName') */ === 'youtube-publ-date') {
								// TODO fix this to parse & print nicely
								$(elemYT).replaceWith(item.snippet.publishedAt);
								next();
							} else next(new Error("failed to match -title or -author or -description "+ $(elemYT).name));
						} else next(new Error("nothing found for youtube id="+ id));
                    });
                }
            }, function(err) {
                if (err) done(err);
                else done();
            });
        });
        
        config.mahabhuta.push(function($, metadata, dirty, done) {
        	// <vimeo-player url="..." />
        	// <vimeo-thumb url="..." />
        	// <vimeo-title url="..." />
        	// <vimeo-author url="..." />
        	// <vimeo-description url="..." />
        	
            var elements = [];
            $('vimeo-player').each(function(i, elem) { elements.push(elem); });
            $('vimeo-thumbnail').each(function(i, elem) { elements.push(elem); });
            $('vimeo-title').each(function(i, elem) { elements.push(elem); });
            $('vimeo-author').each(function(i, elem) { elements.push(elem); });
            $('vimeo-description').each(function(i, elem) { elements.push(elem); });
            async.eachSeries(elements, function(element, next) {
            	logger.trace(element.name);
            	vimeoData($(element).attr('url'), function(err, vdata) {
            		if (err) next(err);
            		else {
            			if (element.name === 'vimeo-player') {
            				$(element).replaceWith(vdata.html);
            				next();
            			} else if (element.name === 'vimeo-thumbnail') {
            				
							var width = $(element).attr('width')
								? $(element).attr('width')
								: undefined;
							var height = $(element).attr('height')
								? $(element).attr('height')
								: undefined;
							var _class = $(element).attr('class')
								? $(element).attr('class')
								: undefined;
							var style = $(element).attr('style')
								? $(element).attr('style')
								: undefined;
							var align = $(element).attr('align')
								? $(element).attr('align')
								: undefined;
								
							akasha.partial("youtube-thumb.html.ejs", {
								imgwidth: width,
								imgalign: align,
								imgclass: _class,
								style: style,
								imgurl: vdata.thumbnail_url
							}, function(err, thumb) {
								if (err) { logger.error(err); next(err); }
								else {
									// logger.trace('vimeo-thumbnail '+ thumb);
									$(element).replaceWith(thumb);
									next();
								}
							});
            			} else if (element.name === 'vimeo-title') {
            				$(element).replaceWith(vdata.title);
            				next();
            			} else if (element.name === 'vimeo-author') {
            				$(element).replaceWith(vdata.author_name);
            				next();
            			} else if (element.name === 'vimeo-description') {
            				$(element).replaceWith(vdata.description);
            				next();
            			} else {
            				next();
            			}
            		}
            	});
            },
            function(err) {
            	if (err) done(err); else done();
            });
        });
        
        config.mahabhuta.push(function($, metadata, dirty, done) {
            // <oembed href="..." optional: template="..."/>
            logger.trace('oembed');
            var elemsOE = [];
            $('oembed').each(function(i, elem) { elemsOE[i] = elem; });
            // util.log(util.inspect(elemsOE));
            async.eachSeries(elemsOE, function(elemOE, next) {
                // util.log(util.inspect(elemOE));
                akasha.oembedRender({
                    template: $(elemOE).attr('template'),
                    url: $(elemOE).attr("href")
                }, function(err, html) {
                    if (err) next(err);
                    else { 
                        $(elemOE).replaceWith(html);
                        next();
                    }
                });
            }, function(err) {
                if (err) done(err);
                else done();
            });
        });
{'fraction_non_alphanumeric': 0.1698971752747902, 'fraction_numerical': 0.0019501240988062877, 'mean_word_length': 1.7565564424173319, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 27, 'https://': 2, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1125805', 'n_tokens_mistral': 13070, 'n_tokens_neox': 10051, 'n_words': 1883}