├── .gitignore ├── Inferno_CSE546Midterm.pdf ├── Project Proposal Final.pdf ├── hadoopjars ├── youtubeview.jar ├── youtubecategory.jar └── youtubeuploader.jar ├── Inferno - CSE546Midterm.ppt ├── Inferno - Project Presentation.ppt ├── WebContent ├── public │ ├── images │ │ ├── pic01.jpg │ │ ├── pic02.jpg │ │ ├── pic03.jpg │ │ ├── pic04.jpg │ │ ├── pic05.jpg │ │ ├── pic06.jpg │ │ ├── pic07.jpg │ │ ├── pic08.jpg │ │ ├── pic09.jpg │ │ ├── pic10.jpg │ │ ├── pic11.jpg │ │ ├── ajax-loader.gif │ │ └── ajax-loader-analyze.gif │ ├── assets │ │ ├── fonts │ │ │ ├── FontAwesome.otf │ │ │ ├── fontawesome-webfont.eot │ │ │ ├── fontawesome-webfont.ttf │ │ │ ├── fontawesome-webfont.woff │ │ │ └── fontawesome-webfont.woff2 │ │ ├── sass │ │ │ ├── components │ │ │ │ ├── _icon.scss │ │ │ │ ├── _box.scss │ │ │ │ ├── _mini-posts.scss │ │ │ │ ├── _section.scss │ │ │ │ ├── _image.scss │ │ │ │ ├── _table.scss │ │ │ │ ├── _button.scss │ │ │ │ ├── _features.scss │ │ │ │ ├── _posts.scss │ │ │ │ ├── _list.scss │ │ │ │ └── _form.scss │ │ │ ├── layout │ │ │ │ ├── _wrapper.scss │ │ │ │ ├── _footer.scss │ │ │ │ ├── _header.scss │ │ │ │ ├── _main.scss │ │ │ │ ├── _banner.scss │ │ │ │ ├── _menu.scss │ │ │ │ └── _sidebar.scss │ │ │ ├── ie8.scss │ │ │ ├── libs │ │ │ │ ├── _functions.scss │ │ │ │ ├── _vars.scss │ │ │ │ ├── _mixins.scss │ │ │ │ └── _skel.scss │ │ │ ├── base │ │ │ │ ├── _page.scss │ │ │ │ └── _typography.scss │ │ │ ├── ie9.scss │ │ │ └── main.scss │ │ ├── css │ │ │ ├── ie8.css │ │ │ └── ie9.css │ │ └── js │ │ │ ├── jquery.backtotop.js │ │ │ ├── jquery.mobilemenu.js │ │ │ ├── getdatahelper.js │ │ │ ├── ie │ │ │ ├── html5shiv.js │ │ │ └── respond.min.js │ │ │ ├── jquery.placeholder.min.js │ │ │ ├── jquery.easypiechart.min.js │ │ │ ├── main.js │ │ │ ├── analyzehelper.js │ │ │ ├── skel.min.js │ │ │ └── util.js │ ├── index.html │ ├── projectdescription.html │ ├── aboutus.html │ ├── getdata.html │ └── stats.html ├── .idea │ ├── vcs.xml │ ├── modules.xml │ ├── YouTube-Data-Analysis.iml │ └── workspace.xml ├── package.json ├── app.js └── controllers │ └── searchapi.js ├── youtubeviews ├── bin │ └── youtubeviews │ │ ├── Topviewed.class │ │ ├── Topviewed$Map.class │ │ └── Topviewed$Reduce.class ├── .project ├── .settings │ └── org.eclipse.jdt.core.prefs ├── src │ └── youtubeviews │ │ └── Topviewed.java └── .classpath ├── youtubecategory ├── bin │ └── youtubecategory │ │ ├── Topcategory.class │ │ ├── Topcategory$Map.class │ │ └── Topcategory$Reduce.class ├── .project ├── .settings │ └── org.eclipse.jdt.core.prefs ├── src │ └── youtubecategory │ │ └── Topcategory.java └── .classpath ├── youtubeuploader ├── bin │ └── youtubeuploader │ │ ├── Youtubetopuploader.class │ │ ├── Youtubetopuploader$Map.class │ │ └── Youtubetopuploader$Reduce.class ├── .project ├── .settings │ └── org.eclipse.jdt.core.prefs ├── src │ └── youtubeuploader │ │ └── Youtubetopuploader.java └── .classpath ├── scripts ├── getdata.sh └── analyzedata.sh └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | #node modules 2 | 3 | node_modules 4 | 5 | #Outputfile 6 | 7 | *.csv 8 | 9 | *.tsv -------------------------------------------------------------------------------- /Inferno_CSE546Midterm.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitmathur89/YouTube-Data-Analysis/HEAD/Inferno_CSE546Midterm.pdf -------------------------------------------------------------------------------- /Project Proposal Final.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitmathur89/YouTube-Data-Analysis/HEAD/Project Proposal Final.pdf -------------------------------------------------------------------------------- /hadoopjars/youtubeview.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitmathur89/YouTube-Data-Analysis/HEAD/hadoopjars/youtubeview.jar -------------------------------------------------------------------------------- /Inferno - CSE546Midterm.ppt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitmathur89/YouTube-Data-Analysis/HEAD/Inferno - CSE546Midterm.ppt -------------------------------------------------------------------------------- /hadoopjars/youtubecategory.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitmathur89/YouTube-Data-Analysis/HEAD/hadoopjars/youtubecategory.jar -------------------------------------------------------------------------------- /hadoopjars/youtubeuploader.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitmathur89/YouTube-Data-Analysis/HEAD/hadoopjars/youtubeuploader.jar -------------------------------------------------------------------------------- /Inferno - Project Presentation.ppt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitmathur89/YouTube-Data-Analysis/HEAD/Inferno - Project Presentation.ppt -------------------------------------------------------------------------------- /WebContent/public/images/pic01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitmathur89/YouTube-Data-Analysis/HEAD/WebContent/public/images/pic01.jpg -------------------------------------------------------------------------------- /WebContent/public/images/pic02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitmathur89/YouTube-Data-Analysis/HEAD/WebContent/public/images/pic02.jpg -------------------------------------------------------------------------------- /WebContent/public/images/pic03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitmathur89/YouTube-Data-Analysis/HEAD/WebContent/public/images/pic03.jpg -------------------------------------------------------------------------------- /WebContent/public/images/pic04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitmathur89/YouTube-Data-Analysis/HEAD/WebContent/public/images/pic04.jpg -------------------------------------------------------------------------------- /WebContent/public/images/pic05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitmathur89/YouTube-Data-Analysis/HEAD/WebContent/public/images/pic05.jpg -------------------------------------------------------------------------------- /WebContent/public/images/pic06.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitmathur89/YouTube-Data-Analysis/HEAD/WebContent/public/images/pic06.jpg -------------------------------------------------------------------------------- /WebContent/public/images/pic07.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitmathur89/YouTube-Data-Analysis/HEAD/WebContent/public/images/pic07.jpg -------------------------------------------------------------------------------- /WebContent/public/images/pic08.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitmathur89/YouTube-Data-Analysis/HEAD/WebContent/public/images/pic08.jpg -------------------------------------------------------------------------------- /WebContent/public/images/pic09.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitmathur89/YouTube-Data-Analysis/HEAD/WebContent/public/images/pic09.jpg -------------------------------------------------------------------------------- /WebContent/public/images/pic10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitmathur89/YouTube-Data-Analysis/HEAD/WebContent/public/images/pic10.jpg -------------------------------------------------------------------------------- /WebContent/public/images/pic11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitmathur89/YouTube-Data-Analysis/HEAD/WebContent/public/images/pic11.jpg -------------------------------------------------------------------------------- /WebContent/public/images/ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitmathur89/YouTube-Data-Analysis/HEAD/WebContent/public/images/ajax-loader.gif -------------------------------------------------------------------------------- /WebContent/public/assets/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitmathur89/YouTube-Data-Analysis/HEAD/WebContent/public/assets/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /youtubeviews/bin/youtubeviews/Topviewed.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitmathur89/YouTube-Data-Analysis/HEAD/youtubeviews/bin/youtubeviews/Topviewed.class -------------------------------------------------------------------------------- /WebContent/public/images/ajax-loader-analyze.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitmathur89/YouTube-Data-Analysis/HEAD/WebContent/public/images/ajax-loader-analyze.gif -------------------------------------------------------------------------------- /youtubeviews/bin/youtubeviews/Topviewed$Map.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitmathur89/YouTube-Data-Analysis/HEAD/youtubeviews/bin/youtubeviews/Topviewed$Map.class -------------------------------------------------------------------------------- /youtubecategory/bin/youtubecategory/Topcategory.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitmathur89/YouTube-Data-Analysis/HEAD/youtubecategory/bin/youtubecategory/Topcategory.class -------------------------------------------------------------------------------- /youtubeviews/bin/youtubeviews/Topviewed$Reduce.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitmathur89/YouTube-Data-Analysis/HEAD/youtubeviews/bin/youtubeviews/Topviewed$Reduce.class -------------------------------------------------------------------------------- /WebContent/public/assets/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitmathur89/YouTube-Data-Analysis/HEAD/WebContent/public/assets/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /WebContent/public/assets/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitmathur89/YouTube-Data-Analysis/HEAD/WebContent/public/assets/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /WebContent/public/assets/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitmathur89/YouTube-Data-Analysis/HEAD/WebContent/public/assets/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /WebContent/public/assets/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitmathur89/YouTube-Data-Analysis/HEAD/WebContent/public/assets/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /youtubecategory/bin/youtubecategory/Topcategory$Map.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitmathur89/YouTube-Data-Analysis/HEAD/youtubecategory/bin/youtubecategory/Topcategory$Map.class -------------------------------------------------------------------------------- /youtubecategory/bin/youtubecategory/Topcategory$Reduce.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitmathur89/YouTube-Data-Analysis/HEAD/youtubecategory/bin/youtubecategory/Topcategory$Reduce.class -------------------------------------------------------------------------------- /youtubeuploader/bin/youtubeuploader/Youtubetopuploader.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitmathur89/YouTube-Data-Analysis/HEAD/youtubeuploader/bin/youtubeuploader/Youtubetopuploader.class -------------------------------------------------------------------------------- /youtubeuploader/bin/youtubeuploader/Youtubetopuploader$Map.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitmathur89/YouTube-Data-Analysis/HEAD/youtubeuploader/bin/youtubeuploader/Youtubetopuploader$Map.class -------------------------------------------------------------------------------- /youtubeuploader/bin/youtubeuploader/Youtubetopuploader$Reduce.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arpitmathur89/YouTube-Data-Analysis/HEAD/youtubeuploader/bin/youtubeuploader/Youtubetopuploader$Reduce.class -------------------------------------------------------------------------------- /WebContent/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /scripts/getdata.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo Running script to copy data from localfile to HDFS; 4 | 5 | /opt/hadoop/bin/hadoop fs -rm hdfs:/data.csv; 6 | 7 | /opt/hadoop/bin/hadoop fs -copyFromLocal '/home/ubuntu/YouTube-Data-Analysis/WebContent/data.csv' hdfs:/ 8 | -------------------------------------------------------------------------------- /WebContent/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /WebContent/public/assets/sass/components/_icon.scss: -------------------------------------------------------------------------------- 1 | /// 2 | /// Editorial by HTML5 UP 3 | /// html5up.net | @ajlkn 4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | /// 6 | 7 | /* Icon */ 8 | 9 | .icon { 10 | @include icon; 11 | border-bottom: none; 12 | position: relative; 13 | 14 | > .label { 15 | display: none; 16 | } 17 | } -------------------------------------------------------------------------------- /WebContent/public/assets/sass/layout/_wrapper.scss: -------------------------------------------------------------------------------- 1 | /// 2 | /// Editorial by HTML5 UP 3 | /// html5up.net | @ajlkn 4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | /// 6 | 7 | /* Wrapper */ 8 | 9 | #wrapper { 10 | @include vendor('display', 'flex'); 11 | @include vendor('flex-direction', 'row-reverse'); 12 | min-height: 100vh; 13 | } -------------------------------------------------------------------------------- /WebContent/public/assets/sass/layout/_footer.scss: -------------------------------------------------------------------------------- 1 | /// 2 | /// Editorial by HTML5 UP 3 | /// html5up.net | @ajlkn 4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | /// 6 | 7 | /* Footer */ 8 | 9 | #footer { 10 | .copyright { 11 | color: _palette(fg-light); 12 | font-size: 0.9em; 13 | 14 | a { 15 | color: inherit; 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /WebContent/public/assets/css/ie8.css: -------------------------------------------------------------------------------- 1 | /* 2 | Editorial by HTML5 UP 3 | html5up.net | @ajlkn 4 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | */ 6 | 7 | /* Button */ 8 | 9 | input[type="submit"], 10 | input[type="reset"], 11 | input[type="button"], 12 | button, 13 | .button { 14 | border: solid 2px #f56a6a; 15 | } 16 | 17 | /* Posts */ 18 | 19 | .posts article { 20 | width: 40%; 21 | } -------------------------------------------------------------------------------- /youtubeviews/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | youtubeviews 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /youtubecategory/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | youtubecategory 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /youtubeuploader/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | youtubeuploader 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /WebContent/.idea/YouTube-Data-Analysis.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /WebContent/public/assets/sass/ie8.scss: -------------------------------------------------------------------------------- 1 | @import 'libs/vars'; 2 | @import 'libs/functions'; 3 | @import 'libs/mixins'; 4 | @import 'libs/skel'; 5 | 6 | /* 7 | Editorial by HTML5 UP 8 | html5up.net | @ajlkn 9 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 10 | */ 11 | 12 | /* Button */ 13 | 14 | input[type="submit"], 15 | input[type="reset"], 16 | input[type="button"], 17 | button, 18 | .button { 19 | border: solid 2px _palette(accent); 20 | } 21 | 22 | /* Posts */ 23 | 24 | .posts { 25 | article { 26 | width: 40%; 27 | } 28 | } -------------------------------------------------------------------------------- /WebContent/public/assets/sass/components/_box.scss: -------------------------------------------------------------------------------- 1 | /// 2 | /// Editorial by HTML5 UP 3 | /// html5up.net | @ajlkn 4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | /// 6 | 7 | /* Box */ 8 | 9 | .box { 10 | border-radius: _size(border-radius); 11 | border: solid 1px _palette(border); 12 | margin-bottom: _size(element-margin); 13 | padding: 1.5em; 14 | 15 | > :last-child, 16 | > :last-child > :last-child, 17 | > :last-child > :last-child > :last-child { 18 | margin-bottom: 0; 19 | } 20 | 21 | &.alt { 22 | border: 0; 23 | border-radius: 0; 24 | padding: 0; 25 | } 26 | } -------------------------------------------------------------------------------- /youtubeviews/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 4 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 5 | org.eclipse.jdt.core.compiler.compliance=1.7 6 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 7 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 8 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 9 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 10 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 11 | org.eclipse.jdt.core.compiler.source=1.7 12 | -------------------------------------------------------------------------------- /youtubecategory/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 4 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 5 | org.eclipse.jdt.core.compiler.compliance=1.7 6 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 7 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 8 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 9 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 10 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 11 | org.eclipse.jdt.core.compiler.source=1.7 12 | -------------------------------------------------------------------------------- /youtubeuploader/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 4 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 5 | org.eclipse.jdt.core.compiler.compliance=1.7 6 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 7 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 8 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 9 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 10 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 11 | org.eclipse.jdt.core.compiler.source=1.7 12 | -------------------------------------------------------------------------------- /WebContent/public/assets/js/jquery.backtotop.js: -------------------------------------------------------------------------------- 1 | /* 2 | Template Name: Splash 3 | Author: OS Templates 4 | Author URI: http://www.os-templates.com/ 5 | Licence: Free to use under our free template licence terms 6 | Licence URI: http://www.os-templates.com/template-terms 7 | File: Back to Top JS 8 | */ 9 | 10 | jQuery("#backtotop").click(function () { 11 | jQuery("body,html").animate({ 12 | scrollTop: 0 13 | }, 600); 14 | }); 15 | jQuery(window).scroll(function () { 16 | if (jQuery(window).scrollTop() > 150) { 17 | jQuery("#backtotop").addClass("visible"); 18 | } else { 19 | jQuery("#backtotop").removeClass("visible"); 20 | } 21 | }); -------------------------------------------------------------------------------- /WebContent/public/assets/sass/components/_mini-posts.scss: -------------------------------------------------------------------------------- 1 | /// 2 | /// Editorial by HTML5 UP 3 | /// html5up.net | @ajlkn 4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | /// 6 | 7 | /* Mini Posts */ 8 | 9 | .mini-posts { 10 | article { 11 | border-top: solid 1px _palette(border); 12 | margin-top: _size(element-margin); 13 | padding-top: _size(element-margin); 14 | 15 | .image { 16 | display: block; 17 | margin: 0 0 (_size(element-margin) * 0.75) 0; 18 | 19 | img { 20 | display: block; 21 | width: 100%; 22 | } 23 | } 24 | 25 | &:first-child { 26 | border-top: 0; 27 | margin-top: 0; 28 | padding-top: 0; 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /WebContent/public/assets/sass/libs/_functions.scss: -------------------------------------------------------------------------------- 1 | /// Gets a duration value. 2 | /// @param {string} $keys Key(s). 3 | /// @return {string} Value. 4 | @function _duration($keys...) { 5 | @return val($duration, $keys...); 6 | } 7 | 8 | /// Gets a font value. 9 | /// @param {string} $keys Key(s). 10 | /// @return {string} Value. 11 | @function _font($keys...) { 12 | @return val($font, $keys...); 13 | } 14 | 15 | /// Gets a misc value. 16 | /// @param {string} $keys Key(s). 17 | /// @return {string} Value. 18 | @function _misc($keys...) { 19 | @return val($misc, $keys...); 20 | } 21 | 22 | /// Gets a palette value. 23 | /// @param {string} $keys Key(s). 24 | /// @return {string} Value. 25 | @function _palette($keys...) { 26 | @return val($palette, $keys...); 27 | } 28 | 29 | /// Gets a size value. 30 | /// @param {string} $keys Key(s). 31 | /// @return {string} Value. 32 | @function _size($keys...) { 33 | @return val($size, $keys...); 34 | } -------------------------------------------------------------------------------- /WebContent/public/assets/sass/components/_section.scss: -------------------------------------------------------------------------------- 1 | /// 2 | /// Editorial by HTML5 UP 3 | /// html5up.net | @ajlkn 4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | /// 6 | 7 | /* Section/Article */ 8 | 9 | section, article { 10 | &.special { 11 | text-align: center; 12 | } 13 | } 14 | 15 | header { 16 | p { 17 | font-family: _font(family-heading); 18 | font-size: 1em; 19 | font-weight: _font(weight-heading-alt); 20 | letter-spacing: _font(kerning-heading); 21 | margin-top: -0.5em; 22 | text-transform: uppercase; 23 | } 24 | 25 | &.major { 26 | > :last-child { 27 | border-bottom: solid 3px _palette(accent); 28 | display: inline-block; 29 | margin: 0 0 _size(element-margin) 0; 30 | padding: 0 0.75em 0.5em 0; 31 | } 32 | } 33 | 34 | &.main { 35 | > :last-child { 36 | margin: 0 0 (_size(element-margin) * 0.5) 0; 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /WebContent/public/assets/sass/base/_page.scss: -------------------------------------------------------------------------------- 1 | /// 2 | /// Editorial by HTML5 UP 3 | /// html5up.net | @ajlkn 4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | /// 6 | 7 | /* Basic */ 8 | 9 | // MSIE: Required for IEMobile. 10 | @-ms-viewport { 11 | width: device-width; 12 | } 13 | 14 | // MSIE: Prevents scrollbar from overlapping content. 15 | body { 16 | -ms-overflow-style: scrollbar; 17 | } 18 | 19 | // Ensures page width is always >=320px. 20 | @include breakpoint(xsmall) { 21 | html, body { 22 | min-width: 320px; 23 | } 24 | } 25 | 26 | body { 27 | background: _palette(bg); 28 | 29 | // Prevents animation/transition "flicker". 30 | // Automatically added/removed by js/main.js. 31 | &.is-loading, 32 | &.is-resizing { 33 | *, *:before, *:after { 34 | @include vendor('animation', 'none !important'); 35 | @include vendor('transition', 'none !important'); 36 | } 37 | } 38 | 39 | } -------------------------------------------------------------------------------- /WebContent/public/assets/sass/libs/_vars.scss: -------------------------------------------------------------------------------- 1 | // Misc. 2 | $misc: ( 3 | z-index-base: 10000 4 | ); 5 | 6 | // Duration. 7 | $duration: ( 8 | nav: 0.5s, 9 | transition: 0.2s 10 | ); 11 | 12 | // Size. 13 | $size: ( 14 | border-radius: 0.375em, 15 | element-height: 2.75em, 16 | element-margin: 2em, 17 | sidebar-width: 26em, 18 | sidebar-width-alt: 24em, 19 | gutter: 3em 20 | ); 21 | 22 | // Font. 23 | $font: ( 24 | family: ('Open Sans', sans-serif), 25 | family-heading: ('Roboto Slab', serif), 26 | family-fixed: ('Courier New', monospace), 27 | weight: 400, 28 | weight-bold: 600, 29 | weight-heading: 700, 30 | weight-heading-alt: 400, 31 | kerning-heading: 0.075em 32 | ); 33 | 34 | // Palette. 35 | $palette: ( 36 | bg: #ffffff, 37 | bg-alt: #f5f6f7, 38 | fg: #7f888f, 39 | fg-bold: #3d4449, 40 | fg-light: #9fa3a6, 41 | border: rgba(210,215,217,0.75), 42 | border-bg: transparentize(#e6ebed, 0.75), 43 | accent: #f56a6a 44 | ); -------------------------------------------------------------------------------- /WebContent/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "youtube-data-analysis", 3 | "version": "1.0.0", 4 | "description": "Required node modules to run this project", 5 | "main": "app.js", 6 | "dependencies": { 7 | "async": "^2.1.1", 8 | "csv-write-stream": "^2.0.0", 9 | "express": "^4.14.0", 10 | "json2csv": "^3.7.0", 11 | "socket.io": "^1.5.1", 12 | "youtube-api": "^2.0.4" 13 | }, 14 | "devDependencies": {}, 15 | "scripts": { 16 | "test": "echo \"Error: no test specified\" && exit 1" 17 | }, 18 | "repository": { 19 | "type": "git", 20 | "url": "git+https://github.com/arpitmathur89/YouTube-Data-Analysis.git" 21 | }, 22 | "keywords": [ 23 | "youtube-data-api", 24 | "hadoop", 25 | "map-reduce", 26 | "cloud-computing" 27 | ], 28 | "author": "Arpit Mathur", 29 | "license": "ISC", 30 | "bugs": { 31 | "url": "https://github.com/arpitmathur89/YouTube-Data-Analysis/issues" 32 | }, 33 | "homepage": "https://github.com/arpitmathur89/YouTube-Data-Analysis#readme" 34 | } 35 | -------------------------------------------------------------------------------- /WebContent/public/assets/sass/layout/_header.scss: -------------------------------------------------------------------------------- 1 | /// 2 | /// Editorial by HTML5 UP 3 | /// html5up.net | @ajlkn 4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | /// 6 | 7 | /* Header */ 8 | 9 | #header { 10 | @include vendor('display', 'flex'); 11 | border-bottom: solid 5px _palette(accent); 12 | padding: 6em 0 1em 0; 13 | position: relative; 14 | 15 | > * { 16 | @include vendor('flex', '1'); 17 | margin-bottom: 0; 18 | } 19 | 20 | .logo { 21 | border-bottom: 0; 22 | color: inherit; 23 | font-family: _font(family-heading); 24 | font-size: 1.125em; 25 | } 26 | 27 | .icons { 28 | text-align: right; 29 | } 30 | 31 | @include breakpoint(xlarge) { 32 | padding-top: 5em; 33 | } 34 | 35 | @include breakpoint(small) { 36 | padding-top: 6.5em; 37 | 38 | .logo { 39 | font-size: 1.25em; 40 | margin: 0; 41 | } 42 | 43 | .icons { 44 | height: (6.25em / 1.25); 45 | line-height: (6.25em / 1.25); 46 | position: absolute; 47 | right: (-0.625em / 1.25); 48 | top: 0; 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /WebContent/public/assets/sass/layout/_main.scss: -------------------------------------------------------------------------------- 1 | /// 2 | /// Editorial by HTML5 UP 3 | /// html5up.net | @ajlkn 4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | /// 6 | 7 | /* Main */ 8 | 9 | #main { 10 | @include vendor('flex-grow', '1'); 11 | @include vendor('flex-shrink', '1'); 12 | width: 100%; 13 | 14 | > .inner { 15 | @include padding(0, 6em); 16 | margin: 0 auto; 17 | max-width: 110em; 18 | 19 | > section { 20 | @include padding(6em, 0); 21 | border-top: solid 2px _palette(border); 22 | 23 | &:first-of-type { 24 | border-top: 0 !important; 25 | } 26 | } 27 | } 28 | 29 | @include breakpoint(xlarge) { 30 | > .inner { 31 | @include padding(0, 5em); 32 | 33 | > section { 34 | @include padding(5em, 0); 35 | } 36 | } 37 | } 38 | 39 | @include breakpoint(large) { 40 | > .inner { 41 | @include padding(0, 4em); 42 | 43 | > section { 44 | @include padding(4em, 0); 45 | } 46 | } 47 | } 48 | 49 | @include breakpoint(small) { 50 | > .inner { 51 | @include padding(0, 2em); 52 | 53 | > section { 54 | @include padding(3em, 0); 55 | } 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /WebContent/public/assets/css/ie9.css: -------------------------------------------------------------------------------- 1 | /* 2 | Editorial by HTML5 UP 3 | html5up.net | @ajlkn 4 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | */ 6 | 7 | /* Features */ 8 | 9 | .features:after { 10 | clear: both; 11 | content: ''; 12 | display: block; 13 | } 14 | 15 | .features article { 16 | float: left; 17 | } 18 | 19 | .features article:after { 20 | clear: both; 21 | content: ''; 22 | display: block; 23 | } 24 | 25 | .features article .icon { 26 | float: left; 27 | } 28 | 29 | /* Posts */ 30 | 31 | .posts:after { 32 | clear: both; 33 | content: ''; 34 | display: block; 35 | } 36 | 37 | .posts article { 38 | float: left; 39 | } 40 | 41 | /* Main */ 42 | 43 | #main { 44 | padding-left: 24em; 45 | } 46 | 47 | /* Sidebar */ 48 | 49 | #sidebar { 50 | position: absolute; 51 | top: 0; 52 | left: 0; 53 | min-height: 100%; 54 | width: 24em; 55 | } 56 | 57 | /* Banner */ 58 | 59 | #banner:after { 60 | clear: both; 61 | content: ''; 62 | display: block; 63 | } 64 | 65 | #banner .content { 66 | float: left; 67 | padding-right: 4em; 68 | } 69 | 70 | #banner .image { 71 | float: left; 72 | margin-left: 0; 73 | } -------------------------------------------------------------------------------- /WebContent/public/assets/js/jquery.mobilemenu.js: -------------------------------------------------------------------------------- 1 | /* 2 | Template Name: Splash 3 | Author: OS Templates 4 | Author URI: http://www.os-templates.com/ 5 | Licence: Free to use under our free template licence terms 6 | Licence URI: http://www.os-templates.com/template-terms 7 | File: Mobile Menu JS 8 | 9 | Thanks to: 10 | "Convert a Menu to a Dropdown for Small Screens" from Chris Collier - http://css-tricks.com/convert-menu-to-dropdown/ 11 | "Submenu's with a dash" Daryn St. Pierre - http://jsfiddle.net/bloqhead/Kq43X/ 12 | */ 13 | 14 | $('
").attr(a.extend(b(this),{type:"text"}))}d.removeAttr("name").data({"placeholder-password":f,"placeholder-id":g}).bind("focus.placeholder",c),f.data({"placeholder-textinput":d,"placeholder-id":g}).before(d)}f=f.removeAttr("id").hide().prevAll('input[type="text"]:first').attr("id",g).show()}f.addClass(m.customClass),f[0].value=f.attr("placeholder")}else f.removeClass(m.customClass)}function e(){try{return document.activeElement}catch(a){}}var f,g,h="[object OperaMini]"==Object.prototype.toString.call(window.operamini),i="placeholder"in document.createElement("input")&&!h,j="placeholder"in document.createElement("textarea")&&!h,k=a.valHooks,l=a.propHooks;if(i&&j)g=a.fn.placeholder=function(){return this},g.input=g.textarea=!0;else{var m={};g=a.fn.placeholder=function(b){var e={customClass:"placeholder"};m=a.extend({},e,b);var f=this;return f.filter((i?"textarea":":input")+"[placeholder]").not("."+m.customClass).bind({"focus.placeholder":c,"blur.placeholder":d}).data("placeholder-enabled",!0).trigger("blur.placeholder"),f},g.input=i,g.textarea=j,f={get:function(b){var c=a(b),d=c.data("placeholder-password");return d?d[0].value:c.data("placeholder-enabled")&&c.hasClass(m.customClass)?"":b.value},set:function(b,f){var g=a(b),h=g.data("placeholder-password");return h?h[0].value=f:g.data("placeholder-enabled")?(""===f?(b.value=f,b!=e()&&d.call(b)):g.hasClass(m.customClass)?c.call(b,!0,f)||(b.value=f):b.value=f,g):b.value=f}},i||(k.input=f,l.value=f),j||(k.textarea=f,l.value=f),a(function(){a(document).delegate("form","submit.placeholder",function(){var b=a("."+m.customClass,this).each(c);setTimeout(function(){b.each(d)},10)})}),a(window).bind("beforeunload.placeholder",function(){a("."+m.customClass).each(function(){this.value=""})})}}); 6 | 7 | // Run It 8 | jQuery(document).ready(function($) { 9 | $("input, textarea").placeholder(); 10 | }); -------------------------------------------------------------------------------- /youtubeviews/src/youtubeviews/Topviewed.java: -------------------------------------------------------------------------------- 1 | package youtubeviews; 2 | import java.io.IOException; 3 | 4 | import org.apache.hadoop.io.IntWritable; 5 | import org.apache.hadoop.io.LongWritable; 6 | import org.apache.hadoop.io.Text; 7 | import org.apache.hadoop.mapreduce.Mapper; 8 | import org.apache.hadoop.mapreduce.Reducer; 9 | import org.apache.hadoop.conf.Configuration; 10 | import org.apache.hadoop.mapreduce.Job; 11 | import org.apache.hadoop.mapreduce.lib.input.TextInputFormat; 12 | import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat; 13 | import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; 14 | import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; 15 | import org.apache.hadoop.fs.Path; 16 | 17 | public class Topviewed { 18 | public static class Map extends Mapper { 20 | 21 | private Text video_name = new Text(); 22 | private IntWritable views = new IntWritable(); 23 | public void map(LongWritable key, Text value, Context context ) 24 | throws IOException, InterruptedException { 25 | String line = value.toString(); 26 | String str[]=line.split(","); 27 | 28 | if(str.length >= 5){ 29 | video_name.set(str[0]); 30 | str[5]=str[5].replace("\"", ""); 31 | if(str[5].matches("\\d+")){ //this regular expression specifies that the string should contain only integer values 32 | int temp=Integer.parseInt(str[5]); //typecasting string to Integer 33 | views.set(temp); 34 | } 35 | } 36 | 37 | context.write(video_name, views); 38 | } 39 | 40 | } 41 | public static class Reduce extends Reducer { 43 | 44 | public void reduce(Text key, Iterable values, Context context) 45 | throws IOException, InterruptedException { 46 | int sum = 0; 47 | for (IntWritable val : values) { 48 | sum += val.get(); 49 | } 50 | context.write(key, new IntWritable(sum)); 51 | } 52 | } 53 | 54 | @SuppressWarnings("deprecation") 55 | public static void main(String[] args) throws Exception { 56 | Configuration conf = new Configuration(); 57 | Job job = new Job(conf, "videorating"); 58 | job.setJarByClass(Topviewed.class); 59 | job.setMapOutputKeyClass(Text.class); 60 | job.setMapOutputValueClass(IntWritable.class); 61 | job.setOutputKeyClass(Text.class); 62 | job.setOutputValueClass(IntWritable.class); 63 | job.setMapperClass(Map.class); 64 | job.setReducerClass(Reduce.class); 65 | job.setInputFormatClass(TextInputFormat.class); 66 | job.setOutputFormatClass(TextOutputFormat.class); 67 | FileInputFormat.addInputPath(job, new Path(args[0])); 68 | FileOutputFormat.setOutputPath(job, new Path(args[1])); 69 | job.waitForCompletion(true); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /youtubeuploader/src/youtubeuploader/Youtubetopuploader.java: -------------------------------------------------------------------------------- 1 | package youtubeuploader; 2 | import java.io.IOException; 3 | import org.apache.hadoop.io.IntWritable; 4 | import org.apache.hadoop.io.LongWritable; 5 | import org.apache.hadoop.io.Text; 6 | import org.apache.hadoop.mapreduce.Mapper; 7 | import org.apache.hadoop.mapreduce.Reducer; 8 | //import org.apache.hadoop.mapreduce.Reducer.Context; 9 | import org.apache.hadoop.conf.Configuration; 10 | import org.apache.hadoop.mapreduce.Job; 11 | import org.apache.hadoop.mapreduce.lib.input.TextInputFormat; 12 | import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat; 13 | import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; 14 | import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; 15 | import org.apache.hadoop.fs.Path; 16 | 17 | public class Youtubetopuploader { 18 | public static class Map extends Mapper{ 19 | private Text uploader = new Text(); 20 | private final static IntWritable occurance = new IntWritable(1); 21 | public void map(LongWritable key, Text value, 22 | Context context) throws IOException,InterruptedException { 23 | 24 | String record = value.toString(); 25 | String str[] = record.split(","); 26 | if(str.length>=7){ 27 | uploader.set(str[7]); 28 | } 29 | context.write(uploader, occurance); 30 | } 31 | } 32 | 33 | public static class Reduce extends Reducer{ 34 | 35 | public void reduce(Text key, Iterable values, 36 | Context context) throws IOException,InterruptedException { 37 | int totaloccurance = 0; 38 | 39 | for(IntWritable value: values) 40 | { 41 | totaloccurance+=value.get(); 42 | } 43 | context.write(key, new IntWritable(totaloccurance)); 44 | 45 | } 46 | 47 | } 48 | 49 | public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException { 50 | // TODO Auto-generated method stub 51 | // TODO Auto-generated method stub 52 | 53 | //JobConf conf = new JobConf(WordCount.class); 54 | Configuration conf1= new Configuration(); 55 | 56 | 57 | //conf.setJobName("mywc"); 58 | @SuppressWarnings("deprecation") 59 | Job job = new Job(conf1,"myyoutube"); 60 | 61 | job.setJarByClass(Youtubetopuploader.class); 62 | job.setMapperClass(Map.class); 63 | job.setReducerClass(Reduce.class); 64 | 65 | //conf.setMapperClass(Map.class); 66 | //conf.setReducerClass(Reduce.class); 67 | 68 | job.setOutputKeyClass(Text.class); 69 | job.setOutputValueClass(IntWritable.class); 70 | 71 | job.setInputFormatClass(TextInputFormat.class); 72 | job.setOutputFormatClass(TextOutputFormat.class); 73 | 74 | 75 | 76 | @SuppressWarnings("unused") 77 | Path outputPath = new Path(args[1]); 78 | 79 | //Configuring the input/output path from the filesystem into the job 80 | 81 | FileInputFormat.addInputPath(job, new Path(args[0])); 82 | FileOutputFormat.setOutputPath(job, new Path(args[1])); 83 | 84 | //deleting the output path automatically from hdfs so that we don't have delete it explicitly 85 | 86 | //outputPath.getFileSystem(conf).delete(outputPath); 87 | 88 | //exiting the job only if the flag value becomes false 89 | 90 | System.exit(job.waitForCompletion(true) ? 0 : 1); 91 | } 92 | 93 | 94 | 95 | } 96 | -------------------------------------------------------------------------------- /youtubeviews/.classpath: -------------------------------------------------------------------------------- 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 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /youtubecategory/.classpath: -------------------------------------------------------------------------------- 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 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /youtubeuploader/.classpath: -------------------------------------------------------------------------------- 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 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /WebContent/public/assets/sass/components/_features.scss: -------------------------------------------------------------------------------- 1 | /// 2 | /// Editorial by HTML5 UP 3 | /// html5up.net | @ajlkn 4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | /// 6 | 7 | /* Features */ 8 | 9 | .features { 10 | $gutter: _size(gutter); 11 | 12 | @include vendor('display', 'flex'); 13 | @include vendor('flex-wrap', 'wrap'); 14 | margin: 0 0 _size(element-margin) ($gutter * -1); 15 | width: calc(100% + #{$gutter}); 16 | 17 | article { 18 | @include vendor('align-items', 'center'); 19 | @include vendor('display', 'flex'); 20 | margin: 0 0 $gutter $gutter; 21 | position: relative; 22 | width: calc(50% - #{$gutter}); 23 | 24 | &:nth-child(2n - 1) { 25 | margin-right: ($gutter * 0.5); 26 | } 27 | 28 | &:nth-child(2n) { 29 | margin-left: ($gutter * 0.5); 30 | } 31 | 32 | &:nth-last-child(1), 33 | &:nth-last-child(2) { 34 | margin-bottom: 0; 35 | } 36 | 37 | .icon { 38 | @include vendor('flex-grow', '0'); 39 | @include vendor('flex-shrink', '0'); 40 | display: block; 41 | height: 10em; 42 | line-height: 10em; 43 | margin: 0 _size(element-margin) 0 0; 44 | text-align: center; 45 | width: 10em; 46 | 47 | &:before { 48 | color: _palette(accent); 49 | font-size: 2.75rem; 50 | position: relative; 51 | top: 0.05em; 52 | } 53 | 54 | &:after { 55 | @include vendor('transform', 'rotate(45deg)'); 56 | border-radius: 0.25rem; 57 | border: solid 2px _palette(border); 58 | content: ''; 59 | display: block; 60 | height: 7em; 61 | left: 50%; 62 | margin: -3.5em 0 0 -3.5em; 63 | position: absolute; 64 | top: 50%; 65 | width: 7em; 66 | } 67 | } 68 | 69 | .content { 70 | @include vendor('flex-grow', '1'); 71 | @include vendor('flex-shrink', '1'); 72 | width: 100%; 73 | 74 | > :last-child { 75 | margin-bottom: 0; 76 | } 77 | } 78 | } 79 | 80 | @include breakpoint(medium) { 81 | margin: 0 0 _size(element-margin) 0; 82 | width: 100%; 83 | 84 | article { 85 | margin: 0 0 $gutter 0; 86 | width: 100%; 87 | 88 | &:nth-child(2n - 1) { 89 | margin-right: 0; 90 | } 91 | 92 | &:nth-child(2n) { 93 | margin-left: 0; 94 | } 95 | 96 | &:nth-last-child(1), 97 | &:nth-last-child(2) { 98 | margin-bottom: $gutter; 99 | } 100 | 101 | &:last-child { 102 | margin-bottom: 0; 103 | } 104 | 105 | .icon { 106 | height: 8em; 107 | line-height: 8em; 108 | width: 8em; 109 | 110 | &:before { 111 | font-size: 2.25rem; 112 | } 113 | 114 | &:after { 115 | height: 6em; 116 | margin: -3em 0 0 -3em; 117 | width: 6em; 118 | } 119 | } 120 | } 121 | } 122 | 123 | @include breakpoint(xsmall) { 124 | article { 125 | @include vendor('flex-direction', 'column'); 126 | @include vendor('align-items', 'flex-start'); 127 | 128 | .icon { 129 | height: 6em; 130 | line-height: 6em; 131 | margin: 0 0 (_size(element-margin) * 0.75) 0; 132 | width: 6em; 133 | 134 | &:before { 135 | font-size: 1.5rem; 136 | } 137 | 138 | &:after { 139 | height: 4em; 140 | margin: -2em 0 0 -2em; 141 | width: 4em; 142 | } 143 | } 144 | } 145 | } 146 | 147 | @include breakpoint(xsmall) { 148 | article { 149 | .icon { 150 | &:before { 151 | font-size: 1.25rem; 152 | } 153 | } 154 | } 155 | } 156 | } -------------------------------------------------------------------------------- /WebContent/public/assets/sass/components/_posts.scss: -------------------------------------------------------------------------------- 1 | /// 2 | /// Editorial by HTML5 UP 3 | /// html5up.net | @ajlkn 4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | /// 6 | 7 | /* Posts */ 8 | 9 | .posts { 10 | $gutter: (_size(gutter) * 2); 11 | 12 | @include vendor('display', 'flex'); 13 | @include vendor('flex-wrap', 'wrap'); 14 | margin: 0 0 _size(element-margin) ($gutter * -1); 15 | width: calc(100% + #{$gutter}); 16 | 17 | article { 18 | @include vendor('flex-grow', '0'); 19 | @include vendor('flex-shrink', '1'); 20 | margin: 0 0 $gutter $gutter; 21 | position: relative; 22 | width: calc(#{(100% / 3)} - #{$gutter}); 23 | 24 | &:before { 25 | background: _palette(border); 26 | content: ''; 27 | display: block; 28 | height: calc(100% + #{$gutter}); 29 | left: ($gutter * -0.5); 30 | position: absolute; 31 | top: 0; 32 | width: 1px; 33 | } 34 | 35 | &:after { 36 | background: _palette(border); 37 | bottom: ($gutter * -0.5); 38 | content: ''; 39 | display: block; 40 | height: 1px; 41 | position: absolute; 42 | right: 0; 43 | width: calc(100% + #{$gutter}); 44 | } 45 | 46 | > :last-child { 47 | margin-bottom: 0; 48 | } 49 | 50 | .image { 51 | display: block; 52 | margin: 0 0 _size(element-margin) 0; 53 | 54 | img { 55 | display: block; 56 | width: 100%; 57 | } 58 | } 59 | } 60 | 61 | @include breakpoint(xlarge-to-max) { 62 | article { 63 | &:nth-child(3n + 1) { 64 | &:before { 65 | display: none; 66 | } 67 | 68 | &:after { 69 | width: 100%; 70 | } 71 | } 72 | 73 | &:nth-last-child(1), 74 | &:nth-last-child(2), 75 | &:nth-last-child(3) { 76 | margin-bottom: 0; 77 | 78 | &:before { 79 | height: 100%; 80 | } 81 | 82 | &:after { 83 | display: none; 84 | } 85 | } 86 | } 87 | } 88 | 89 | @include breakpoint(xlarge) { 90 | article { 91 | width: calc(50% - #{$gutter}); 92 | 93 | &:nth-last-child(3) { 94 | margin-bottom: $gutter; 95 | } 96 | } 97 | } 98 | 99 | @include breakpoint(small-to-xlarge) { 100 | article { 101 | &:nth-child(2n + 1) { 102 | &:before { 103 | display: none; 104 | } 105 | 106 | &:after { 107 | width: 100%; 108 | } 109 | } 110 | 111 | &:nth-last-child(1), 112 | &:nth-last-child(2) { 113 | margin-bottom: 0; 114 | 115 | &:before { 116 | height: 100%; 117 | } 118 | 119 | &:after { 120 | display: none; 121 | } 122 | } 123 | } 124 | } 125 | 126 | @include breakpoint(small) { 127 | $gutter: _size(gutter) * 1.5; 128 | 129 | margin: 0 0 _size(element-margin) ($gutter * -1); 130 | width: calc(100% + #{$gutter}); 131 | 132 | article { 133 | margin: 0 0 $gutter $gutter; 134 | width: calc(50% - #{$gutter}); 135 | 136 | &:before { 137 | height: calc(100% + #{$gutter}); 138 | left: ($gutter * -0.5); 139 | } 140 | 141 | &:after { 142 | bottom: ($gutter * -0.5); 143 | width: calc(100% + #{$gutter}); 144 | } 145 | 146 | &:nth-last-child(3) { 147 | margin-bottom: $gutter; 148 | } 149 | } 150 | } 151 | 152 | @include breakpoint(xsmall) { 153 | $gutter: _size(gutter) * 1.5; 154 | 155 | margin: 0 0 _size(element-margin) 0; 156 | width: 100%; 157 | 158 | article { 159 | margin: 0 0 $gutter 0; 160 | width: 100%; 161 | 162 | &:before { 163 | display: none; 164 | } 165 | 166 | &:after { 167 | width: 100%; 168 | } 169 | 170 | &:last-child { 171 | margin-bottom: 0; 172 | 173 | &:after { 174 | display: none; 175 | } 176 | } 177 | } 178 | } 179 | } -------------------------------------------------------------------------------- /WebContent/public/assets/sass/base/_typography.scss: -------------------------------------------------------------------------------- 1 | /// 2 | /// Editorial by HTML5 UP 3 | /// html5up.net | @ajlkn 4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | /// 6 | 7 | /* Type */ 8 | 9 | body, input, select, textarea { 10 | color: _palette(fg); 11 | font-family: _font(family); 12 | font-size: 13pt; 13 | font-weight: _font(weight); 14 | line-height: 1.65; 15 | 16 | @include breakpoint(xlarge) { 17 | font-size: 11pt; 18 | } 19 | 20 | @include breakpoint(large) { 21 | font-size: 10pt; 22 | } 23 | 24 | @include breakpoint(xxsmall) { 25 | font-size: 9pt; 26 | } 27 | } 28 | 29 | a { 30 | @include vendor('transition', ( 31 | 'color #{_duration(transition)} ease-in-out', 32 | 'border-bottom-color #{_duration(transition)} ease-in-out' 33 | )); 34 | border-bottom: dotted 1px; 35 | color: _palette(accent); 36 | text-decoration: none; 37 | 38 | &:hover { 39 | border-bottom-color: _palette(accent); 40 | color: _palette(accent) !important; 41 | 42 | strong { 43 | color: inherit; 44 | } 45 | } 46 | } 47 | 48 | strong, b { 49 | color: _palette(fg-bold); 50 | font-weight: _font(weight-bold); 51 | } 52 | 53 | em, i { 54 | font-style: italic; 55 | } 56 | 57 | p { 58 | margin: 0 0 _size(element-margin) 0; 59 | } 60 | 61 | h1, h2, h3, h4, h5, h6 { 62 | color: _palette(fg-bold); 63 | font-family: _font(family-heading); 64 | font-weight: _font(weight-heading); 65 | line-height: 1.5; 66 | margin: 0 0 (_size(element-margin) * 0.5) 0; 67 | 68 | a { 69 | color: inherit; 70 | text-decoration: none; 71 | } 72 | } 73 | 74 | h1 { 75 | font-size: 4em; 76 | margin: 0 0 (_size(element-margin) * 0.25) 0; 77 | line-height: 1.3; 78 | } 79 | 80 | h2 { 81 | font-size: 1.75em; 82 | } 83 | 84 | h3 { 85 | font-size: 1.25em; 86 | } 87 | 88 | h4 { 89 | font-size: 1.1em; 90 | } 91 | 92 | h5 { 93 | font-size: 0.9em; 94 | } 95 | 96 | h6 { 97 | font-size: 0.7em; 98 | } 99 | 100 | @include breakpoint(xlarge) { 101 | h1 { 102 | font-size: 3.5em; 103 | } 104 | } 105 | 106 | @include breakpoint(medium) { 107 | h1 { 108 | font-size: 3.25em; 109 | } 110 | } 111 | 112 | @include breakpoint(small) { 113 | h1 { 114 | font-size: 2em; 115 | line-height: 1.4; 116 | } 117 | 118 | h2 { 119 | font-size: 1.5em; 120 | } 121 | } 122 | 123 | sub { 124 | font-size: 0.8em; 125 | position: relative; 126 | top: 0.5em; 127 | } 128 | 129 | sup { 130 | font-size: 0.8em; 131 | position: relative; 132 | top: -0.5em; 133 | } 134 | 135 | blockquote { 136 | border-left: solid 3px _palette(border); 137 | font-style: italic; 138 | margin: 0 0 _size(element-margin) 0; 139 | padding: (_size(element-margin) / 4) 0 (_size(element-margin) / 4) _size(element-margin); 140 | } 141 | 142 | code { 143 | background: _palette(border-bg); 144 | border-radius: _size(border-radius); 145 | border: solid 1px _palette(border); 146 | font-family: _font(family-fixed); 147 | font-size: 0.9em; 148 | margin: 0 0.25em; 149 | padding: 0.25em 0.65em; 150 | } 151 | 152 | pre { 153 | -webkit-overflow-scrolling: touch; 154 | font-family: _font(family-fixed); 155 | font-size: 0.9em; 156 | margin: 0 0 _size(element-margin) 0; 157 | 158 | code { 159 | display: block; 160 | line-height: 1.75; 161 | padding: 1em 1.5em; 162 | overflow-x: auto; 163 | } 164 | } 165 | 166 | hr { 167 | border: 0; 168 | border-bottom: solid 1px _palette(border); 169 | margin: _size(element-margin) 0; 170 | 171 | &.major { 172 | margin: (_size(element-margin) * 1.5) 0; 173 | } 174 | } 175 | 176 | .align-left { 177 | text-align: left; 178 | } 179 | 180 | .align-center { 181 | text-align: center; 182 | } 183 | 184 | .align-right { 185 | text-align: right; 186 | } -------------------------------------------------------------------------------- /WebContent/public/assets/sass/components/_list.scss: -------------------------------------------------------------------------------- 1 | /// 2 | /// Editorial by HTML5 UP 3 | /// html5up.net | @ajlkn 4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | /// 6 | 7 | /* List */ 8 | 9 | ol { 10 | list-style: decimal; 11 | margin: 0 0 _size(element-margin) 0; 12 | padding-left: 1.25em; 13 | 14 | li { 15 | padding-left: 0.25em; 16 | } 17 | } 18 | 19 | ul { 20 | list-style: disc; 21 | margin: 0 0 _size(element-margin) 0; 22 | padding-left: 1em; 23 | 24 | li { 25 | padding-left: 0.5em; 26 | } 27 | 28 | &.alt { 29 | list-style: none; 30 | padding-left: 0; 31 | 32 | li { 33 | border-top: solid 1px _palette(border); 34 | padding: 0.5em 0; 35 | 36 | &:first-child { 37 | border-top: 0; 38 | padding-top: 0; 39 | } 40 | } 41 | } 42 | 43 | &.icons { 44 | cursor: default; 45 | list-style: none; 46 | padding-left: 0; 47 | 48 | li { 49 | display: inline-block; 50 | padding: 0 1em 0 0; 51 | 52 | &:last-child { 53 | padding-right: 0; 54 | } 55 | 56 | .icon { 57 | color: inherit; 58 | 59 | &:before { 60 | font-size: 1.25em; 61 | } 62 | } 63 | } 64 | } 65 | 66 | &.contact { 67 | list-style: none; 68 | padding: 0; 69 | 70 | li { 71 | @include icon; 72 | border-top: solid 1px _palette(border); 73 | margin: 1.5em 0 0 0; 74 | padding: 1.5em 0 0 3em; 75 | position: relative; 76 | 77 | &:before { 78 | color: _palette(accent); 79 | display: inline-block; 80 | font-size: 1.5em; 81 | height: 1.125em; 82 | left: 0; 83 | line-height: 1.125em; 84 | position: absolute; 85 | text-align: center; 86 | top: (1.5em / 1.5); 87 | width: 1.5em; 88 | } 89 | 90 | &:first-child { 91 | border-top: 0; 92 | margin-top: 0; 93 | padding-top: 0; 94 | 95 | &:before { 96 | top: 0; 97 | } 98 | } 99 | 100 | a { 101 | color: inherit; 102 | } 103 | } 104 | } 105 | 106 | &.actions { 107 | cursor: default; 108 | list-style: none; 109 | padding-left: 0; 110 | 111 | li { 112 | display: inline-block; 113 | padding: 0 (_size(element-margin) * 0.5) 0 0; 114 | vertical-align: middle; 115 | 116 | &:last-child { 117 | padding-right: 0; 118 | } 119 | } 120 | 121 | &.small { 122 | li { 123 | padding: 0 (_size(element-margin) * 0.25) 0 0; 124 | } 125 | } 126 | 127 | &.vertical { 128 | li { 129 | display: block; 130 | padding: (_size(element-margin) * 0.5) 0 0 0; 131 | 132 | &:first-child { 133 | padding-top: 0; 134 | } 135 | 136 | > * { 137 | margin-bottom: 0; 138 | } 139 | } 140 | 141 | &.small { 142 | li { 143 | padding: (_size(element-margin) * 0.25) 0 0 0; 144 | 145 | &:first-child { 146 | padding-top: 0; 147 | } 148 | } 149 | } 150 | } 151 | 152 | &.fit { 153 | display: table; 154 | margin-left: (_size(element-margin) * -0.5); 155 | padding: 0; 156 | table-layout: fixed; 157 | width: calc(100% + #{(_size(element-margin) * 0.5)}); 158 | 159 | li { 160 | display: table-cell; 161 | padding: 0 0 0 (_size(element-margin) * 0.5); 162 | 163 | > * { 164 | margin-bottom: 0; 165 | } 166 | } 167 | 168 | &.small { 169 | margin-left: (_size(element-margin) * -0.25); 170 | width: calc(100% + #{(_size(element-margin) * 0.25)}); 171 | 172 | li { 173 | padding: 0 0 0 (_size(element-margin) * 0.25); 174 | } 175 | } 176 | } 177 | } 178 | } 179 | 180 | dl { 181 | margin: 0 0 _size(element-margin) 0; 182 | 183 | dt { 184 | display: block; 185 | font-weight: _font(weight-bold); 186 | margin: 0 0 (_size(element-margin) * 0.5) 0; 187 | } 188 | 189 | dd { 190 | margin-left: _size(element-margin); 191 | } 192 | } -------------------------------------------------------------------------------- /WebContent/public/assets/sass/components/_form.scss: -------------------------------------------------------------------------------- 1 | /// 2 | /// Editorial by HTML5 UP 3 | /// html5up.net | @ajlkn 4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | /// 6 | 7 | /* Form */ 8 | 9 | form { 10 | margin: 0 0 _size(element-margin) 0; 11 | } 12 | 13 | label { 14 | color: _palette(fg-bold); 15 | display: block; 16 | font-size: 0.9em; 17 | font-weight: _font(weight-bold); 18 | margin: 0 0 (_size(element-margin) * 0.5) 0; 19 | } 20 | 21 | input[type="text"], 22 | input[type="password"], 23 | input[type="email"], 24 | input[type="tel"], 25 | select, 26 | textarea { 27 | @include vendor('appearance', 'none'); 28 | background: _palette(bg); 29 | border-radius: _size(border-radius); 30 | border: none; 31 | border: solid 1px _palette(border); 32 | color: inherit; 33 | display: block; 34 | outline: 0; 35 | padding: 0 1em; 36 | text-decoration: none; 37 | width: 100%; 38 | 39 | &:invalid { 40 | box-shadow: none; 41 | } 42 | 43 | &:focus { 44 | border-color: _palette(accent); 45 | box-shadow: 0 0 0 1px _palette(accent); 46 | } 47 | } 48 | 49 | .select-wrapper { 50 | @include icon; 51 | display: block; 52 | position: relative; 53 | 54 | &:before { 55 | color: _palette(border); 56 | content: '\f078'; 57 | display: block; 58 | height: _size(element-height); 59 | line-height: _size(element-height); 60 | pointer-events: none; 61 | position: absolute; 62 | right: 0; 63 | text-align: center; 64 | top: 0; 65 | width: _size(element-height); 66 | } 67 | 68 | select::-ms-expand { 69 | display: none; 70 | } 71 | } 72 | 73 | input[type="text"], 74 | input[type="password"], 75 | input[type="email"], 76 | select { 77 | height: _size(element-height); 78 | } 79 | 80 | textarea { 81 | padding: 0.75em 1em; 82 | } 83 | 84 | input[type="checkbox"], 85 | input[type="radio"], { 86 | @include vendor('appearance', 'none'); 87 | display: block; 88 | float: left; 89 | margin-right: -2em; 90 | opacity: 0; 91 | width: 1em; 92 | z-index: -1; 93 | 94 | & + label { 95 | @include icon; 96 | color: _palette(fg); 97 | cursor: pointer; 98 | display: inline-block; 99 | font-size: 1em; 100 | font-weight: _font(weight); 101 | padding-left: (_size(element-height) * 0.6) + 0.75em; 102 | padding-right: 0.75em; 103 | position: relative; 104 | 105 | &:before { 106 | background: _palette(bg); 107 | border-radius: _size(border-radius); 108 | border: solid 1px _palette(border); 109 | content: ''; 110 | display: inline-block; 111 | height: (_size(element-height) * 0.6); 112 | left: 0; 113 | line-height: (_size(element-height) * 0.575); 114 | position: absolute; 115 | text-align: center; 116 | top: 0; 117 | width: (_size(element-height) * 0.6); 118 | } 119 | } 120 | 121 | &:checked + label { 122 | &:before { 123 | background: _palette(fg-bold); 124 | border-color: _palette(fg-bold); 125 | color: _palette(bg); 126 | content: '\f00c'; 127 | } 128 | } 129 | 130 | &:focus + label { 131 | &:before { 132 | border-color: _palette(accent); 133 | box-shadow: 0 0 0 1px _palette(accent); 134 | } 135 | } 136 | } 137 | 138 | input[type="checkbox"] { 139 | & + label { 140 | &:before { 141 | border-radius: _size(border-radius); 142 | } 143 | } 144 | } 145 | 146 | input[type="radio"] { 147 | & + label { 148 | &:before { 149 | border-radius: 100%; 150 | } 151 | } 152 | } 153 | 154 | ::-webkit-input-placeholder { 155 | color: _palette(fg-light) !important; 156 | opacity: 1.0; 157 | } 158 | 159 | :-moz-placeholder { 160 | color: _palette(fg-light) !important; 161 | opacity: 1.0; 162 | } 163 | 164 | ::-moz-placeholder { 165 | color: _palette(fg-light) !important; 166 | opacity: 1.0; 167 | } 168 | 169 | :-ms-input-placeholder { 170 | color: _palette(fg-light) !important; 171 | opacity: 1.0; 172 | } 173 | 174 | .formerize-placeholder { 175 | color: _palette(fg-light) !important; 176 | opacity: 1.0; 177 | } -------------------------------------------------------------------------------- /WebContent/app.js: -------------------------------------------------------------------------------- 1 | var express = require('express'), 2 | app = express(), 3 | server = require('http').createServer(app); 4 | var io = require("socket.io")(server); 5 | var searchapi = require('./controllers/searchapi'); 6 | var fs = require('fs'); 7 | var exec = require('child_process').exec; 8 | var child; 9 | 10 | app.use(express.static(__dirname + '/public')); 11 | 12 | app.get('/', function(req, res){ 13 | res.sendFile(__dirname + '/public'); 14 | }); 15 | 16 | io.sockets.on('connection', function (socket) { 17 | console.log("Connected using sockets"); 18 | 19 | socket.on('clickedsearch', function(data){ 20 | var time = data.timeframe; 21 | socket.emit('getting data', "fetching data"); 22 | searchapi.clickedSearchButton(time,function(finaldata){ 23 | if(finaldata == "success"){ 24 | child = exec('/home/ubuntu/YouTube-Data-Analysis/scripts/getdata.sh',function(error,stdout,stderr){ 25 | if (error) { 26 | console.error(error); 27 | socket.emit('getting data', "failed"); 28 | return; 29 | } 30 | console.log('stdout: ' + stdout); 31 | console.log('stderr: ' + stderr); 32 | socket.emit('getting data', "success"); 33 | }); 34 | }else{ 35 | socket.emit('getting data', "failed"); 36 | } 37 | }); 38 | }); 39 | 40 | 41 | socket.on('clickedanalyze',function(data){ 42 | 43 | socket.emit('analyzing data', "analyzing data"); 44 | console.log("Analyzing Data"); 45 | //Execute Hadoop script 46 | //For shell script 47 | 48 | child = exec('/home/ubuntu/YouTube-Data-Analysis/scripts/analyzedata.sh',function(error,stdout,stderr){ 49 | var resultdata = {}; 50 | if (error) { 51 | console.error(error); 52 | resultdata.response = "error"; 53 | socket.emit('analyzing data', resultdata); 54 | return; 55 | } 56 | 57 | // To test on Windows 58 | /* child = exec('node --version',(error, stdout, stderr)=>{ 59 | var resultdata = {}; 60 | if (error) { 61 | console.error(error); 62 | resultdata.response = "error"; 63 | socket.emit('analyzing data', resultdata); 64 | return; 65 | } */ 66 | console.log('stdout: ' + stdout); 67 | console.log('stderr: ' + stderr); 68 | //Execute all command and then read tsv code 69 | var categtsv = fs.readFileSync('/home/ubuntu/YouTube-Data-Analysis/output/outcategory.tsv','utf8'); 70 | //var categtsv = fs.readFileSync('./../output/outcategory.tsv','utf8'); 71 | var categheaders = ["Category","Count"]; 72 | var uploadertsv = fs.readFileSync('/home/ubuntu/YouTube-Data-Analysis/output/outuploader.tsv','utf8'); 73 | //var uploadertsv = fs.readFileSync('./../output/outuploader.tsv','utf8'); 74 | var uploaderheaders = ["Uploader","Count"]; 75 | var viewtsv = fs.readFileSync('/home/ubuntu/YouTube-Data-Analysis/output/outview.tsv','utf8'); 76 | //var viewtsv = fs.readFileSync('./../output/outview.tsv','utf8'); 77 | var viewheaders = ["Title","Count"]; 78 | 79 | // Call tsv to JSOn to send the data 80 | var topcateg = tsvJSON(categtsv,categheaders); 81 | var topuploader = tsvJSON(uploadertsv,uploaderheaders); 82 | var topviewed = tsvJSON(viewtsv,viewheaders); 83 | resultdata.response = "success"; 84 | resultdata.topcategory = topcateg; 85 | resultdata.topuploader = topuploader; 86 | resultdata.topviewed = topviewed; 87 | // Function to convert TSV to JSON object 88 | function tsvJSON(tsv,headers){ 89 | 90 | var lines=tsv.split("\n"); 91 | 92 | var result = []; 93 | 94 | for(var i=0;i #mq-test-1 { width: 42px; }',c.insertBefore(e,d),b=42===f.offsetWidth,c.removeChild(e),{matches:b,media:a}}}(a.document)}(this),function(a){"use strict";function b(){v(!0)}var c={};a.respond=c,c.update=function(){};var d=[],e=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}(),f=function(a,b){var c=e();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))},g=function(a){return a.replace(c.regex.minmaxwh,"").match(c.regex.other)};if(c.ajax=f,c.queue=d,c.unsupportedmq=g,c.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,comments:/\/\*[^*]*\*+([^/][^*]*\*+)*\//gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\(\s*min\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/,maxw:/\(\s*max\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/,minmaxwh:/\(\s*m(in|ax)\-(height|width)\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/gi,other:/\([^\)]*\)/g},c.mediaQueriesSupported=a.matchMedia&&null!==a.matchMedia("only all")&&a.matchMedia("only all").matches,!c.mediaQueriesSupported){var h,i,j,k=a.document,l=k.documentElement,m=[],n=[],o=[],p={},q=30,r=k.getElementsByTagName("head")[0]||l,s=k.getElementsByTagName("base")[0],t=r.getElementsByTagName("link"),u=function(){var a,b=k.createElement("div"),c=k.body,d=l.style.fontSize,e=c&&c.style.fontSize,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",c||(c=f=k.createElement("body"),c.style.background="none"),l.style.fontSize="100%",c.style.fontSize="100%",c.appendChild(b),f&&l.insertBefore(c,l.firstChild),a=b.offsetWidth,f?l.removeChild(c):c.removeChild(b),l.style.fontSize=d,e&&(c.style.fontSize=e),a=j=parseFloat(a)},v=function(b){var c="clientWidth",d=l[c],e="CSS1Compat"===k.compatMode&&d||k.body[c]||d,f={},g=t[t.length-1],p=(new Date).getTime();if(b&&h&&q>p-h)return a.clearTimeout(i),i=a.setTimeout(v,q),void 0;h=p;for(var s in m)if(m.hasOwnProperty(s)){var w=m[s],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?j||u():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?j||u():1)),w.hasquery&&(z&&A||!(z||e>=x)||!(A||y>=e))||(f[w.media]||(f[w.media]=[]),f[w.media].push(n[w.rules]))}for(var C in o)o.hasOwnProperty(C)&&o[C]&&o[C].parentNode===r&&r.removeChild(o[C]);o.length=0;for(var D in f)if(f.hasOwnProperty(D)){var E=k.createElement("style"),F=f[D].join("\n");E.type="text/css",E.media=D,r.insertBefore(E,g.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(k.createTextNode(F)),o.push(E)}},w=function(a,b,d){var e=a.replace(c.regex.comments,"").replace(c.regex.keyframes,"").match(c.regex.media),f=e&&e.length||0;b=b.substring(0,b.lastIndexOf("/"));var h=function(a){return a.replace(c.regex.urls,"$1"+b+"$2$3")},i=!f&&d;b.length&&(b+="/"),i&&(f=1);for(var j=0;f>j;j++){var k,l,o,p;i?(k=d,n.push(h(a))):(k=e[j].match(c.regex.findStyles)&&RegExp.$1,n.push(RegExp.$2&&h(RegExp.$2))),o=k.split(","),p=o.length;for(var q=0;p>q;q++)l=o[q],g(l)||m.push({media:l.split("(")[0].match(c.regex.only)&&RegExp.$2||"all",rules:n.length-1,hasquery:l.indexOf("(")>-1,minw:l.match(c.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:l.match(c.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}v()},x=function(){if(d.length){var b=d.shift();f(b.href,function(c){w(c,b.href,b.media),p[b.href]=!0,a.setTimeout(function(){x()},0)})}},y=function(){for(var b=0;b 2 | 7 | 8 | 9 | YouTube Data Analysis by Team Inferno 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 |
27 |
28 | 29 | 30 | 36 | 37 | 38 | 46 | 47 |
48 |
49 | 50 | 51 | 107 | 108 |
109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /WebContent/public/projectdescription.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | Get Data - YouTube Data Analysis 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 |
28 |
29 | 30 | 31 | 37 | 38 | 39 |
40 |
41 |

Project Description

42 |
43 | 44 | 45 |

Project Name

46 |

Youtube Data Analysis in a Hadoop MapReduce Environment

47 | 48 | 49 | 50 |
51 |
52 | 53 | 54 | 55 | 56 | 112 | 113 |
114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /WebContent/public/assets/sass/layout/_sidebar.scss: -------------------------------------------------------------------------------- 1 | /// 2 | /// Editorial by HTML5 UP 3 | /// html5up.net | @ajlkn 4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | /// 6 | 7 | /* Sidebar */ 8 | 9 | #search { 10 | form { 11 | @include icon; 12 | position: relative; 13 | 14 | &:before { 15 | @include vendor('transform', 'scaleX(-1)'); 16 | color: _palette(fg); 17 | content: '\f002'; 18 | cursor: default; 19 | display: block; 20 | font-size: 1.5em; 21 | height: _size(element-height) / 1.375; 22 | line-height: _size(element-height) / 1.375; 23 | opacity: 0.325; 24 | position: absolute; 25 | right: 0; 26 | text-align: center; 27 | top: 0; 28 | width: _size(element-height) / 1.375; 29 | } 30 | 31 | input[type="text"] { 32 | padding-right: _size(element-height); 33 | } 34 | } 35 | } 36 | 37 | #sidebar { 38 | $pad: 2em / 0.9; 39 | 40 | @include vendor('flex-grow', '0'); 41 | @include vendor('flex-shrink', '0'); 42 | @include vendor('transition', ( 43 | 'margin-left 0.5s ease', 44 | 'box-shadow 0.5s ease' 45 | )); 46 | background-color: _palette(bg-alt); 47 | font-size: 0.9em; 48 | position: relative; 49 | width: _size(sidebar-width); 50 | 51 | h2 { 52 | font-size: (1.25em / 0.9); 53 | } 54 | 55 | > .inner { 56 | @include padding($pad, $pad, (0, 0, $pad, 0)); 57 | position: relative; 58 | width: _size(sidebar-width); 59 | 60 | > * { 61 | border-bottom: solid 2px _palette(border); 62 | margin: 0 0 (_size(element-margin) * 1.75) 0; 63 | padding: 0 0 (_size(element-margin) * 1.75) 0; 64 | 65 | > :last-child { 66 | margin-bottom: 0; 67 | } 68 | 69 | &:last-child { 70 | border-bottom: 0; 71 | margin-bottom: 0; 72 | padding-bottom: 0; 73 | } 74 | } 75 | 76 | > .alt { 77 | background-color: darken(_palette(bg-alt), 2); 78 | border-bottom: 0; 79 | margin: ($pad * -1) 0 ($pad * 2) ($pad * -1); 80 | padding: $pad; 81 | width: calc(100% + #{$pad * 2}); 82 | } 83 | } 84 | 85 | .toggle { 86 | @include icon; 87 | @include vendor('transition', 'left 0.5s ease'); 88 | -webkit-tap-highlight-color: rgba(255,255,255,0); 89 | border: 0; 90 | display: block; 91 | height: 7.5em; 92 | left: _size(sidebar-width); 93 | line-height: 7.5em; 94 | outline: 0; 95 | overflow: hidden; 96 | position: absolute; 97 | text-align: center; 98 | text-indent: 7.5em; 99 | top: 0; 100 | width: 6em; 101 | z-index: _misc(z-index-base); 102 | 103 | &:before { 104 | content: '\f0c9'; 105 | font-size: 2rem; 106 | height: inherit; 107 | left: 0; 108 | line-height: inherit; 109 | position: absolute; 110 | text-indent: 0; 111 | top: 0; 112 | width: inherit; 113 | } 114 | } 115 | 116 | &.inactive { 117 | margin-left: (_size(sidebar-width) * -1); 118 | } 119 | 120 | @include breakpoint(xlarge) { 121 | $pad: 1.5em / 0.9; 122 | 123 | width: _size(sidebar-width-alt); 124 | 125 | > .inner { 126 | @include padding($pad, $pad, (0, 0, $pad, 0)); 127 | width: _size(sidebar-width-alt); 128 | 129 | > .alt { 130 | margin: ($pad * -1) 0 ($pad * 2) ($pad * -1); 131 | padding: $pad; 132 | width: calc(100% + #{$pad * 2}); 133 | } 134 | } 135 | 136 | .toggle { 137 | height: 6.25em; 138 | left: _size(sidebar-width-alt); 139 | line-height: 6.25em; 140 | text-indent: 5em; 141 | width: 5em; 142 | 143 | &:before { 144 | font-size: 1.5rem; 145 | } 146 | } 147 | 148 | &.inactive { 149 | margin-left: (_size(sidebar-width-alt) * -1); 150 | } 151 | } 152 | 153 | @include breakpoint(large) { 154 | box-shadow: 0 0 5em 0 rgba(0, 0, 0, 0.175); 155 | height: 100%; 156 | left: 0; 157 | position: fixed; 158 | top: 0; 159 | z-index: _misc(z-index-base); 160 | 161 | &.inactive { 162 | box-shadow: none; 163 | } 164 | 165 | > .inner { 166 | -webkit-overflow-scrolling: touch; 167 | height: 100%; 168 | left: 0; 169 | overflow-x: hidden; 170 | overflow-y: auto; 171 | position: absolute; 172 | top: 0; 173 | 174 | &:after { 175 | content: ''; 176 | display: block; 177 | height: 4em; 178 | width: 100%; 179 | } 180 | } 181 | 182 | .toggle { 183 | text-indent: 6em; 184 | width: 6em; 185 | 186 | &:before { 187 | font-size: 1.5rem; 188 | margin-left: (-0.875em / 2); 189 | } 190 | } 191 | 192 | body.is-loading & { 193 | display: none; 194 | } 195 | } 196 | 197 | @include breakpoint(small) { 198 | .toggle { 199 | text-indent: 7.25em; 200 | width: 7.25em; 201 | 202 | &:before { 203 | color: _palette(fg); 204 | margin-left: (-0.125em / 2); 205 | margin-top: (-0.5em / 2); 206 | font-size: 1.1rem; 207 | z-index: 1; 208 | } 209 | 210 | &:after { 211 | background: transparentize(lighten(_palette(fg), 35), 0.25); 212 | border-radius: _size(border-radius); 213 | content: ''; 214 | height: 3.5em; 215 | left: 1em; 216 | position: absolute; 217 | top: 1em; 218 | width: 5em; 219 | } 220 | } 221 | } 222 | } -------------------------------------------------------------------------------- /WebContent/public/assets/js/jquery.easypiechart.min.js: -------------------------------------------------------------------------------- 1 | /**! 2 | * easy-pie-chart 3 | * Lightweight plugin to render simple, animated and retina optimized pie charts 4 | * 5 | * @license 6 | * @author Robert Fleischmann (http://robert-fleischmann.de) 7 | * @version 2.1.7 8 | **/ 9 | !function(a,b){"function"==typeof define&&define.amd?define(["jquery"],function(a){return b(a)}):"object"==typeof exports?module.exports=b(require("jquery")):b(jQuery)}(this,function(a){var b=function(a,b){var c,d=document.createElement("canvas");a.appendChild(d),"object"==typeof G_vmlCanvasManager&&G_vmlCanvasManager.initElement(d);var e=d.getContext("2d");d.width=d.height=b.size;var f=1;window.devicePixelRatio>1&&(f=window.devicePixelRatio,d.style.width=d.style.height=[b.size,"px"].join(""),d.width=d.height=b.size*f,e.scale(f,f)),e.translate(b.size/2,b.size/2),e.rotate((-0.5+b.rotate/180)*Math.PI);var g=(b.size-b.lineWidth)/2;b.scaleColor&&b.scaleLength&&(g-=b.scaleLength+2),Date.now=Date.now||function(){return+new Date};var h=function(a,b,c){c=Math.min(Math.max(-1,c||0),1);var d=0>=c?!0:!1;e.beginPath(),e.arc(0,0,g,0,2*Math.PI*c,d),e.strokeStyle=a,e.lineWidth=b,e.stroke()},i=function(){var a,c;e.lineWidth=1,e.fillStyle=b.scaleColor,e.save();for(var d=24;d>0;--d)d%6===0?(c=b.scaleLength,a=0):(c=.6*b.scaleLength,a=b.scaleLength-c),e.fillRect(-b.size/2+a,0,c,1),e.rotate(Math.PI/12);e.restore()},j=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||function(a){window.setTimeout(a,1e3/60)}}(),k=function(){b.scaleColor&&i(),b.trackColor&&h(b.trackColor,b.trackWidth||b.lineWidth,1)};this.getCanvas=function(){return d},this.getCtx=function(){return e},this.clear=function(){e.clearRect(b.size/-2,b.size/-2,b.size,b.size)},this.draw=function(a){b.scaleColor||b.trackColor?e.getImageData&&e.putImageData?c?e.putImageData(c,0,0):(k(),c=e.getImageData(0,0,b.size*f,b.size*f)):(this.clear(),k()):this.clear(),e.lineCap=b.lineCap;var d;d="function"==typeof b.barColor?b.barColor(a):b.barColor,h(d,b.lineWidth,a/100)}.bind(this),this.animate=function(a,c){var d=Date.now();b.onStart(a,c);var e=function(){var f=Math.min(Date.now()-d,b.animate.duration),g=b.easing(this,f,a,c-a,b.animate.duration);this.draw(g),b.onStep(a,c,g),f>=b.animate.duration?b.onStop(a,c):j(e)}.bind(this);j(e)}.bind(this)},c=function(a,c){var d={barColor:"#ef1e25",trackColor:"#f9f9f9",scaleColor:"#dfe0e0",scaleLength:5,lineCap:"round",lineWidth:3,trackWidth:void 0,size:110,rotate:0,animate:{duration:1e3,enabled:!0},easing:function(a,b,c,d,e){return b/=e/2,1>b?d/2*b*b+c:-d/2*(--b*(b-2)-1)+c},onStart:function(a,b){},onStep:function(a,b,c){},onStop:function(a,b){}};if("undefined"!=typeof b)d.renderer=b;else{if("undefined"==typeof SVGRenderer)throw new Error("Please load either the SVG- or the CanvasRenderer");d.renderer=SVGRenderer}var e={},f=0,g=function(){this.el=a,this.options=e;for(var b in d)d.hasOwnProperty(b)&&(e[b]=c&&"undefined"!=typeof c[b]?c[b]:d[b],"function"==typeof e[b]&&(e[b]=e[b].bind(this)));"string"==typeof e.easing&&"undefined"!=typeof jQuery&&jQuery.isFunction(jQuery.easing[e.easing])?e.easing=jQuery.easing[e.easing]:e.easing=d.easing,"number"==typeof e.animate&&(e.animate={duration:e.animate,enabled:!0}),"boolean"!=typeof e.animate||e.animate||(e.animate={duration:1e3,enabled:e.animate}),this.renderer=new e.renderer(a,e),this.renderer.draw(f),a.dataset&&a.dataset.percent?this.update(parseFloat(a.dataset.percent)):a.getAttribute&&a.getAttribute("data-percent")&&this.update(parseFloat(a.getAttribute("data-percent")))}.bind(this);this.update=function(a){return a=parseFloat(a),e.animate.enabled?this.renderer.animate(f,a):this.renderer.draw(a),f=a,this}.bind(this),this.disableAnimation=function(){return e.animate.enabled=!1,this},this.enableAnimation=function(){return e.animate.enabled=!0,this},g()};a.fn.easyPieChart=function(b){return this.each(function(){var d;a.data(this,"easyPieChart")||(d=a.extend({},b,a(this).data()),a.data(this,"easyPieChart",new c(this,d)))})}}); 10 | 11 | /* 12 | Template Name: Splash 13 | Author: OS Templates 14 | Author URI: http://www.os-templates.com/ 15 | Licence: Free to use under our free template licence terms 16 | Licence URI: http://www.os-templates.com/template-terms 17 | File: EasyPieChart SetUp js 18 | */ 19 | jQuery(document).ready(function($) { 20 | function animateElements() { 21 | $('.pr-chart-ctrl').each(function() { 22 | var elementPos = $(this).offset().top; 23 | var topOfWindow = $(window).scrollTop(); 24 | var animate = $(this).data('animate'); 25 | if (elementPos < topOfWindow + $(window).height() - 30 && !animate) { 26 | $(this).data('animate', true); 27 | $(this).find('.pr-chart').easyPieChart({ 28 | size: 200, 29 | barColor: '#EE391A', 30 | trackColor: 'rgba(255,255,255,.2)', 31 | scaleColor: 'rgba(255,255,255,.5)', 32 | scaleLength: 5, 33 | lineWidth: 5, 34 | lineCap: 'square', 35 | onStep: function(from, to, percent) { 36 | $(this.el).find('i').text(Math.round(percent) + '%'); 37 | } 38 | }).stop(); 39 | } 40 | }); 41 | } 42 | animateElements(); 43 | $(window).scroll(animateElements); 44 | }); -------------------------------------------------------------------------------- /WebContent/public/aboutus.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | Get Data - YouTube Data Analysis 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 |
28 |
29 | 30 | 31 | 37 | 38 | 39 |
40 |
41 |

About US

42 |
43 | 44 | 45 |

Mission

46 |

Our mission is to provide cloud based big data analytics for classifying large unstructured data into useful information.
YouTube data is fed for the chosen timeframe and top 5 categories of videos, maximum viewed videos and uploaders are displayed to the user.
Businesses can be benefited by investing on the most trending categories.

47 | 48 |

Why Big Data Analystics ?

49 |
    50 |
  • Cloud based big data analytics has substantial cost advantages in the recent days.
  • 51 |
  • Analytics has illustrated faster decision making which reduces a lot of time.
  • 52 |
  • The ultimate goal is to provide a big data era with valuable products delivered to the customer.
  • 53 |
54 | 55 |

Developers

56 |
57 |
58 |

Arpit Mathur
Masters in Software Engineering
Arizona State University

59 |
60 |
61 |

Senthamil Sindhu
Masters in Software Engineering
Arizona State University

62 |
63 |
64 |

Vimarsh Deo
Masters in Software Engineering
Arizona State University

65 |
66 |
67 |
68 |
69 | 70 | 71 | 72 | 73 | 74 | 130 | 131 |
132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /WebContent/public/getdata.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | Get Data - YouTube Data Analysis 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 |
25 |
26 | 27 | 28 | 34 | 35 | 36 |
37 |
38 |

Fetch YouTube Data

39 |
40 | 41 | 42 |

Search

43 |

Search is conducted via YouTube APIs. Search results are stack ranked by publish date (latest first)..

44 |
45 |
46 |
47 | 58 |
59 |
60 |
61 | 62 | 63 | 64 |
65 | 69 | 72 |
73 | 74 | 75 | 76 | 77 |
78 |
79 | 80 | 81 | 82 | 83 | 139 | 140 |
141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | -------------------------------------------------------------------------------- /WebContent/public/stats.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | Statistics - YouTube Data Analysis 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 |
26 |
27 | 28 | 29 | 35 | 36 | 37 |
38 |
39 |

Statistics

40 |
41 |

Click on Analyze data button to execute the Hadoop MapReduce algorithm which will return the statistics.

42 |
43 | 44 |
45 | 49 |
50 | 112 | 113 | 114 |
115 | 116 |
117 |
118 | 119 | 120 | 176 | 177 |
178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | -------------------------------------------------------------------------------- /WebContent/public/assets/js/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | Editorial by HTML5 UP 3 | html5up.net | @ajlkn 4 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | */ 6 | 7 | (function($) { 8 | 9 | skel.breakpoints({ 10 | xlarge: '(max-width: 1680px)', 11 | large: '(max-width: 1280px)', 12 | medium: '(max-width: 980px)', 13 | small: '(max-width: 736px)', 14 | xsmall: '(max-width: 480px)', 15 | 'xlarge-to-max': '(min-width: 1681px)', 16 | 'small-to-xlarge': '(min-width: 481px) and (max-width: 1680px)' 17 | }); 18 | 19 | $(function() { 20 | 21 | var $window = $(window), 22 | $head = $('head'), 23 | $body = $('body'); 24 | 25 | // Disable animations/transitions ... 26 | 27 | // ... until the page has loaded. 28 | $body.addClass('is-loading'); 29 | 30 | $window.on('load', function() { 31 | setTimeout(function() { 32 | $body.removeClass('is-loading'); 33 | }, 100); 34 | }); 35 | 36 | // ... when resizing. 37 | var resizeTimeout; 38 | 39 | $window.on('resize', function() { 40 | 41 | // Mark as resizing. 42 | $body.addClass('is-resizing'); 43 | 44 | // Unmark after delay. 45 | clearTimeout(resizeTimeout); 46 | 47 | resizeTimeout = setTimeout(function() { 48 | $body.removeClass('is-resizing'); 49 | }, 100); 50 | 51 | }); 52 | 53 | // Fix: Placeholder polyfill. 54 | $('form').placeholder(); 55 | 56 | // Prioritize "important" elements on medium. 57 | skel.on('+medium -medium', function() { 58 | $.prioritize( 59 | '.important\\28 medium\\29', 60 | skel.breakpoint('medium').active 61 | ); 62 | }); 63 | 64 | // Fixes. 65 | 66 | // Object fit images. 67 | if (!skel.canUse('object-fit') 68 | || skel.vars.browser == 'safari') 69 | $('.image.object').each(function() { 70 | 71 | var $this = $(this), 72 | $img = $this.children('img'); 73 | 74 | // Hide original image. 75 | $img.css('opacity', '0'); 76 | 77 | // Set background. 78 | $this 79 | .css('background-image', 'url("' + $img.attr('src') + '")') 80 | .css('background-size', $img.css('object-fit') ? $img.css('object-fit') : 'cover') 81 | .css('background-position', $img.css('object-position') ? $img.css('object-position') : 'center'); 82 | 83 | }); 84 | 85 | // Sidebar. 86 | var $sidebar = $('#sidebar'), 87 | $sidebar_inner = $sidebar.children('.inner'); 88 | 89 | // Inactive by default on <= large. 90 | skel 91 | .on('+large', function() { 92 | $sidebar.addClass('inactive'); 93 | }) 94 | .on('-large !large', function() { 95 | $sidebar.removeClass('inactive'); 96 | }); 97 | 98 | // Hack: Workaround for Chrome/Android scrollbar position bug. 99 | if (skel.vars.os == 'android' 100 | && skel.vars.browser == 'chrome') 101 | $('') 102 | .appendTo($head); 103 | 104 | // Toggle. 105 | if (skel.vars.IEVersion > 9) { 106 | 107 | $('Toggle') 108 | .appendTo($sidebar) 109 | .on('click', function(event) { 110 | 111 | // Prevent default. 112 | event.preventDefault(); 113 | event.stopPropagation(); 114 | 115 | // Toggle. 116 | $sidebar.toggleClass('inactive'); 117 | 118 | }); 119 | 120 | } 121 | 122 | // Events. 123 | 124 | // Link clicks. 125 | $sidebar.on('click', 'a', function(event) { 126 | 127 | // >large? Bail. 128 | if (!skel.breakpoint('large').active) 129 | return; 130 | 131 | // Vars. 132 | var $a = $(this), 133 | href = $a.attr('href'), 134 | target = $a.attr('target'); 135 | 136 | // Prevent default. 137 | event.preventDefault(); 138 | event.stopPropagation(); 139 | 140 | // Check URL. 141 | if (!href || href == '#' || href == '') 142 | return; 143 | 144 | // Hide sidebar. 145 | $sidebar.addClass('inactive'); 146 | 147 | // Redirect to href. 148 | setTimeout(function() { 149 | 150 | if (target == '_blank') 151 | window.open(href); 152 | else 153 | window.location.href = href; 154 | 155 | }, 500); 156 | 157 | }); 158 | 159 | // Prevent certain events inside the panel from bubbling. 160 | $sidebar.on('click touchend touchstart touchmove', function(event) { 161 | 162 | // >large? Bail. 163 | if (!skel.breakpoint('large').active) 164 | return; 165 | 166 | // Prevent propagation. 167 | event.stopPropagation(); 168 | 169 | }); 170 | 171 | // Hide panel on body click/tap. 172 | $body.on('click touchend', function(event) { 173 | 174 | // >large? Bail. 175 | if (!skel.breakpoint('large').active) 176 | return; 177 | 178 | // Deactivate. 179 | $sidebar.addClass('inactive'); 180 | 181 | }); 182 | 183 | // Scroll lock. 184 | // Note: If you do anything to change the height of the sidebar's content, be sure to 185 | // trigger 'resize.sidebar-lock' on $window so stuff doesn't get out of sync. 186 | 187 | $window.on('load.sidebar-lock', function() { 188 | 189 | var sh, wh, st; 190 | 191 | // Reset scroll position to 0 if it's 1. 192 | if ($window.scrollTop() == 1) 193 | $window.scrollTop(0); 194 | 195 | $window 196 | .on('scroll.sidebar-lock', function() { 197 | 198 | var x, y; 199 | 200 | // IE<10? Bail. 201 | if (skel.vars.IEVersion < 10) 202 | return; 203 | 204 | // <=large? Bail. 205 | if (skel.breakpoint('large').active) { 206 | 207 | $sidebar_inner 208 | .data('locked', 0) 209 | .css('position', '') 210 | .css('top', ''); 211 | 212 | return; 213 | 214 | } 215 | 216 | // Calculate positions. 217 | x = Math.max(sh - wh, 0); 218 | y = Math.max(0, $window.scrollTop() - x); 219 | 220 | // Lock/unlock. 221 | if ($sidebar_inner.data('locked') == 1) { 222 | 223 | if (y <= 0) 224 | $sidebar_inner 225 | .data('locked', 0) 226 | .css('position', '') 227 | .css('top', ''); 228 | else 229 | $sidebar_inner 230 | .css('top', -1 * x); 231 | 232 | } 233 | else { 234 | 235 | if (y > 0) 236 | $sidebar_inner 237 | .data('locked', 1) 238 | .css('position', 'fixed') 239 | .css('top', -1 * x); 240 | 241 | } 242 | 243 | }) 244 | .on('resize.sidebar-lock', function() { 245 | 246 | // Calculate heights. 247 | wh = $window.height(); 248 | sh = $sidebar_inner.outerHeight() + 30; 249 | 250 | // Trigger scroll. 251 | $window.trigger('scroll.sidebar-lock'); 252 | 253 | }) 254 | .trigger('resize.sidebar-lock'); 255 | 256 | }); 257 | 258 | // Menu. 259 | var $menu = $('#menu'), 260 | $menu_openers = $menu.children('ul').find('.opener'); 261 | 262 | // Openers. 263 | $menu_openers.each(function() { 264 | 265 | var $this = $(this); 266 | 267 | $this.on('click', function(event) { 268 | 269 | // Prevent default. 270 | event.preventDefault(); 271 | 272 | // Toggle. 273 | $menu_openers.not($this).removeClass('active'); 274 | $this.toggleClass('active'); 275 | 276 | // Trigger resize (sidebar lock). 277 | $window.triggerHandler('resize.sidebar-lock'); 278 | 279 | }); 280 | 281 | }); 282 | 283 | }); 284 | 285 | })(jQuery); -------------------------------------------------------------------------------- /WebContent/public/assets/js/analyzehelper.js: -------------------------------------------------------------------------------- 1 | // Helper file to make ajax call to server on various button clicks 2 | 3 | window.onload = function(){ 4 | 5 | var analyzeButton = document.getElementById("analyze"); 6 | //Ajax call to make a request to Run Hadoop Map-Reduce algorithm on the server 7 | analyzeButton.onclick = function(e){ 8 | 9 | var socket = io.connect(); 10 | e.preventDefault(); 11 | socket.emit('clickedanalyze', "clicked on analyze"); 12 | 13 | socket.on('analyzing data',function(data){ 14 | var resp = data; 15 | if(data =="analyzing data"){ 16 | 17 | $("#ajax_loader").show(); 18 | d3.select("#topcategchart").selectAll("svg").remove(); 19 | d3.select("#topviewedchart").selectAll("svg").remove(); 20 | 21 | }else if(resp.response =="success"){ 22 | $("#ajax_loader").hide(); 23 | //Collect all JSON objects 24 | var topcategories = resp.topcategory; 25 | var topuploader = resp.topuploader; 26 | var topviewed = resp.topviewed; 27 | 28 | var topcategchart = document.getElementById("topcategchart"); 29 | drawLegendChart(topcategories,topcategchart); 30 | var topcategtable = document.getElementById("topcategtable"); 31 | $("#topcategtable tr").remove(); 32 | drawTable(topcategories,topcategtable); 33 | 34 | var topviewedchart = document.getElementById("topviewedchart"); 35 | drawHorizontalChart(topviewed, topviewedchart); 36 | var topviewedtable = document.getElementById("topviewedtable"); 37 | $("#topviewedtable tr").remove(); 38 | drawTableViews(topviewed,topviewedtable); 39 | 40 | var topuploadertable = document.getElementById("topuploadertable"); 41 | $("#topuploadertable tr").remove(); 42 | drawTableUploader(topuploader,topuploadertable); 43 | 44 | $("#display-results").show(); 45 | 46 | }else if(resp.response =="error"){ 47 | $("#ajax_loader").hide(); 48 | console.log("Some Error occured"); 49 | } 50 | }); 51 | 52 | } 53 | 54 | 55 | function drawTable(data,selecter){ 56 | 57 | var tabdata = $.parseJSON(data); 58 | 59 | $(function() { 60 | $.each(tabdata, function(i, item) { 61 | var $tr = $('').append( 62 | $('').text(i+1), 63 | $('').text(item.Category), 64 | $('').text(item.Count) 65 | ).appendTo(selecter); 66 | 67 | }); 68 | }); 69 | 70 | 71 | 72 | } 73 | 74 | function drawTableViews(data,selecter){ 75 | 76 | var tabdata = $.parseJSON(data); 77 | 78 | $(function() { 79 | $.each(tabdata, function(i, item) { 80 | var $tr = $('').append( 81 | $('').text(i+1), 82 | $('').text(item.Title), 83 | $('').text(item.Count) 84 | ).appendTo(selecter); 85 | 86 | }); 87 | }); 88 | 89 | 90 | 91 | } 92 | function drawTableUploader(data,selecter){ 93 | 94 | var tabdata = $.parseJSON(data); 95 | 96 | $(function() { 97 | $.each(tabdata, function(i, item) { 98 | var $tr = $('').append( 99 | $('').text(i+1), 100 | $('').text(item.Uploader), 101 | $('').text(item.Count) 102 | ).appendTo(selecter); 103 | 104 | }); 105 | }); 106 | 107 | 108 | 109 | } 110 | 111 | function drawLegendChart(dataset,selecter){ 112 | 113 | var dataset = $.parseJSON(dataset); 114 | var width = 360; 115 | var height = 360; 116 | var radius = Math.min(width, height) / 2; 117 | var donutWidth = 75; 118 | var legendRectSize = 18; 119 | var legendSpacing = 4; 120 | 121 | var color = d3.scale.category20b(); 122 | 123 | var svg = d3.select(selecter) 124 | .append('svg') 125 | .attr('width', width) 126 | .attr('height', height) 127 | .append('g') 128 | .attr('transform', 'translate(' + (width / 2) + 129 | ',' + (height / 2) + ')'); 130 | 131 | var arc = d3.svg.arc() 132 | .innerRadius(radius - donutWidth) 133 | .outerRadius(radius); 134 | 135 | var pie = d3.layout.pie() 136 | .value(function(d) { return Number(d.Count); }) 137 | .sort(null); 138 | 139 | var path = svg.selectAll('path') 140 | .data(pie(dataset)) 141 | .enter() 142 | .append('path') 143 | .attr('d', arc) 144 | .attr('fill', function(d, i) { 145 | return color(d.data.Category); 146 | }); 147 | 148 | var legend = svg.selectAll('.legend') 149 | .data(color.domain()) 150 | .enter() 151 | .append('g') 152 | .attr('class', 'legend') 153 | .attr('transform', function(d, i) { 154 | var height = legendRectSize + legendSpacing; 155 | var offset = height * color.domain().length / 2; 156 | var horz = -2 * legendRectSize; 157 | var vert = i * height - offset; 158 | return 'translate(' + horz + ',' + vert + ')'; 159 | }); 160 | 161 | legend.append('rect') 162 | .attr('width', legendRectSize) 163 | .attr('height', legendRectSize) 164 | .style('fill', color) 165 | .style('stroke', color); 166 | 167 | legend.append('text') 168 | .attr('x', legendRectSize + legendSpacing) 169 | .attr('y', legendRectSize - legendSpacing) 170 | .text(function(d) { return d; }); 171 | 172 | 173 | } 174 | 175 | function drawHorizontalChart(data,selecter){ 176 | 177 | 178 | var tabdata = $.parseJSON(data); 179 | 180 | var colors = ['#0000b4','#0082ca','#0094ff','#0d4bcf','#79BCBF']; 181 | var w = 800, 182 | h = 400; 183 | 184 | var svg = d3.select(selecter) 185 | .append("svg") 186 | .attr("width", w) 187 | .attr("height", h); 188 | 189 | 190 | var max_n = 0; 191 | for (var d in tabdata) { 192 | max_n = Math.max(Number(tabdata[d].Count), max_n); 193 | } 194 | 195 | var dx = w / max_n; 196 | var dy = h / tabdata.length; 197 | 198 | var colorScale = d3.scale.quantize() 199 | .domain([0,tabdata.length]) 200 | .range(colors); 201 | 202 | // bars 203 | var bars = svg.selectAll(".bar") 204 | .data(tabdata) 205 | .enter() 206 | .append("rect") 207 | .attr("class", function(d, i) {return "bar " + d.Title;}) 208 | .attr("x", function(d, i) {return 0;}) 209 | .attr("y", function(d, i) {return dy*i;}) 210 | .style('fill',function(d,i){ return colorScale(i); }) 211 | .attr("width", function(d, i) {return dx*Number(d.Count)}) 212 | .attr("height", dy); 213 | 214 | // labels 215 | var text = svg.selectAll("text") 216 | .data(tabdata) 217 | .enter() 218 | .append("text") 219 | .attr("class", function(d, i) {return "label " + d.Title;}) 220 | .attr("x", 2) 221 | .attr("y", function(d, i) {return dy*i + 15;}) 222 | .text( function(d) {return d.Title + " ( Views: " + d.Count + ")";}) 223 | .attr("font-size", "12px") 224 | .style("font-weight", "bold"); 225 | 226 | 227 | 228 | 229 | 230 | } 231 | } 232 | -------------------------------------------------------------------------------- /WebContent/public/assets/js/skel.min.js: -------------------------------------------------------------------------------- 1 | /* skel.js v3.0.1 | (c) skel.io | MIT licensed */ 2 | var skel=function(){"use strict";var t={breakpointIds:null,events:{},isInit:!1,obj:{attachments:{},breakpoints:{},head:null,states:{}},sd:"/",state:null,stateHandlers:{},stateId:"",vars:{},DOMReady:null,indexOf:null,isArray:null,iterate:null,matchesMedia:null,extend:function(e,n){t.iterate(n,function(i){t.isArray(n[i])?(t.isArray(e[i])||(e[i]=[]),t.extend(e[i],n[i])):"object"==typeof n[i]?("object"!=typeof e[i]&&(e[i]={}),t.extend(e[i],n[i])):e[i]=n[i]})},newStyle:function(t){var e=document.createElement("style");return e.type="text/css",e.innerHTML=t,e},_canUse:null,canUse:function(e){t._canUse||(t._canUse=document.createElement("div"));var n=t._canUse.style,i=e.charAt(0).toUpperCase()+e.slice(1);return e in n||"Moz"+i in n||"Webkit"+i in n||"O"+i in n||"ms"+i in n},on:function(e,n){var i=e.split(/[\s]+/);return t.iterate(i,function(e){var a=i[e];if(t.isInit){if("init"==a)return void n();if("change"==a)n();else{var r=a.charAt(0);if("+"==r||"!"==r){var o=a.substring(1);if(o in t.obj.breakpoints)if("+"==r&&t.obj.breakpoints[o].active)n();else if("!"==r&&!t.obj.breakpoints[o].active)return void n()}}}t.events[a]||(t.events[a]=[]),t.events[a].push(n)}),t},trigger:function(e){return t.events[e]&&0!=t.events[e].length?(t.iterate(t.events[e],function(n){t.events[e][n]()}),t):void 0},breakpoint:function(e){return t.obj.breakpoints[e]},breakpoints:function(e){function n(t,e){this.name=this.id=t,this.media=e,this.active=!1,this.wasActive=!1}return n.prototype.matches=function(){return t.matchesMedia(this.media)},n.prototype.sync=function(){this.wasActive=this.active,this.active=this.matches()},t.iterate(e,function(i){t.obj.breakpoints[i]=new n(i,e[i])}),window.setTimeout(function(){t.poll()},0),t},addStateHandler:function(e,n){t.stateHandlers[e]=n},callStateHandler:function(e){var n=t.stateHandlers[e]();t.iterate(n,function(e){t.state.attachments.push(n[e])})},changeState:function(e){t.iterate(t.obj.breakpoints,function(e){t.obj.breakpoints[e].sync()}),t.vars.lastStateId=t.stateId,t.stateId=e,t.breakpointIds=t.stateId===t.sd?[]:t.stateId.substring(1).split(t.sd),t.obj.states[t.stateId]?t.state=t.obj.states[t.stateId]:(t.obj.states[t.stateId]={attachments:[]},t.state=t.obj.states[t.stateId],t.iterate(t.stateHandlers,t.callStateHandler)),t.detachAll(t.state.attachments),t.attachAll(t.state.attachments),t.vars.stateId=t.stateId,t.vars.state=t.state,t.trigger("change"),t.iterate(t.obj.breakpoints,function(e){t.obj.breakpoints[e].active?t.obj.breakpoints[e].wasActive||t.trigger("+"+e):t.obj.breakpoints[e].wasActive&&t.trigger("-"+e)})},generateStateConfig:function(e,n){var i={};return t.extend(i,e),t.iterate(t.breakpointIds,function(e){t.extend(i,n[t.breakpointIds[e]])}),i},getStateId:function(){var e="";return t.iterate(t.obj.breakpoints,function(n){var i=t.obj.breakpoints[n];i.matches()&&(e+=t.sd+i.id)}),e},poll:function(){var e="";e=t.getStateId(),""===e&&(e=t.sd),e!==t.stateId&&t.changeState(e)},_attach:null,attach:function(e){var n=t.obj.head,i=e.element;return i.parentNode&&i.parentNode.tagName?!1:(t._attach||(t._attach=n.firstChild),n.insertBefore(i,t._attach.nextSibling),e.permanent&&(t._attach=i),!0)},attachAll:function(e){var n=[];t.iterate(e,function(t){n[e[t].priority]||(n[e[t].priority]=[]),n[e[t].priority].push(e[t])}),n.reverse(),t.iterate(n,function(e){t.iterate(n[e],function(i){t.attach(n[e][i])})})},detach:function(t){var e=t.element;return t.permanent||!e.parentNode||e.parentNode&&!e.parentNode.tagName?!1:(e.parentNode.removeChild(e),!0)},detachAll:function(e){var n={};t.iterate(e,function(t){n[e[t].id]=!0}),t.iterate(t.obj.attachments,function(e){e in n||t.detach(t.obj.attachments[e])})},attachment:function(e){return e in t.obj.attachments?t.obj.attachments[e]:null},newAttachment:function(e,n,i,a){return t.obj.attachments[e]={id:e,element:n,priority:i,permanent:a}},init:function(){t.initMethods(),t.initVars(),t.initEvents(),t.obj.head=document.getElementsByTagName("head")[0],t.isInit=!0,t.trigger("init")},initEvents:function(){t.on("resize",function(){t.poll()}),t.on("orientationChange",function(){t.poll()}),t.DOMReady(function(){t.trigger("ready")}),window.onload&&t.on("load",window.onload),window.onload=function(){t.trigger("load")},window.onresize&&t.on("resize",window.onresize),window.onresize=function(){t.trigger("resize")},window.onorientationchange&&t.on("orientationChange",window.onorientationchange),window.onorientationchange=function(){t.trigger("orientationChange")}},initMethods:function(){document.addEventListener?!function(e,n){t.DOMReady=n()}("domready",function(){function t(t){for(r=1;t=n.shift();)t()}var e,n=[],i=document,a="DOMContentLoaded",r=/^loaded|^c/.test(i.readyState);return i.addEventListener(a,e=function(){i.removeEventListener(a,e),t()}),function(t){r?t():n.push(t)}}):!function(e,n){t.DOMReady=n()}("domready",function(t){function e(t){for(h=1;t=i.shift();)t()}var n,i=[],a=!1,r=document,o=r.documentElement,s=o.doScroll,c="DOMContentLoaded",d="addEventListener",u="onreadystatechange",l="readyState",f=s?/^loaded|^c/:/^loaded|c/,h=f.test(r[l]);return r[d]&&r[d](c,n=function(){r.removeEventListener(c,n,a),e()},a),s&&r.attachEvent(u,n=function(){/^c/.test(r[l])&&(r.detachEvent(u,n),e())}),t=s?function(e){self!=top?h?e():i.push(e):function(){try{o.doScroll("left")}catch(n){return setTimeout(function(){t(e)},50)}e()}()}:function(t){h?t():i.push(t)}}),Array.prototype.indexOf?t.indexOf=function(t,e){return t.indexOf(e)}:t.indexOf=function(t,e){if("string"==typeof t)return t.indexOf(e);var n,i,a=e?e:0;if(!this)throw new TypeError;if(i=this.length,0===i||a>=i)return-1;for(0>a&&(a=i-Math.abs(a)),n=a;i>n;n++)if(this[n]===t)return n;return-1},Array.isArray?t.isArray=function(t){return Array.isArray(t)}:t.isArray=function(t){return"[object Array]"===Object.prototype.toString.call(t)},Object.keys?t.iterate=function(t,e){if(!t)return[];var n,i=Object.keys(t);for(n=0;i[n]&&e(i[n],t[i[n]])!==!1;n++);}:t.iterate=function(t,e){if(!t)return[];var n;for(n in t)if(Object.prototype.hasOwnProperty.call(t,n)&&e(n,t[n])===!1)break},window.matchMedia?t.matchesMedia=function(t){return""==t?!0:window.matchMedia(t).matches}:window.styleMedia||window.media?t.matchesMedia=function(t){if(""==t)return!0;var e=window.styleMedia||window.media;return e.matchMedium(t||"all")}:window.getComputedStyle?t.matchesMedia=function(t){if(""==t)return!0;var e=document.createElement("style"),n=document.getElementsByTagName("script")[0],i=null;e.type="text/css",e.id="matchmediajs-test",n.parentNode.insertBefore(e,n),i="getComputedStyle"in window&&window.getComputedStyle(e,null)||e.currentStyle;var a="@media "+t+"{ #matchmediajs-test { width: 1px; } }";return e.styleSheet?e.styleSheet.cssText=a:e.textContent=a,"1px"===i.width}:t.matchesMedia=function(t){if(""==t)return!0;var e,n,i,a,r={"min-width":null,"max-width":null},o=!1;for(i=t.split(/\s+and\s+/),e=0;er["max-width"]||null!==r["min-height"]&&cr["max-height"]?!1:!0},navigator.userAgent.match(/MSIE ([0-9]+)/)&&RegExp.$1<9&&(t.newStyle=function(t){var e=document.createElement("span");return e.innerHTML=' ",e})},initVars:function(){var e,n,i,a=navigator.userAgent;e="other",n=0,i=[["firefox",/Firefox\/([0-9\.]+)/],["bb",/BlackBerry.+Version\/([0-9\.]+)/],["bb",/BB[0-9]+.+Version\/([0-9\.]+)/],["opera",/OPR\/([0-9\.]+)/],["opera",/Opera\/([0-9\.]+)/],["edge",/Edge\/([0-9\.]+)/],["safari",/Version\/([0-9\.]+).+Safari/],["chrome",/Chrome\/([0-9\.]+)/],["ie",/MSIE ([0-9]+)/],["ie",/Trident\/.+rv:([0-9]+)/]],t.iterate(i,function(t,i){return a.match(i[1])?(e=i[0],n=parseFloat(RegExp.$1),!1):void 0}),t.vars.browser=e,t.vars.browserVersion=n,e="other",n=0,i=[["ios",/([0-9_]+) like Mac OS X/,function(t){return t.replace("_",".").replace("_","")}],["ios",/CPU like Mac OS X/,function(t){return 0}],["wp",/Windows Phone ([0-9\.]+)/,null],["android",/Android ([0-9\.]+)/,null],["mac",/Macintosh.+Mac OS X ([0-9_]+)/,function(t){return t.replace("_",".").replace("_","")}],["windows",/Windows NT ([0-9\.]+)/,null],["bb",/BlackBerry.+Version\/([0-9\.]+)/,null],["bb",/BB[0-9]+.+Version\/([0-9\.]+)/,null]],t.iterate(i,function(t,i){return a.match(i[1])?(e=i[0],n=parseFloat(i[2]?i[2](RegExp.$1):RegExp.$1),!1):void 0}),t.vars.os=e,t.vars.osVersion=n,t.vars.IEVersion="ie"==t.vars.browser?t.vars.browserVersion:99,t.vars.touch="wp"==t.vars.os?navigator.msMaxTouchPoints>0:!!("ontouchstart"in window),t.vars.mobile="wp"==t.vars.os||"android"==t.vars.os||"ios"==t.vars.os||"bb"==t.vars.os}};return t.init(),t}();!function(t,e){"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?module.exports=e():t.skel=e()}(this,function(){return skel}); 3 | -------------------------------------------------------------------------------- /WebContent/controllers/searchapi.js: -------------------------------------------------------------------------------- 1 | var youtube = require('youtube-api'); 2 | var async = require('async'); 3 | var fs = require('fs'); 4 | var os = require("os"); 5 | var json2csv = require('json2csv'); 6 | var finalResults = []; 7 | var inputObject = {}; 8 | var count = 0; 9 | var publishAfterTime = ''; 10 | var publishBeforeTime = ''; 11 | 12 | var API_ACCESS_KEY = 'AIzaSyD93zoVXfwOKmkxMFU0LWKvkdzQMdm1yOk'; 13 | 14 | var nextPageToken; 15 | 16 | exports.clickedSearchButton = function(time,done){ 17 | 18 | youtube.authenticate({ 19 | type: 'key', 20 | key: API_ACCESS_KEY, 21 | }); 22 | finalResults = []; 23 | count = 0; 24 | inputObject = {}; 25 | inputObject.inputTimeWindow = time; 26 | if (fs.existsSync('data.csv')) { 27 | fs.unlinkSync('data.csv'); 28 | } 29 | search(null,done); 30 | 31 | } 32 | 33 | function search(pageToken,mycall) { 34 | 35 | getPublishBeforeAndAfterTime(); 36 | var requestOptions = { 37 | type: 'playlist', 38 | part: 'snippet', 39 | q: '', 40 | maxResults: '50', 41 | publishedAfter: publishAfterTime, 42 | publishedBefore: publishBeforeTime 43 | } 44 | if (pageToken) { 45 | requestOptions.pageToken = pageToken; 46 | } 47 | 48 | var request = youtube.search.list(requestOptions,function(err,response){ 49 | if (err) return console.log("error"); 50 | var resultsArr = []; 51 | nextPageToken = response.nextPageToken; 52 | for(var x in response.items){ 53 | var playlistResult = new Object(); 54 | playlistResult.playlistId = response.items[x].id.playlistId; 55 | resultsArr.push(playlistResult) 56 | } 57 | for (var i = 0; i < resultsArr.length; i++) { 58 | finalResults.push(resultsArr[i]); 59 | } 60 | if(nextPageToken){ 61 | search(nextPageToken,mycall); 62 | }else{ 63 | getVideoDetails(function(data){ 64 | mycall("success"); 65 | }); 66 | } 67 | }); 68 | } 69 | 70 | function getVideoDetails(callback){ 71 | 72 | var i =0 ; 73 | async.whilst( 74 | function(){ return i tag OR Just update it by replacing localhost with master 136 | 137 | 138 | 139 | fs.default.name 140 | 141 | hdfs://HadoopMaster:9000 142 | 143 | 144 | 145 | 146 | ### Update hdfs-site.xml 147 | 148 | Update this file by updating repliction factor from 1 to 3. 149 | 150 | 151 | To edit file, fire the below given command 152 | 153 | `ubuntu@hadoopmaster1:/opt/hadoop/etc/hadoop$ sudo gedit hdfs-site.xml` 154 | 155 | 156 | Paste/Update these lines into tag 157 | 158 | 159 | 160 | dfs.replication 161 | 162 | 3 163 | 164 | 165 | 166 | 167 | ### Update yarn-site.xml 168 | 169 | Update this file by updating the following three properties by updating hostname from localhost to HadoopMaster 170 | 171 | 172 | To edit file, fire the below given command 173 | 174 | `ubuntu@hadoopmaster1:/opt/hadoop/etc/hadoop$ sudo gedit yarn-site.xml` 175 | 176 | 177 | Paste/Update these lines into tag 178 | 179 | 180 | 181 | yarn.resourcemanager.resource-tracker.address 182 | 183 | HadoopMaster:8025 184 | 185 | 186 | 187 | 188 | 189 | yarn.resourcemanager.scheduler.address 190 | 191 | HadoopMaster:8035 192 | 193 | 194 | 195 | 196 | 197 | yarn.resourcemanager.address 198 | 199 | HadoopMaster:8050 200 | 201 | 202 | 203 | 204 | ### Update Mapred-site.xml 205 | 206 | Update this file by updating and adding following properties, 207 | 208 | 209 | To edit file, fire the below given command 210 | 211 | `ubuntu@hadoopmaster1:/opt/hadoop/etc/hadoop$ sudo gedit mapred-site.xml` 212 | 213 | 214 | Paste/Update these lines into tag 215 | 216 | 217 | 218 | mapreduce.job.tracker 219 | 220 | HadoopMaster:5431 221 | 222 | 223 | 224 | 225 | 226 | mapred.framework.name 227 | 228 | yarn 229 | 230 | 231 | 232 | 233 | ### Update slaves 234 | 235 | Update the directory of slave nodes of Hadoop cluster 236 | 237 | 238 | To edit file, fire the below given command 239 | 240 | `ubuntu@hadoopmaster1:/opt/hadoop/etc/hadoop$ sudo gedit slaves` 241 | 242 | 243 | ### Add name of slave nodes 244 | 245 | hadoopslave1 246 | hadoopslave2 247 | hadoopslave3 248 | 249 | 250 | ### Format Namenonde (Run on MasterNode) : 251 | 252 | Run this command from Masternode 253 | 254 | ubuntu@hadoopmaster1: /opt/hadoop/$ hdfs namenode -format 255 | 256 | 257 | ### Copy Hadoop distribution to other nodes: 258 | 259 | `sudo scp -R /opt/hadoop/ ubuntu@hadoopslave1:/opt/` 260 | 261 | `sudo scp -R /opt/hadoop/ ubuntu@hadoopslave2:/opt/` 262 | 263 | `sudo scp -R /opt/hadoop/ ubuntu@hadoopslave3:/opt/` 264 | 265 | 266 | ### Starting Namenode, Datanode and ResourceManger: 267 | 268 | `start-all.sh` 269 | 270 | 271 | ### Check if Hadoop started as desired using jps command. 272 | 273 | 274 | ## Obtaining Youtube API access key 275 | 276 | Use the following link to obtain an API access key. 277 | 278 | https://youtu.be/JbWnRhHfTDA 279 | 280 | ## Install Node.js and node package manager 281 | 282 | 283 | `sudo apt-get update` 284 | 285 | `sudo apt-get install nodejs` 286 | 287 | `sudo apt-get install npm` 288 | 289 | 290 | After installing node.js and npm go to WebContent folder and run the below command to download all the dependencies. 291 | 292 | 293 | `npm install` 294 | 295 | 296 | ## Run The Project 297 | 298 | Run the nodejs server using the command. 299 | 300 | `cd YouTube-Data-Analysis/WebContent/` 301 | 302 | `nodejs app.js` 303 | 304 | The project will be up and running at port `http://localhost:8080` 305 | 306 | Click on `Get More Data` option on the sidebar to get new data via the YouTube API. After the data is stored in the server, a script will run in background to store the data in Hadoop File system. 307 | 308 | Click on `Statistics` option on the sidebar to run the Hadoop MapReduce algorithm on the data. The `Analyze data` button will run the script to start hadoop MapReduce algorithm. The result will be displayed on the same webpage. 309 | 310 | ## Description of each file 311 | 312 | Filename | Purpose | New/Modified | Comments 313 | ------------- | ----------------|------------------ | ---------- 314 | YoutubeCategory.java | Mapper Reducer code to get top 5 categories | New | Create JAR of this file to run in Hadoop system 315 | YoutubeUploader.java | Mapper Reducer code to get top uploaders | New | Create JAR of this file to run in Hadoop system 316 | YoutubeView.java | Mapper Reducer code to get most viewed videos | New | Create JAR of this file to run in Hadoop system 317 | analyzedata.sh | Shell script to execute Hadoop commands | New | Merged Sorting commands in the file 318 | getdata.sh | Shell script to copy the data file from server to HDFS | New | No Comments 319 | app.js | Main configuration file to run the entire application | Modified | Changed client server communication from AJAX to socket.io 320 | searchapi.js | Connect to YouTube data API to fetch data in a file | Modified | Changed callbacks and data to be fetched -------------------------------------------------------------------------------- /WebContent/public/assets/js/util.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | 3 | /** 4 | * Generate an indented list of links from a nav. Meant for use with panel(). 5 | * @return {jQuery} jQuery object. 6 | */ 7 | $.fn.navList = function() { 8 | 9 | var $this = $(this); 10 | $a = $this.find('a'), 11 | b = []; 12 | 13 | $a.each(function() { 14 | 15 | var $this = $(this), 16 | indent = Math.max(0, $this.parents('li').length - 1), 17 | href = $this.attr('href'), 18 | target = $this.attr('target'); 19 | 20 | b.push( 21 | '' + 26 | '' + 27 | $this.text() + 28 | '' 29 | ); 30 | 31 | }); 32 | 33 | return b.join(''); 34 | 35 | }; 36 | 37 | /** 38 | * Panel-ify an element. 39 | * @param {object} userConfig User config. 40 | * @return {jQuery} jQuery object. 41 | */ 42 | $.fn.panel = function(userConfig) { 43 | 44 | // No elements? 45 | if (this.length == 0) 46 | return $this; 47 | 48 | // Multiple elements? 49 | if (this.length > 1) { 50 | 51 | for (var i=0; i < this.length; i++) 52 | $(this[i]).panel(userConfig); 53 | 54 | return $this; 55 | 56 | } 57 | 58 | // Vars. 59 | var $this = $(this), 60 | $body = $('body'), 61 | $window = $(window), 62 | id = $this.attr('id'), 63 | config; 64 | 65 | // Config. 66 | config = $.extend({ 67 | 68 | // Delay. 69 | delay: 0, 70 | 71 | // Hide panel on link click. 72 | hideOnClick: false, 73 | 74 | // Hide panel on escape keypress. 75 | hideOnEscape: false, 76 | 77 | // Hide panel on swipe. 78 | hideOnSwipe: false, 79 | 80 | // Reset scroll position on hide. 81 | resetScroll: false, 82 | 83 | // Reset forms on hide. 84 | resetForms: false, 85 | 86 | // Side of viewport the panel will appear. 87 | side: null, 88 | 89 | // Target element for "class". 90 | target: $this, 91 | 92 | // Class to toggle. 93 | visibleClass: 'visible' 94 | 95 | }, userConfig); 96 | 97 | // Expand "target" if it's not a jQuery object already. 98 | if (typeof config.target != 'jQuery') 99 | config.target = $(config.target); 100 | 101 | // Panel. 102 | 103 | // Methods. 104 | $this._hide = function(event) { 105 | 106 | // Already hidden? Bail. 107 | if (!config.target.hasClass(config.visibleClass)) 108 | return; 109 | 110 | // If an event was provided, cancel it. 111 | if (event) { 112 | 113 | event.preventDefault(); 114 | event.stopPropagation(); 115 | 116 | } 117 | 118 | // Hide. 119 | config.target.removeClass(config.visibleClass); 120 | 121 | // Post-hide stuff. 122 | window.setTimeout(function() { 123 | 124 | // Reset scroll position. 125 | if (config.resetScroll) 126 | $this.scrollTop(0); 127 | 128 | // Reset forms. 129 | if (config.resetForms) 130 | $this.find('form').each(function() { 131 | this.reset(); 132 | }); 133 | 134 | }, config.delay); 135 | 136 | }; 137 | 138 | // Vendor fixes. 139 | $this 140 | .css('-ms-overflow-style', '-ms-autohiding-scrollbar') 141 | .css('-webkit-overflow-scrolling', 'touch'); 142 | 143 | // Hide on click. 144 | if (config.hideOnClick) { 145 | 146 | $this.find('a') 147 | .css('-webkit-tap-highlight-color', 'rgba(0,0,0,0)'); 148 | 149 | $this 150 | .on('click', 'a', function(event) { 151 | 152 | var $a = $(this), 153 | href = $a.attr('href'), 154 | target = $a.attr('target'); 155 | 156 | if (!href || href == '#' || href == '' || href == '#' + id) 157 | return; 158 | 159 | // Cancel original event. 160 | event.preventDefault(); 161 | event.stopPropagation(); 162 | 163 | // Hide panel. 164 | $this._hide(); 165 | 166 | // Redirect to href. 167 | window.setTimeout(function() { 168 | 169 | if (target == '_blank') 170 | window.open(href); 171 | else 172 | window.location.href = href; 173 | 174 | }, config.delay + 10); 175 | 176 | }); 177 | 178 | } 179 | 180 | // Event: Touch stuff. 181 | $this.on('touchstart', function(event) { 182 | 183 | $this.touchPosX = event.originalEvent.touches[0].pageX; 184 | $this.touchPosY = event.originalEvent.touches[0].pageY; 185 | 186 | }) 187 | 188 | $this.on('touchmove', function(event) { 189 | 190 | if ($this.touchPosX === null 191 | || $this.touchPosY === null) 192 | return; 193 | 194 | var diffX = $this.touchPosX - event.originalEvent.touches[0].pageX, 195 | diffY = $this.touchPosY - event.originalEvent.touches[0].pageY, 196 | th = $this.outerHeight(), 197 | ts = ($this.get(0).scrollHeight - $this.scrollTop()); 198 | 199 | // Hide on swipe? 200 | if (config.hideOnSwipe) { 201 | 202 | var result = false, 203 | boundary = 20, 204 | delta = 50; 205 | 206 | switch (config.side) { 207 | 208 | case 'left': 209 | result = (diffY < boundary && diffY > (-1 * boundary)) && (diffX > delta); 210 | break; 211 | 212 | case 'right': 213 | result = (diffY < boundary && diffY > (-1 * boundary)) && (diffX < (-1 * delta)); 214 | break; 215 | 216 | case 'top': 217 | result = (diffX < boundary && diffX > (-1 * boundary)) && (diffY > delta); 218 | break; 219 | 220 | case 'bottom': 221 | result = (diffX < boundary && diffX > (-1 * boundary)) && (diffY < (-1 * delta)); 222 | break; 223 | 224 | default: 225 | break; 226 | 227 | } 228 | 229 | if (result) { 230 | 231 | $this.touchPosX = null; 232 | $this.touchPosY = null; 233 | $this._hide(); 234 | 235 | return false; 236 | 237 | } 238 | 239 | } 240 | 241 | // Prevent vertical scrolling past the top or bottom. 242 | if (($this.scrollTop() < 0 && diffY < 0) 243 | || (ts > (th - 2) && ts < (th + 2) && diffY > 0)) { 244 | 245 | event.preventDefault(); 246 | event.stopPropagation(); 247 | 248 | } 249 | 250 | }); 251 | 252 | // Event: Prevent certain events inside the panel from bubbling. 253 | $this.on('click touchend touchstart touchmove', function(event) { 254 | event.stopPropagation(); 255 | }); 256 | 257 | // Event: Hide panel if a child anchor tag pointing to its ID is clicked. 258 | $this.on('click', 'a[href="#' + id + '"]', function(event) { 259 | 260 | event.preventDefault(); 261 | event.stopPropagation(); 262 | 263 | config.target.removeClass(config.visibleClass); 264 | 265 | }); 266 | 267 | // Body. 268 | 269 | // Event: Hide panel on body click/tap. 270 | $body.on('click touchend', function(event) { 271 | $this._hide(event); 272 | }); 273 | 274 | // Event: Toggle. 275 | $body.on('click', 'a[href="#' + id + '"]', function(event) { 276 | 277 | event.preventDefault(); 278 | event.stopPropagation(); 279 | 280 | config.target.toggleClass(config.visibleClass); 281 | 282 | }); 283 | 284 | // Window. 285 | 286 | // Event: Hide on ESC. 287 | if (config.hideOnEscape) 288 | $window.on('keydown', function(event) { 289 | 290 | if (event.keyCode == 27) 291 | $this._hide(event); 292 | 293 | }); 294 | 295 | return $this; 296 | 297 | }; 298 | 299 | /** 300 | * Apply "placeholder" attribute polyfill to one or more forms. 301 | * @return {jQuery} jQuery object. 302 | */ 303 | $.fn.placeholder = function() { 304 | 305 | // Browser natively supports placeholders? Bail. 306 | if (typeof (document.createElement('input')).placeholder != 'undefined') 307 | return $(this); 308 | 309 | // No elements? 310 | if (this.length == 0) 311 | return $this; 312 | 313 | // Multiple elements? 314 | if (this.length > 1) { 315 | 316 | for (var i=0; i < this.length; i++) 317 | $(this[i]).placeholder(); 318 | 319 | return $this; 320 | 321 | } 322 | 323 | // Vars. 324 | var $this = $(this); 325 | 326 | // Text, TextArea. 327 | $this.find('input[type=text],textarea') 328 | .each(function() { 329 | 330 | var i = $(this); 331 | 332 | if (i.val() == '' 333 | || i.val() == i.attr('placeholder')) 334 | i 335 | .addClass('polyfill-placeholder') 336 | .val(i.attr('placeholder')); 337 | 338 | }) 339 | .on('blur', function() { 340 | 341 | var i = $(this); 342 | 343 | if (i.attr('name').match(/-polyfill-field$/)) 344 | return; 345 | 346 | if (i.val() == '') 347 | i 348 | .addClass('polyfill-placeholder') 349 | .val(i.attr('placeholder')); 350 | 351 | }) 352 | .on('focus', function() { 353 | 354 | var i = $(this); 355 | 356 | if (i.attr('name').match(/-polyfill-field$/)) 357 | return; 358 | 359 | if (i.val() == i.attr('placeholder')) 360 | i 361 | .removeClass('polyfill-placeholder') 362 | .val(''); 363 | 364 | }); 365 | 366 | // Password. 367 | $this.find('input[type=password]') 368 | .each(function() { 369 | 370 | var i = $(this); 371 | var x = $( 372 | $('
') 373 | .append(i.clone()) 374 | .remove() 375 | .html() 376 | .replace(/type="password"/i, 'type="text"') 377 | .replace(/type=password/i, 'type=text') 378 | ); 379 | 380 | if (i.attr('id') != '') 381 | x.attr('id', i.attr('id') + '-polyfill-field'); 382 | 383 | if (i.attr('name') != '') 384 | x.attr('name', i.attr('name') + '-polyfill-field'); 385 | 386 | x.addClass('polyfill-placeholder') 387 | .val(x.attr('placeholder')).insertAfter(i); 388 | 389 | if (i.val() == '') 390 | i.hide(); 391 | else 392 | x.hide(); 393 | 394 | i 395 | .on('blur', function(event) { 396 | 397 | event.preventDefault(); 398 | 399 | var x = i.parent().find('input[name=' + i.attr('name') + '-polyfill-field]'); 400 | 401 | if (i.val() == '') { 402 | 403 | i.hide(); 404 | x.show(); 405 | 406 | } 407 | 408 | }); 409 | 410 | x 411 | .on('focus', function(event) { 412 | 413 | event.preventDefault(); 414 | 415 | var i = x.parent().find('input[name=' + x.attr('name').replace('-polyfill-field', '') + ']'); 416 | 417 | x.hide(); 418 | 419 | i 420 | .show() 421 | .focus(); 422 | 423 | }) 424 | .on('keypress', function(event) { 425 | 426 | event.preventDefault(); 427 | x.val(''); 428 | 429 | }); 430 | 431 | }); 432 | 433 | // Events. 434 | $this 435 | .on('submit', function() { 436 | 437 | $this.find('input[type=text],input[type=password],textarea') 438 | .each(function(event) { 439 | 440 | var i = $(this); 441 | 442 | if (i.attr('name').match(/-polyfill-field$/)) 443 | i.attr('name', ''); 444 | 445 | if (i.val() == i.attr('placeholder')) { 446 | 447 | i.removeClass('polyfill-placeholder'); 448 | i.val(''); 449 | 450 | } 451 | 452 | }); 453 | 454 | }) 455 | .on('reset', function(event) { 456 | 457 | event.preventDefault(); 458 | 459 | $this.find('select') 460 | .val($('option:first').val()); 461 | 462 | $this.find('input,textarea') 463 | .each(function() { 464 | 465 | var i = $(this), 466 | x; 467 | 468 | i.removeClass('polyfill-placeholder'); 469 | 470 | switch (this.type) { 471 | 472 | case 'submit': 473 | case 'reset': 474 | break; 475 | 476 | case 'password': 477 | i.val(i.attr('defaultValue')); 478 | 479 | x = i.parent().find('input[name=' + i.attr('name') + '-polyfill-field]'); 480 | 481 | if (i.val() == '') { 482 | i.hide(); 483 | x.show(); 484 | } 485 | else { 486 | i.show(); 487 | x.hide(); 488 | } 489 | 490 | break; 491 | 492 | case 'checkbox': 493 | case 'radio': 494 | i.attr('checked', i.attr('defaultValue')); 495 | break; 496 | 497 | case 'text': 498 | case 'textarea': 499 | i.val(i.attr('defaultValue')); 500 | 501 | if (i.val() == '') { 502 | i.addClass('polyfill-placeholder'); 503 | i.val(i.attr('placeholder')); 504 | } 505 | 506 | break; 507 | 508 | default: 509 | i.val(i.attr('defaultValue')); 510 | break; 511 | 512 | } 513 | }); 514 | 515 | }); 516 | 517 | return $this; 518 | 519 | }; 520 | 521 | /** 522 | * Moves elements to/from the first positions of their respective parents. 523 | * @param {jQuery} $elements Elements (or selector) to move. 524 | * @param {bool} condition If true, moves elements to the top. Otherwise, moves elements back to their original locations. 525 | */ 526 | $.prioritize = function($elements, condition) { 527 | 528 | var key = '__prioritize'; 529 | 530 | // Expand $elements if it's not already a jQuery object. 531 | if (typeof $elements != 'jQuery') 532 | $elements = $($elements); 533 | 534 | // Step through elements. 535 | $elements.each(function() { 536 | 537 | var $e = $(this), $p, 538 | $parent = $e.parent(); 539 | 540 | // No parent? Bail. 541 | if ($parent.length == 0) 542 | return; 543 | 544 | // Not moved? Move it. 545 | if (!$e.data(key)) { 546 | 547 | // Condition is false? Bail. 548 | if (!condition) 549 | return; 550 | 551 | // Get placeholder (which will serve as our point of reference for when this element needs to move back). 552 | $p = $e.prev(); 553 | 554 | // Couldn't find anything? Means this element's already at the top, so bail. 555 | if ($p.length == 0) 556 | return; 557 | 558 | // Move element to top of parent. 559 | $e.prependTo($parent); 560 | 561 | // Mark element as moved. 562 | $e.data(key, $p); 563 | 564 | } 565 | 566 | // Moved already? 567 | else { 568 | 569 | // Condition is true? Bail. 570 | if (condition) 571 | return; 572 | 573 | $p = $e.data(key); 574 | 575 | // Move element back to its original location (using our placeholder). 576 | $e.insertAfter($p); 577 | 578 | // Unmark element as moved. 579 | $e.removeData(key); 580 | 581 | } 582 | 583 | }); 584 | 585 | }; 586 | 587 | })(jQuery); -------------------------------------------------------------------------------- /WebContent/.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 22 | 23 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 68 | 69 | 74 | 75 | 76 | 77 | 78 | true 79 | DEFINITION_ORDER 80 | 81 | 82 | 83 | 84 | 85 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | project 146 | 147 | 148 | true 149 | 150 | 151 | 152 | DIRECTORY 153 | 154 | false 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 1476497571596 176 | 181 | 182 | 183 | 184 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 212 | 215 | 216 | 217 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | -------------------------------------------------------------------------------- /WebContent/public/assets/sass/libs/_skel.scss: -------------------------------------------------------------------------------- 1 | // skel.scss v3.0.1 | (c) skel.io | MIT licensed */ 2 | 3 | // Vars. 4 | 5 | /// Breakpoints. 6 | /// @var {list} 7 | $breakpoints: () !global; 8 | 9 | /// Vendor prefixes. 10 | /// @var {list} 11 | $vendor-prefixes: ( 12 | '-moz-', 13 | '-webkit-', 14 | '-ms-', 15 | '' 16 | ); 17 | 18 | /// Properties that should be vendorized. 19 | /// @var {list} 20 | $vendor-properties: ( 21 | 'align-content', 22 | 'align-items', 23 | 'align-self', 24 | 'animation', 25 | 'animation-delay', 26 | 'animation-direction', 27 | 'animation-duration', 28 | 'animation-fill-mode', 29 | 'animation-iteration-count', 30 | 'animation-name', 31 | 'animation-play-state', 32 | 'animation-timing-function', 33 | 'appearance', 34 | 'backface-visibility', 35 | 'box-sizing', 36 | 'filter', 37 | 'flex', 38 | 'flex-basis', 39 | 'flex-direction', 40 | 'flex-flow', 41 | 'flex-grow', 42 | 'flex-shrink', 43 | 'flex-wrap', 44 | 'justify-content', 45 | 'order', 46 | 'perspective', 47 | 'pointer-events', 48 | 'transform', 49 | 'transform-origin', 50 | 'transform-style', 51 | 'transition', 52 | 'transition-delay', 53 | 'transition-duration', 54 | 'transition-property', 55 | 'transition-timing-function', 56 | 'user-select' 57 | ); 58 | 59 | /// Values that should be vendorized. 60 | /// @var {list} 61 | $vendor-values: ( 62 | 'filter', 63 | 'flex', 64 | 'linear-gradient', 65 | 'radial-gradient', 66 | 'transform' 67 | ); 68 | 69 | // Functions. 70 | 71 | /// Removes a specific item from a list. 72 | /// @author Hugo Giraudel 73 | /// @param {list} $list List. 74 | /// @param {integer} $index Index. 75 | /// @return {list} Updated list. 76 | @function remove-nth($list, $index) { 77 | 78 | $result: null; 79 | 80 | @if type-of($index) != number { 81 | @warn "$index: #{quote($index)} is not a number for `remove-nth`."; 82 | } 83 | @else if $index == 0 { 84 | @warn "List index 0 must be a non-zero integer for `remove-nth`."; 85 | } 86 | @else if abs($index) > length($list) { 87 | @warn "List index is #{$index} but list is only #{length($list)} item long for `remove-nth`."; 88 | } 89 | @else { 90 | 91 | $result: (); 92 | $index: if($index < 0, length($list) + $index + 1, $index); 93 | 94 | @for $i from 1 through length($list) { 95 | 96 | @if $i != $index { 97 | $result: append($result, nth($list, $i)); 98 | } 99 | 100 | } 101 | 102 | } 103 | 104 | @return $result; 105 | 106 | } 107 | 108 | /// Replaces a substring within another string. 109 | /// @author Hugo Giraudel 110 | /// @param {string} $string String. 111 | /// @param {string} $search Substring. 112 | /// @param {string} $replace Replacement. 113 | /// @return {string} Updated string. 114 | @function str-replace($string, $search, $replace: '') { 115 | 116 | $index: str-index($string, $search); 117 | 118 | @if $index { 119 | @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace); 120 | } 121 | 122 | @return $string; 123 | 124 | } 125 | 126 | /// Replaces a substring within each string in a list. 127 | /// @param {list} $strings List of strings. 128 | /// @param {string} $search Substring. 129 | /// @param {string} $replace Replacement. 130 | /// @return {list} Updated list of strings. 131 | @function str-replace-all($strings, $search, $replace: '') { 132 | 133 | @each $string in $strings { 134 | $strings: set-nth($strings, index($strings, $string), str-replace($string, $search, $replace)); 135 | } 136 | 137 | @return $strings; 138 | 139 | } 140 | 141 | /// Gets a value from a map. 142 | /// @author Hugo Giraudel 143 | /// @param {map} $map Map. 144 | /// @param {string} $keys Key(s). 145 | /// @return {string} Value. 146 | @function val($map, $keys...) { 147 | 148 | @if nth($keys, 1) == null { 149 | $keys: remove-nth($keys, 1); 150 | } 151 | 152 | @each $key in $keys { 153 | $map: map-get($map, $key); 154 | } 155 | 156 | @return $map; 157 | 158 | } 159 | 160 | // Mixins. 161 | 162 | /// Sets the global box model. 163 | /// @param {string} $model Model (default is content). 164 | @mixin boxModel($model: 'content') { 165 | 166 | $x: $model + '-box'; 167 | 168 | *, *:before, *:after { 169 | -moz-box-sizing: #{$x}; 170 | -webkit-box-sizing: #{$x}; 171 | box-sizing: #{$x}; 172 | } 173 | 174 | } 175 | 176 | /// Wraps @content in a @media block using a given breakpoint. 177 | /// @param {string} $breakpoint Breakpoint. 178 | /// @param {map} $queries Additional queries. 179 | @mixin breakpoint($breakpoint: null, $queries: null) { 180 | 181 | $query: 'screen'; 182 | 183 | // Breakpoint. 184 | @if $breakpoint and map-has-key($breakpoints, $breakpoint) { 185 | $query: $query + ' and ' + map-get($breakpoints, $breakpoint); 186 | } 187 | 188 | // Queries. 189 | @if $queries { 190 | @each $k, $v in $queries { 191 | $query: $query + ' and (' + $k + ':' + $v + ')'; 192 | } 193 | } 194 | 195 | @media #{$query} { 196 | @content; 197 | } 198 | 199 | } 200 | 201 | /// Wraps @content in a @media block targeting a specific orientation. 202 | /// @param {string} $orientation Orientation. 203 | @mixin orientation($orientation) { 204 | @media screen and (orientation: #{$orientation}) { 205 | @content; 206 | } 207 | } 208 | 209 | /// Utility mixin for containers. 210 | /// @param {mixed} $width Width. 211 | @mixin containers($width) { 212 | 213 | // Locked? 214 | $lock: false; 215 | 216 | @if length($width) == 2 { 217 | $width: nth($width, 1); 218 | $lock: true; 219 | } 220 | 221 | // Modifiers. 222 | .container.\31 25\25 { width: 100%; max-width: $width * 1.25; min-width: $width; } 223 | .container.\37 5\25 { width: $width * 0.75; } 224 | .container.\35 0\25 { width: $width * 0.5; } 225 | .container.\32 5\25 { width: $width * 0.25; } 226 | 227 | // Main class. 228 | .container { 229 | @if $lock { 230 | width: $width !important; 231 | } 232 | @else { 233 | width: $width; 234 | } 235 | } 236 | 237 | } 238 | 239 | /// Utility mixin for grid. 240 | /// @param {list} $gutters Column and row gutters (default is 40px). 241 | /// @param {string} $breakpointName Optional breakpoint name. 242 | @mixin grid($gutters: 40px, $breakpointName: null) { 243 | 244 | // Gutters. 245 | @include grid-gutters($gutters); 246 | @include grid-gutters($gutters, \32 00\25, 2); 247 | @include grid-gutters($gutters, \31 50\25, 1.5); 248 | @include grid-gutters($gutters, \35 0\25, 0.5); 249 | @include grid-gutters($gutters, \32 5\25, 0.25); 250 | 251 | // Cells. 252 | $x: ''; 253 | 254 | @if $breakpointName { 255 | $x: '\\28' + $breakpointName + '\\29'; 256 | } 257 | 258 | .\31 2u#{$x}, .\31 2u\24#{$x} { width: 100%; clear: none; margin-left: 0; } 259 | .\31 1u#{$x}, .\31 1u\24#{$x} { width: 91.6666666667%; clear: none; margin-left: 0; } 260 | .\31 0u#{$x}, .\31 0u\24#{$x} { width: 83.3333333333%; clear: none; margin-left: 0; } 261 | .\39 u#{$x}, .\39 u\24#{$x} { width: 75%; clear: none; margin-left: 0; } 262 | .\38 u#{$x}, .\38 u\24#{$x} { width: 66.6666666667%; clear: none; margin-left: 0; } 263 | .\37 u#{$x}, .\37 u\24#{$x} { width: 58.3333333333%; clear: none; margin-left: 0; } 264 | .\36 u#{$x}, .\36 u\24#{$x} { width: 50%; clear: none; margin-left: 0; } 265 | .\35 u#{$x}, .\35 u\24#{$x} { width: 41.6666666667%; clear: none; margin-left: 0; } 266 | .\34 u#{$x}, .\34 u\24#{$x} { width: 33.3333333333%; clear: none; margin-left: 0; } 267 | .\33 u#{$x}, .\33 u\24#{$x} { width: 25%; clear: none; margin-left: 0; } 268 | .\32 u#{$x}, .\32 u\24#{$x} { width: 16.6666666667%; clear: none; margin-left: 0; } 269 | .\31 u#{$x}, .\31 u\24#{$x} { width: 8.3333333333%; clear: none; margin-left: 0; } 270 | 271 | .\31 2u\24#{$x} + *, 272 | .\31 1u\24#{$x} + *, 273 | .\31 0u\24#{$x} + *, 274 | .\39 u\24#{$x} + *, 275 | .\38 u\24#{$x} + *, 276 | .\37 u\24#{$x} + *, 277 | .\36 u\24#{$x} + *, 278 | .\35 u\24#{$x} + *, 279 | .\34 u\24#{$x} + *, 280 | .\33 u\24#{$x} + *, 281 | .\32 u\24#{$x} + *, 282 | .\31 u\24#{$x} + * { 283 | clear: left; 284 | } 285 | 286 | .\-11u#{$x} { margin-left: 91.6666666667% } 287 | .\-10u#{$x} { margin-left: 83.3333333333% } 288 | .\-9u#{$x} { margin-left: 75% } 289 | .\-8u#{$x} { margin-left: 66.6666666667% } 290 | .\-7u#{$x} { margin-left: 58.3333333333% } 291 | .\-6u#{$x} { margin-left: 50% } 292 | .\-5u#{$x} { margin-left: 41.6666666667% } 293 | .\-4u#{$x} { margin-left: 33.3333333333% } 294 | .\-3u#{$x} { margin-left: 25% } 295 | .\-2u#{$x} { margin-left: 16.6666666667% } 296 | .\-1u#{$x} { margin-left: 8.3333333333% } 297 | 298 | } 299 | 300 | /// Utility mixin for grid. 301 | /// @param {list} $gutters Gutters. 302 | /// @param {string} $class Optional class name. 303 | /// @param {integer} $multiplier Multiplier (default is 1). 304 | @mixin grid-gutters($gutters, $class: null, $multiplier: 1) { 305 | 306 | // Expand gutters if it's not a list. 307 | @if length($gutters) == 1 { 308 | $gutters: ($gutters, 0); 309 | } 310 | 311 | // Get column and row gutter values. 312 | $c: nth($gutters, 1); 313 | $r: nth($gutters, 2); 314 | 315 | // Get class (if provided). 316 | $x: ''; 317 | 318 | @if $class { 319 | $x: '.' + $class; 320 | } 321 | 322 | // Default. 323 | .row#{$x} > * { padding: ($r * $multiplier) 0 0 ($c * $multiplier); } 324 | .row#{$x} { margin: ($r * $multiplier * -1) 0 -1px ($c * $multiplier * -1); } 325 | 326 | // Uniform. 327 | .row.uniform#{$x} > * { padding: ($c * $multiplier) 0 0 ($c * $multiplier); } 328 | .row.uniform#{$x} { margin: ($c * $multiplier * -1) 0 -1px ($c * $multiplier * -1); } 329 | 330 | } 331 | 332 | /// Wraps @content in vendorized keyframe blocks. 333 | /// @param {string} $name Name. 334 | @mixin keyframes($name) { 335 | 336 | @-moz-keyframes #{$name} { @content; } 337 | @-webkit-keyframes #{$name} { @content; } 338 | @-ms-keyframes #{$name} { @content; } 339 | @keyframes #{$name} { @content; } 340 | 341 | } 342 | 343 | /// 344 | /// Sets breakpoints. 345 | /// @param {map} $x Breakpoints. 346 | /// 347 | @mixin skel-breakpoints($x: ()) { 348 | $breakpoints: $x !global; 349 | } 350 | 351 | /// 352 | /// Initializes layout module. 353 | /// @param {map} config Config. 354 | /// 355 | @mixin skel-layout($config: ()) { 356 | 357 | // Config. 358 | $configPerBreakpoint: (); 359 | 360 | $z: map-get($config, 'breakpoints'); 361 | 362 | @if $z { 363 | $configPerBreakpoint: $z; 364 | } 365 | 366 | // Reset. 367 | $x: map-get($config, 'reset'); 368 | 369 | @if $x { 370 | 371 | /* Reset */ 372 | 373 | @include reset($x); 374 | 375 | } 376 | 377 | // Box model. 378 | $x: map-get($config, 'boxModel'); 379 | 380 | @if $x { 381 | 382 | /* Box Model */ 383 | 384 | @include boxModel($x); 385 | 386 | } 387 | 388 | // Containers. 389 | $containers: map-get($config, 'containers'); 390 | 391 | @if $containers { 392 | 393 | /* Containers */ 394 | 395 | .container { 396 | margin-left: auto; 397 | margin-right: auto; 398 | } 399 | 400 | // Use default is $containers is just "true". 401 | @if $containers == true { 402 | $containers: 960px; 403 | } 404 | 405 | // Apply base. 406 | @include containers($containers); 407 | 408 | // Apply per-breakpoint. 409 | @each $name in map-keys($breakpoints) { 410 | 411 | // Get/use breakpoint setting if it exists. 412 | $x: map-get($configPerBreakpoint, $name); 413 | 414 | // Per-breakpoint config exists? 415 | @if $x { 416 | $y: map-get($x, 'containers'); 417 | 418 | // Setting exists? Use it. 419 | @if $y { 420 | $containers: $y; 421 | } 422 | 423 | } 424 | 425 | // Create @media block. 426 | @media screen and #{map-get($breakpoints, $name)} { 427 | @include containers($containers); 428 | } 429 | 430 | } 431 | 432 | } 433 | 434 | // Grid. 435 | $grid: map-get($config, 'grid'); 436 | 437 | @if $grid { 438 | 439 | /* Grid */ 440 | 441 | // Use defaults if $grid is just "true". 442 | @if $grid == true { 443 | $grid: (); 444 | } 445 | 446 | // Sub-setting: Gutters. 447 | $grid-gutters: 40px; 448 | $x: map-get($grid, 'gutters'); 449 | 450 | @if $x { 451 | $grid-gutters: $x; 452 | } 453 | 454 | // Rows. 455 | .row { 456 | border-bottom: solid 1px transparent; 457 | -moz-box-sizing: border-box; 458 | -webkit-box-sizing: border-box; 459 | box-sizing: border-box; 460 | } 461 | 462 | .row > * { 463 | float: left; 464 | -moz-box-sizing: border-box; 465 | -webkit-box-sizing: border-box; 466 | box-sizing: border-box; 467 | } 468 | 469 | .row:after, .row:before { 470 | content: ''; 471 | display: block; 472 | clear: both; 473 | height: 0; 474 | } 475 | 476 | .row.uniform > * > :first-child { 477 | margin-top: 0; 478 | } 479 | 480 | .row.uniform > * > :last-child { 481 | margin-bottom: 0; 482 | } 483 | 484 | // Gutters (0%). 485 | @include grid-gutters($grid-gutters, \30 \25, 0); 486 | 487 | // Apply base. 488 | @include grid($grid-gutters); 489 | 490 | // Apply per-breakpoint. 491 | @each $name in map-keys($breakpoints) { 492 | 493 | // Get/use breakpoint setting if it exists. 494 | $x: map-get($configPerBreakpoint, $name); 495 | 496 | // Per-breakpoint config exists? 497 | @if $x { 498 | $y: map-get($x, 'grid'); 499 | 500 | // Setting exists? 501 | @if $y { 502 | 503 | // Sub-setting: Gutters. 504 | $x: map-get($y, 'gutters'); 505 | 506 | @if $x { 507 | $grid-gutters: $x; 508 | } 509 | 510 | } 511 | 512 | } 513 | 514 | // Create @media block. 515 | @media screen and #{map-get($breakpoints, $name)} { 516 | @include grid($grid-gutters, $name); 517 | } 518 | 519 | } 520 | 521 | } 522 | 523 | } 524 | 525 | /// Resets browser styles. 526 | /// @param {string} $mode Mode (default is 'normalize'). 527 | @mixin reset($mode: 'normalize') { 528 | 529 | @if $mode == 'normalize' { 530 | 531 | // normalize.css v3.0.2 | MIT License | git.io/normalize 532 | html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0} 533 | 534 | } 535 | @else if $mode == 'full' { 536 | 537 | // meyerweb.com/eric/tools/css/reset v2.0 | 20110126 | License: none (public domain) 538 | html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline;}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block;}body{line-height:1;}ol,ul{list-style:none;}blockquote,q{quotes:none;}blockquote:before,blockquote:after,q:before,q:after{content:'';content:none;}table{border-collapse:collapse;border-spacing:0;}body{-webkit-text-size-adjust:none} 539 | 540 | } 541 | 542 | } 543 | 544 | /// Vendorizes a declaration's property and/or value(s). 545 | /// @param {string} $property Property. 546 | /// @param {mixed} $value String/list of value(s). 547 | @mixin vendor($property, $value) { 548 | 549 | // Determine if property should expand. 550 | $expandProperty: index($vendor-properties, $property); 551 | 552 | // Determine if value should expand (and if so, add '-prefix-' placeholder). 553 | $expandValue: false; 554 | 555 | @each $x in $value { 556 | @each $y in $vendor-values { 557 | @if $y == str-slice($x, 1, str-length($y)) { 558 | 559 | $value: set-nth($value, index($value, $x), '-prefix-' + $x); 560 | $expandValue: true; 561 | 562 | } 563 | } 564 | } 565 | 566 | // Expand property? 567 | @if $expandProperty { 568 | @each $vendor in $vendor-prefixes { 569 | #{$vendor}#{$property}: #{str-replace-all($value, '-prefix-', $vendor)}; 570 | } 571 | } 572 | 573 | // Expand just the value? 574 | @elseif $expandValue { 575 | @each $vendor in $vendor-prefixes { 576 | #{$property}: #{str-replace-all($value, '-prefix-', $vendor)}; 577 | } 578 | } 579 | 580 | // Neither? Treat them as a normal declaration. 581 | @else { 582 | #{$property}: #{$value}; 583 | } 584 | 585 | } --------------------------------------------------------------------------------