diff --git a/.gitignore b/.gitignore index 8ebb40ff..6369fe36 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .DS_Store .idea *.sublime* +npm-debug.log private*.json @@ -8,3 +9,4 @@ private*.json /bower_components /public /build +**/__pycache__ diff --git a/gulpfile.js b/gulpfile.js index bdc4c722..313c6c43 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -12,20 +12,20 @@ var is_production = process.env['NODE_ENV'] == 'production'; gulp.task("concat-bower", function () { var files = [ - "public/bower_components/jquery/dist/jquery.min.js", - "public/bower_components/angular/angular.min.js", - "public/bower_components/angular-route/angular-route.min.js", - "public/bower_components/angular-animate/angular-animate.min.js", - "public/bower_components/angulartics/dist/angulartics.min.js", - "public/bower_components/angulartics/dist/angulartics-ga.min.js", - "public/bower_components/spin.js/spin.js", - "public/bower_components/angular-spinner/angular-spinner.min.js", - "public/bower_components/socket.io-client/socket.io.js" + './src/public/bower_components/jquery/dist/jquery.min.js', + './src/public/bower_components/angular/angular.min.js', + './src/public/bower_components/angular-route/angular-route.min.js', + './src/public/bower_components/angular-animate/angular-animate.min.js', + './src/public/bower_components/angulartics/dist/angulartics.min.js', + './src/public/bower_components/angulartics/dist/angulartics-ga.min.js', + './src/public/bower_components/spin.js/spin.js', + './src/public/bower_components/angular-spinner/angular-spinner.min.js', + './src/public/bower_components/socket.io-client/socket.io.js' ]; gulp.src(files) .pipe(concat("libs.js")) .pipe(uglify()) - .pipe(gulp.dest("public")); + .pipe(gulp.dest('./public')); }); gulp.task('styles', function () { @@ -34,7 +34,7 @@ gulp.task('styles', function () { require('cssnano')() ]; - gulp.src('./assets/style/*.scss') + gulp.src('./src/assets/style/*.scss') .pipe(sass()) .pipe(postcss(processors)) .pipe(concat('style.css')) @@ -42,25 +42,25 @@ gulp.task('styles', function () { }); gulp.task("copy", function () { - gulp.src("./assets/fonts/*") + gulp.src('./src/assets/fonts/*') .pipe(gulp.dest("./public/fonts")); - gulp.src("./assets/graphics/*") + gulp.src('./src/assets/graphics/*') .pipe(gulp.dest("./public/graphics")); gulp.src([ - "./3rdparty/*", - "robots.txt" + './src/3rdparty/*', + './robots.txt' ]) .pipe(gulp.dest("./public")); }); gulp.task('compile', function () { gulp.src([ - 'client/app.js', - 'client/document.js', - 'client/data.js', - 'client/instagram.js' + './src/client/app.js', + './src/client/document.js', + './src/client/data.js', + './src/client/instagram.js' ]) .pipe(browserify({ transform: [ @@ -73,7 +73,7 @@ gulp.task('compile', function () { }); gulp.task("imagemin", function () { - gulp.src("./assets/img/**/*") + gulp.src('./src/assets/img/**/*') .pipe(imageMin()) .pipe(gulp.dest("./public/img")); }); diff --git a/package.json b/package.json index b792b77d..b23d19bb 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "private": true, "version": "3.4.1", "description": "", - "main": "bin/www.js", + "main": "src/bin/www.js", "scripts": { "test": "mocha" }, diff --git a/3rdparty/animate.min.css b/src/3rdparty/animate.min.css similarity index 100% rename from 3rdparty/animate.min.css rename to src/3rdparty/animate.min.css diff --git a/assets/fonts/PT Free Font License_eng_1.2.txt b/src/assets/fonts/PT Free Font License_eng_1.2.txt similarity index 100% rename from assets/fonts/PT Free Font License_eng_1.2.txt rename to src/assets/fonts/PT Free Font License_eng_1.2.txt diff --git a/assets/fonts/PT Free Font License_rus_1.2.txt b/src/assets/fonts/PT Free Font License_rus_1.2.txt similarity index 100% rename from assets/fonts/PT Free Font License_rus_1.2.txt rename to src/assets/fonts/PT Free Font License_rus_1.2.txt diff --git a/assets/fonts/PTC55F_W.eot b/src/assets/fonts/PTC55F_W.eot similarity index 100% rename from assets/fonts/PTC55F_W.eot rename to src/assets/fonts/PTC55F_W.eot diff --git a/assets/fonts/PTC55F_W.svg b/src/assets/fonts/PTC55F_W.svg similarity index 100% rename from assets/fonts/PTC55F_W.svg rename to src/assets/fonts/PTC55F_W.svg diff --git a/assets/fonts/PTC55F_W.ttf b/src/assets/fonts/PTC55F_W.ttf similarity index 100% rename from assets/fonts/PTC55F_W.ttf rename to src/assets/fonts/PTC55F_W.ttf diff --git a/assets/fonts/PTC55F_W.woff b/src/assets/fonts/PTC55F_W.woff similarity index 100% rename from assets/fonts/PTC55F_W.woff rename to src/assets/fonts/PTC55F_W.woff diff --git a/assets/fonts/PTC75F_W.eot b/src/assets/fonts/PTC75F_W.eot similarity index 100% rename from assets/fonts/PTC75F_W.eot rename to src/assets/fonts/PTC75F_W.eot diff --git a/assets/fonts/PTC75F_W.svg b/src/assets/fonts/PTC75F_W.svg similarity index 100% rename from assets/fonts/PTC75F_W.svg rename to src/assets/fonts/PTC75F_W.svg diff --git a/assets/fonts/PTC75F_W.ttf b/src/assets/fonts/PTC75F_W.ttf similarity index 100% rename from assets/fonts/PTC75F_W.ttf rename to src/assets/fonts/PTC75F_W.ttf diff --git a/assets/fonts/PTC75F_W.woff b/src/assets/fonts/PTC75F_W.woff similarity index 100% rename from assets/fonts/PTC75F_W.woff rename to src/assets/fonts/PTC75F_W.woff diff --git a/assets/fonts/PTN57F_W.eot b/src/assets/fonts/PTN57F_W.eot similarity index 100% rename from assets/fonts/PTN57F_W.eot rename to src/assets/fonts/PTN57F_W.eot diff --git a/assets/fonts/PTN57F_W.svg b/src/assets/fonts/PTN57F_W.svg similarity index 100% rename from assets/fonts/PTN57F_W.svg rename to src/assets/fonts/PTN57F_W.svg diff --git a/assets/fonts/PTN57F_W.ttf b/src/assets/fonts/PTN57F_W.ttf similarity index 100% rename from assets/fonts/PTN57F_W.ttf rename to src/assets/fonts/PTN57F_W.ttf diff --git a/assets/fonts/PTN57F_W.woff b/src/assets/fonts/PTN57F_W.woff similarity index 100% rename from assets/fonts/PTN57F_W.woff rename to src/assets/fonts/PTN57F_W.woff diff --git a/assets/fonts/PTN77F_W.eot b/src/assets/fonts/PTN77F_W.eot similarity index 100% rename from assets/fonts/PTN77F_W.eot rename to src/assets/fonts/PTN77F_W.eot diff --git a/assets/fonts/PTN77F_W.svg b/src/assets/fonts/PTN77F_W.svg similarity index 100% rename from assets/fonts/PTN77F_W.svg rename to src/assets/fonts/PTN77F_W.svg diff --git a/assets/fonts/PTN77F_W.ttf b/src/assets/fonts/PTN77F_W.ttf similarity index 100% rename from assets/fonts/PTN77F_W.ttf rename to src/assets/fonts/PTN77F_W.ttf diff --git a/assets/fonts/PTN77F_W.woff b/src/assets/fonts/PTN77F_W.woff similarity index 100% rename from assets/fonts/PTN77F_W.woff rename to src/assets/fonts/PTN77F_W.woff diff --git a/assets/fonts/PTS55F_W.eot b/src/assets/fonts/PTS55F_W.eot similarity index 100% rename from assets/fonts/PTS55F_W.eot rename to src/assets/fonts/PTS55F_W.eot diff --git a/assets/fonts/PTS55F_W.svg b/src/assets/fonts/PTS55F_W.svg similarity index 100% rename from assets/fonts/PTS55F_W.svg rename to src/assets/fonts/PTS55F_W.svg diff --git a/assets/fonts/PTS55F_W.ttf b/src/assets/fonts/PTS55F_W.ttf similarity index 100% rename from assets/fonts/PTS55F_W.ttf rename to src/assets/fonts/PTS55F_W.ttf diff --git a/assets/fonts/PTS55F_W.woff b/src/assets/fonts/PTS55F_W.woff similarity index 100% rename from assets/fonts/PTS55F_W.woff rename to src/assets/fonts/PTS55F_W.woff diff --git a/assets/fonts/PTS56F_W.eot b/src/assets/fonts/PTS56F_W.eot similarity index 100% rename from assets/fonts/PTS56F_W.eot rename to src/assets/fonts/PTS56F_W.eot diff --git a/assets/fonts/PTS56F_W.svg b/src/assets/fonts/PTS56F_W.svg similarity index 100% rename from assets/fonts/PTS56F_W.svg rename to src/assets/fonts/PTS56F_W.svg diff --git a/assets/fonts/PTS56F_W.ttf b/src/assets/fonts/PTS56F_W.ttf similarity index 100% rename from assets/fonts/PTS56F_W.ttf rename to src/assets/fonts/PTS56F_W.ttf diff --git a/assets/fonts/PTS56F_W.woff b/src/assets/fonts/PTS56F_W.woff similarity index 100% rename from assets/fonts/PTS56F_W.woff rename to src/assets/fonts/PTS56F_W.woff diff --git a/assets/fonts/PTS75F_W.eot b/src/assets/fonts/PTS75F_W.eot similarity index 100% rename from assets/fonts/PTS75F_W.eot rename to src/assets/fonts/PTS75F_W.eot diff --git a/assets/fonts/PTS75F_W.svg b/src/assets/fonts/PTS75F_W.svg similarity index 100% rename from assets/fonts/PTS75F_W.svg rename to src/assets/fonts/PTS75F_W.svg diff --git a/assets/fonts/PTS75F_W.ttf b/src/assets/fonts/PTS75F_W.ttf similarity index 100% rename from assets/fonts/PTS75F_W.ttf rename to src/assets/fonts/PTS75F_W.ttf diff --git a/assets/fonts/PTS75F_W.woff b/src/assets/fonts/PTS75F_W.woff similarity index 100% rename from assets/fonts/PTS75F_W.woff rename to src/assets/fonts/PTS75F_W.woff diff --git a/assets/fonts/PTS76F_W.eot b/src/assets/fonts/PTS76F_W.eot similarity index 100% rename from assets/fonts/PTS76F_W.eot rename to src/assets/fonts/PTS76F_W.eot diff --git a/assets/fonts/PTS76F_W.svg b/src/assets/fonts/PTS76F_W.svg similarity index 100% rename from assets/fonts/PTS76F_W.svg rename to src/assets/fonts/PTS76F_W.svg diff --git a/assets/fonts/PTS76F_W.ttf b/src/assets/fonts/PTS76F_W.ttf similarity index 100% rename from assets/fonts/PTS76F_W.ttf rename to src/assets/fonts/PTS76F_W.ttf diff --git a/assets/fonts/PTS76F_W.woff b/src/assets/fonts/PTS76F_W.woff similarity index 100% rename from assets/fonts/PTS76F_W.woff rename to src/assets/fonts/PTS76F_W.woff diff --git a/assets/fonts/demo.html b/src/assets/fonts/demo.html similarity index 100% rename from assets/fonts/demo.html rename to src/assets/fonts/demo.html diff --git a/assets/fonts/stylesheet.css b/src/assets/fonts/stylesheet.css similarity index 100% rename from assets/fonts/stylesheet.css rename to src/assets/fonts/stylesheet.css diff --git a/assets/graphics/download.png b/src/assets/graphics/download.png similarity index 100% rename from assets/graphics/download.png rename to src/assets/graphics/download.png diff --git a/assets/graphics/icon.vk.png b/src/assets/graphics/icon.vk.png similarity index 100% rename from assets/graphics/icon.vk.png rename to src/assets/graphics/icon.vk.png diff --git a/assets/graphics/lesson-canceled.svg b/src/assets/graphics/lesson-canceled.svg similarity index 100% rename from assets/graphics/lesson-canceled.svg rename to src/assets/graphics/lesson-canceled.svg diff --git a/assets/graphics/m-tape-bl.png b/src/assets/graphics/m-tape-bl.png similarity index 100% rename from assets/graphics/m-tape-bl.png rename to src/assets/graphics/m-tape-bl.png diff --git a/assets/graphics/m-tape-br.png b/src/assets/graphics/m-tape-br.png similarity index 100% rename from assets/graphics/m-tape-br.png rename to src/assets/graphics/m-tape-br.png diff --git a/assets/graphics/m-tape-tl.png b/src/assets/graphics/m-tape-tl.png similarity index 100% rename from assets/graphics/m-tape-tl.png rename to src/assets/graphics/m-tape-tl.png diff --git a/assets/graphics/m-tape-tr.png b/src/assets/graphics/m-tape-tr.png similarity index 100% rename from assets/graphics/m-tape-tr.png rename to src/assets/graphics/m-tape-tr.png diff --git a/assets/graphics/rawline.png b/src/assets/graphics/rawline.png similarity index 100% rename from assets/graphics/rawline.png rename to src/assets/graphics/rawline.png diff --git a/assets/graphics/tape-lb.png b/src/assets/graphics/tape-lb.png similarity index 100% rename from assets/graphics/tape-lb.png rename to src/assets/graphics/tape-lb.png diff --git a/assets/graphics/tape-rb.png b/src/assets/graphics/tape-rb.png similarity index 100% rename from assets/graphics/tape-rb.png rename to src/assets/graphics/tape-rb.png diff --git a/assets/graphics/tape-tl.png b/src/assets/graphics/tape-tl.png similarity index 100% rename from assets/graphics/tape-tl.png rename to src/assets/graphics/tape-tl.png diff --git a/assets/graphics/tape-tr.png b/src/assets/graphics/tape-tr.png similarity index 100% rename from assets/graphics/tape-tr.png rename to src/assets/graphics/tape-tr.png diff --git a/assets/graphics/timeline-arrow-left.png b/src/assets/graphics/timeline-arrow-left.png similarity index 100% rename from assets/graphics/timeline-arrow-left.png rename to src/assets/graphics/timeline-arrow-left.png diff --git a/assets/graphics/timeline-arrow-right.png b/src/assets/graphics/timeline-arrow-right.png similarity index 100% rename from assets/graphics/timeline-arrow-right.png rename to src/assets/graphics/timeline-arrow-right.png diff --git a/assets/graphics/timeline-line.png b/src/assets/graphics/timeline-line.png similarity index 100% rename from assets/graphics/timeline-line.png rename to src/assets/graphics/timeline-line.png diff --git a/assets/style/background-picture.scss b/src/assets/style/background-picture.scss similarity index 100% rename from assets/style/background-picture.scss rename to src/assets/style/background-picture.scss diff --git a/assets/style/breadcrumbs.scss b/src/assets/style/breadcrumbs.scss similarity index 100% rename from assets/style/breadcrumbs.scss rename to src/assets/style/breadcrumbs.scss diff --git a/assets/style/docs.scss b/src/assets/style/docs.scss similarity index 100% rename from assets/style/docs.scss rename to src/assets/style/docs.scss diff --git a/assets/style/document.scss b/src/assets/style/document.scss similarity index 100% rename from assets/style/document.scss rename to src/assets/style/document.scss diff --git a/assets/style/error-404.scss b/src/assets/style/error-404.scss similarity index 100% rename from assets/style/error-404.scss rename to src/assets/style/error-404.scss diff --git a/assets/style/footer.scss b/src/assets/style/footer.scss similarity index 100% rename from assets/style/footer.scss rename to src/assets/style/footer.scss diff --git a/assets/style/gallery.scss b/src/assets/style/gallery.scss similarity index 100% rename from assets/style/gallery.scss rename to src/assets/style/gallery.scss diff --git a/assets/style/home.scss b/src/assets/style/home.scss similarity index 100% rename from assets/style/home.scss rename to src/assets/style/home.scss diff --git a/assets/style/main.scss b/src/assets/style/main.scss similarity index 100% rename from assets/style/main.scss rename to src/assets/style/main.scss diff --git a/assets/style/menu.scss b/src/assets/style/menu.scss similarity index 100% rename from assets/style/menu.scss rename to src/assets/style/menu.scss diff --git a/assets/style/page.scss b/src/assets/style/page.scss similarity index 100% rename from assets/style/page.scss rename to src/assets/style/page.scss diff --git a/assets/style/pages-animations.scss b/src/assets/style/pages-animations.scss similarity index 100% rename from assets/style/pages-animations.scss rename to src/assets/style/pages-animations.scss diff --git a/assets/style/schedule-mobile.scss b/src/assets/style/schedule-mobile.scss similarity index 100% rename from assets/style/schedule-mobile.scss rename to src/assets/style/schedule-mobile.scss diff --git a/assets/style/schedule-table.scss b/src/assets/style/schedule-table.scss similarity index 100% rename from assets/style/schedule-table.scss rename to src/assets/style/schedule-table.scss diff --git a/assets/style/schedule.scss b/src/assets/style/schedule.scss similarity index 100% rename from assets/style/schedule.scss rename to src/assets/style/schedule.scss diff --git a/assets/style/tape-viewer.scss b/src/assets/style/tape-viewer.scss similarity index 100% rename from assets/style/tape-viewer.scss rename to src/assets/style/tape-viewer.scss diff --git a/assets/style/team.scss b/src/assets/style/team.scss similarity index 100% rename from assets/style/team.scss rename to src/assets/style/team.scss diff --git a/assets/style/timeline-instagram.scss b/src/assets/style/timeline-instagram.scss similarity index 100% rename from assets/style/timeline-instagram.scss rename to src/assets/style/timeline-instagram.scss diff --git a/assets/style/timeline-record.scss b/src/assets/style/timeline-record.scss similarity index 100% rename from assets/style/timeline-record.scss rename to src/assets/style/timeline-record.scss diff --git a/assets/style/timeline.scss b/src/assets/style/timeline.scss similarity index 100% rename from assets/style/timeline.scss rename to src/assets/style/timeline.scss diff --git a/bin/www.js b/src/bin/www.js similarity index 100% rename from bin/www.js rename to src/bin/www.js diff --git a/client/api/api.js b/src/client/api/api.js similarity index 100% rename from client/api/api.js rename to src/client/api/api.js diff --git a/client/api/gallery.js b/src/client/api/gallery.js similarity index 100% rename from client/api/gallery.js rename to src/client/api/gallery.js diff --git a/client/api/news.js b/src/client/api/news.js similarity index 100% rename from client/api/news.js rename to src/client/api/news.js diff --git a/client/app.js b/src/client/app.js similarity index 100% rename from client/app.js rename to src/client/app.js diff --git a/client/controllers/ContactsController.js b/src/client/controllers/ContactsController.js similarity index 100% rename from client/controllers/ContactsController.js rename to src/client/controllers/ContactsController.js diff --git a/client/controllers/CopyrightController.js b/src/client/controllers/CopyrightController.js similarity index 100% rename from client/controllers/CopyrightController.js rename to src/client/controllers/CopyrightController.js diff --git a/client/data.js b/src/client/data.js similarity index 100% rename from client/data.js rename to src/client/data.js diff --git a/client/directives/backgroundPicture.js b/src/client/directives/backgroundPicture.js similarity index 100% rename from client/directives/backgroundPicture.js rename to src/client/directives/backgroundPicture.js diff --git a/client/directives/mainMenu.js b/src/client/directives/mainMenu.js similarity index 100% rename from client/directives/mainMenu.js rename to src/client/directives/mainMenu.js diff --git a/client/directives/teamMemberProfile.js b/src/client/directives/teamMemberProfile.js similarity index 100% rename from client/directives/teamMemberProfile.js rename to src/client/directives/teamMemberProfile.js diff --git a/client/document.js b/src/client/document.js similarity index 100% rename from client/document.js rename to src/client/document.js diff --git a/client/filters/remove-hashtags.js b/src/client/filters/remove-hashtags.js similarity index 100% rename from client/filters/remove-hashtags.js rename to src/client/filters/remove-hashtags.js diff --git a/client/filters/removeNewline.js b/src/client/filters/removeNewline.js similarity index 100% rename from client/filters/removeNewline.js rename to src/client/filters/removeNewline.js diff --git a/client/filters/strip.js b/src/client/filters/strip.js similarity index 100% rename from client/filters/strip.js rename to src/client/filters/strip.js diff --git a/client/filters/uppercase-first.js b/src/client/filters/uppercase-first.js similarity index 100% rename from client/filters/uppercase-first.js rename to src/client/filters/uppercase-first.js diff --git a/client/instagram.js b/src/client/instagram.js similarity index 100% rename from client/instagram.js rename to src/client/instagram.js diff --git a/client/modules/schedule.js b/src/client/modules/schedule.js similarity index 100% rename from client/modules/schedule.js rename to src/client/modules/schedule.js diff --git a/client/pages/docs.js b/src/client/pages/docs.js similarity index 100% rename from client/pages/docs.js rename to src/client/pages/docs.js diff --git a/client/pages/gallery.js b/src/client/pages/gallery.js similarity index 100% rename from client/pages/gallery.js rename to src/client/pages/gallery.js diff --git a/client/pages/home.js b/src/client/pages/home.js similarity index 100% rename from client/pages/home.js rename to src/client/pages/home.js diff --git a/client/pages/schedule.js b/src/client/pages/schedule.js similarity index 100% rename from client/pages/schedule.js rename to src/client/pages/schedule.js diff --git a/client/pages/team.js b/src/client/pages/team.js similarity index 100% rename from client/pages/team.js rename to src/client/pages/team.js diff --git a/client/services/io.js b/src/client/services/io.js similarity index 100% rename from client/services/io.js rename to src/client/services/io.js diff --git a/client/ui/breadcrumbs.js b/src/client/ui/breadcrumbs.js similarity index 100% rename from client/ui/breadcrumbs.js rename to src/client/ui/breadcrumbs.js diff --git a/client/ui/menu.js b/src/client/ui/menu.js similarity index 100% rename from client/ui/menu.js rename to src/client/ui/menu.js diff --git a/client/ui/timeline.js b/src/client/ui/timeline.js similarity index 100% rename from client/ui/timeline.js rename to src/client/ui/timeline.js diff --git a/config.js b/src/config.js similarity index 100% rename from config.js rename to src/config.js diff --git a/core/db.js b/src/core/db.js similarity index 100% rename from core/db.js rename to src/core/db.js diff --git a/instagram/index.js b/src/instagram/index.js similarity index 100% rename from instagram/index.js rename to src/instagram/index.js diff --git a/instagram/instagram.js b/src/instagram/instagram.js similarity index 100% rename from instagram/instagram.js rename to src/instagram/instagram.js diff --git a/instagram/io.js b/src/instagram/io.js similarity index 100% rename from instagram/io.js rename to src/instagram/io.js diff --git a/instagram/publish.js b/src/instagram/publish.js similarity index 100% rename from instagram/publish.js rename to src/instagram/publish.js diff --git a/instagram/router.js b/src/instagram/router.js similarity index 100% rename from instagram/router.js rename to src/instagram/router.js diff --git a/models/course.js b/src/models/course.js similarity index 100% rename from models/course.js rename to src/models/course.js diff --git a/models/courses.json b/src/models/courses.json similarity index 100% rename from models/courses.json rename to src/models/courses.json diff --git a/models/document.js b/src/models/document.js similarity index 100% rename from models/document.js rename to src/models/document.js diff --git a/models/documents.json b/src/models/documents.json similarity index 100% rename from models/documents.json rename to src/models/documents.json diff --git a/models/menu.json b/src/models/menu.json similarity index 100% rename from models/menu.json rename to src/models/menu.json diff --git a/models/schedule.js b/src/models/schedule.js similarity index 100% rename from models/schedule.js rename to src/models/schedule.js diff --git a/models/team.js b/src/models/team.js similarity index 100% rename from models/team.js rename to src/models/team.js diff --git a/models/team.json b/src/models/team.json similarity index 100% rename from models/team.json rename to src/models/team.json diff --git a/routes/404.js b/src/routes/404.js similarity index 100% rename from routes/404.js rename to src/routes/404.js diff --git a/routes/gallery.js b/src/routes/gallery.js similarity index 100% rename from routes/gallery.js rename to src/routes/gallery.js diff --git a/routes/index.js b/src/routes/index.js similarity index 100% rename from routes/index.js rename to src/routes/index.js diff --git a/routes/news.js b/src/routes/news.js similarity index 100% rename from routes/news.js rename to src/routes/news.js diff --git a/routes/schedule.js b/src/routes/schedule.js similarity index 100% rename from routes/schedule.js rename to src/routes/schedule.js diff --git a/routes/sitemap.js b/src/routes/sitemap.js similarity index 100% rename from routes/sitemap.js rename to src/routes/sitemap.js diff --git a/server.js b/src/server.js similarity index 97% rename from server.js rename to src/server.js index acb651a7..a4cbeb27 100644 --- a/server.js +++ b/src/server.js @@ -31,7 +31,7 @@ app.use(function *(next) { }); app.use(prerender(config.prerender)); -app.use(serve(path.join(__dirname, "public"))); +app.use(serve(path.join(__dirname, '../public'))); app.use(serve(path.join(__dirname, "templates"))); app.use(helmet()); diff --git a/templates/404.html b/src/templates/404.html similarity index 100% rename from templates/404.html rename to src/templates/404.html diff --git a/templates/document.html b/src/templates/document.html similarity index 100% rename from templates/document.html rename to src/templates/document.html diff --git a/templates/instagram.html b/src/templates/instagram.html similarity index 100% rename from templates/instagram.html rename to src/templates/instagram.html diff --git a/templates/main.html b/src/templates/main.html similarity index 100% rename from templates/main.html rename to src/templates/main.html diff --git a/templates/views/breadcrumbs.html b/src/templates/views/breadcrumbs.html similarity index 100% rename from templates/views/breadcrumbs.html rename to src/templates/views/breadcrumbs.html diff --git a/templates/views/docs.html b/src/templates/views/docs.html similarity index 100% rename from templates/views/docs.html rename to src/templates/views/docs.html diff --git a/templates/views/gallery-album.html b/src/templates/views/gallery-album.html similarity index 100% rename from templates/views/gallery-album.html rename to src/templates/views/gallery-album.html diff --git a/templates/views/gallery.html b/src/templates/views/gallery.html similarity index 100% rename from templates/views/gallery.html rename to src/templates/views/gallery.html diff --git a/templates/views/home.html b/src/templates/views/home.html similarity index 100% rename from templates/views/home.html rename to src/templates/views/home.html diff --git a/templates/views/menu.html b/src/templates/views/menu.html similarity index 100% rename from templates/views/menu.html rename to src/templates/views/menu.html diff --git a/templates/views/schedule.html b/src/templates/views/schedule.html similarity index 100% rename from templates/views/schedule.html rename to src/templates/views/schedule.html diff --git a/templates/views/schedule/record.html b/src/templates/views/schedule/record.html similarity index 100% rename from templates/views/schedule/record.html rename to src/templates/views/schedule/record.html diff --git a/templates/views/schedule/slide.html b/src/templates/views/schedule/slide.html similarity index 100% rename from templates/views/schedule/slide.html rename to src/templates/views/schedule/slide.html diff --git a/templates/views/schedule/table.html b/src/templates/views/schedule/table.html similarity index 100% rename from templates/views/schedule/table.html rename to src/templates/views/schedule/table.html diff --git a/templates/views/team.html b/src/templates/views/team.html similarity index 100% rename from templates/views/team.html rename to src/templates/views/team.html diff --git a/templates/views/team/profile.html b/src/templates/views/team/profile.html similarity index 100% rename from templates/views/team/profile.html rename to src/templates/views/team/profile.html diff --git a/templates/views/timeline-gram.html b/src/templates/views/timeline-gram.html similarity index 100% rename from templates/views/timeline-gram.html rename to src/templates/views/timeline-gram.html diff --git a/templates/views/timeline-post.html b/src/templates/views/timeline-post.html similarity index 100% rename from templates/views/timeline-post.html rename to src/templates/views/timeline-post.html diff --git a/templates/views/timeline.html b/src/templates/views/timeline.html similarity index 100% rename from templates/views/timeline.html rename to src/templates/views/timeline.html diff --git a/utils/common.js b/src/utils/common.js similarity index 100% rename from utils/common.js rename to src/utils/common.js diff --git a/utils/date.js b/src/utils/date.js similarity index 100% rename from utils/date.js rename to src/utils/date.js diff --git a/utils/net.js b/src/utils/net.js similarity index 100% rename from utils/net.js rename to src/utils/net.js diff --git a/utils/populate.js b/src/utils/populate.js similarity index 100% rename from utils/populate.js rename to src/utils/populate.js diff --git a/utils/Sync/Album.py b/utils/Sync/Album.py new file mode 100644 index 00000000..59cec1f2 --- /dev/null +++ b/utils/Sync/Album.py @@ -0,0 +1,22 @@ +__author__ = 'Roman Timashev' + + +class Album: + def __init__(self, type, title, uri, course, course_uri, date, teacher, comment): + super().__init__() + self.products = [] + self.type = type + self.title = title + self.uri = uri + self.course = course + self.course_uri = course_uri + self.date = date + self.teacher = teacher + self.comment = comment + + def add_product(self, product): + self.products.append(product) + + def __repr__(self, *args, **kwargs): + return '[%s by %s (%d items)]' % (self.title, self.teacher, len(self.products)) + diff --git a/utils/Sync/db-test.py b/utils/Sync/db-test.py new file mode 100644 index 00000000..2c8a1a95 --- /dev/null +++ b/utils/Sync/db-test.py @@ -0,0 +1,13 @@ +from pymongo import MongoClient +import settings + +__author__ = 'Roman Timashev' + + +client = MongoClient(settings.database_uri) +p = client.hudozka.posts + +print(list(p.find())) + +# print(dir(p)) +# print(p.insert({'a': 1})) \ No newline at end of file diff --git a/utils/Sync/img.py b/utils/Sync/img.py new file mode 100644 index 00000000..e4a1fb9d --- /dev/null +++ b/utils/Sync/img.py @@ -0,0 +1,25 @@ +import os + +__author__ = 'Roman Timashev' + +from PIL import Image + + +def read_image(src): + return Image.open(src) + + +def minify(image, dest, size, ext=None): + image.thumbnail(size) + image.save(override_extension(dest, ext)) + + +def optimize(image, dest, quality=85, ext=None): + image.save(override_extension(dest, ext), quality=quality) + + +def override_extension(dest, ext=None): + if ext is not None: + dest = os.path.splitext(dest)[0] + ext + + return dest \ No newline at end of file diff --git a/utils/Sync/lxml_utils.py b/utils/Sync/lxml_utils.py new file mode 100644 index 00000000..4972ced0 --- /dev/null +++ b/utils/Sync/lxml_utils.py @@ -0,0 +1,29 @@ +import re + + +def get_following_tags(element, stop_tag_pattr): + stop_exp = re.compile(stop_tag_pattr) + following = element.xpath('./following-sibling::*') + tags = [] + i = 0 + while True: + try: + tag = following[i] + if stop_exp.match(tag.tag): + break + tags.append(tag) + except IndexError as tag: + break + i += 1 + return tags + + +def get_text_following_by_tag(element, tag, contains, strip=True): + e = element.xpath('.//%s[contains(text(), "%s")]/following-sibling::text()' % (tag, contains)) + if len(e) > 0: + if strip: + return e[0].strip() + else: + return e[0] + else: + return None \ No newline at end of file diff --git a/utils/Sync/read_gallery_1.py b/utils/Sync/read_gallery_1.py new file mode 100644 index 00000000..a010c4f1 --- /dev/null +++ b/utils/Sync/read_gallery_1.py @@ -0,0 +1,112 @@ +from datetime import datetime +import re +import lxml.html +from markdown import markdown +import time +from Album import Album +import lxml_utils +import settings + +__author__ = 'Roman Timashev' + +artist_name_exp = re.compile('([ %s]+)(\s\(\d+ лет\))?$' % (settings.CYR_LOWER+settings.CYR_UPPER)) +# artist_name_exp = re.compile('(.+)(\s\(\d+ лет\))?$') +artist_age_exp = re.compile('.+\((\d+) лет\)$') + +class GalleryReader: + def __init__(self, path): + super().__init__() + self.html = None + self.description_path = path + + def read(self): + with open(self.description_path, 'r', encoding='utf-8') as dfile: + data = dfile.read() + md = markdown(data) + self.html = lxml.html.fromstring(md) + + # ALBUM + try: + album_title = self.html.xpath('.//h1/a/text()')[0] + album_uri = self.html.xpath('.//h1/a/@href')[0] + except: + raise Exception('Cannot read album title/uri') + + # COURSE + try: + course_title = self.html.xpath('.//p/a/text()')[0] + course_uri = self.html.xpath('.//p/a/@href')[0] + except: + raise Exception('Cannot read course title/uri') + + # TEACHER + teacher = lxml_utils.get_text_following_by_tag(self.html, 'em', "Преподаватель") + teacher = re.sub(r'\s', '', teacher) + if teacher not in settings.teachers_names: + raise Exception('Teacher %s is not found' % teacher) + teacher_name = settings.teachers_names[teacher] + + # DATE + date = self.get_date() + if date is None: + raise Exception('Date field is empty') + + # PRODUCT + content = self.get_drawings() + + a = Album(type='1', title=album_title, uri=album_uri, course=course_title, course_uri=course_uri, date=date, teacher=teacher_name, comment=None) + for p in content: + a.add_product(p) + return a + + def get_drawings(self): + drawings = [] + h3_list = self.html.xpath('.//h3') + for h3 in h3_list: + artist_name_age = h3.xpath('./a') + if len(artist_name_age) == 0: + raise Exception('Artist name should be a link') + artist_name_age = artist_name_age[0].text + + # ARTIST NAME [required] + if artist_name_age is None: + raise Exception('Artist name section is empty') + + exp = artist_name_exp.search(artist_name_age) + if exp is None: + raise Exception('Artist name is not specified') + artist_name = exp.group(1).strip() + + # ARTIST AGE [optional] + exp = artist_age_exp.search(artist_name_age) + if exp is not None and len(exp.groups()) > 0: + artist_age = int(exp.group(1)) + else: + artist_age = None + + image_filename = h3.xpath('./a/@href')[0] + + # PRODUCT TITLE [optional] + drawing_data = lxml_utils.get_following_tags(h3, 'h3') + if len(drawing_data) == 0: + product_title = None + # raise Exception('Product title not specified') + else: + product_title = drawing_data[0].text[1:-1] + + drawings.append((artist_name, artist_age, image_filename, product_title)) + + return drawings + + def get_date(self): + string = lxml_utils.get_text_following_by_tag(self.html, 'em', "Дата") + if string is None: + return None + + for f in settings.date_formats: + try: + date = time.strptime(string, f) + return datetime.fromtimestamp(time.mktime(date)) + except ValueError: + continue + return None diff --git a/utils/Sync/settings.py b/utils/Sync/settings.py new file mode 100644 index 00000000..f95b4f98 --- /dev/null +++ b/utils/Sync/settings.py @@ -0,0 +1,53 @@ +__author__ = 'Roman Timashev' + +root_dir_gallery = './Gallery' +root_dir_schedule = './Schedules' + +default_description_version = 1 + +database_uri = 'mongodb://localhost/hudozka' + +CYR_LOWER = 'йцукенгшщзхъфывапролджэячсмитьбю' +CYR_UPPER = 'ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ' +EN_LOWER = 'qwertyuiopasdfghjklzxcvbnm' +EN_UPPER = 'QWERTYUIOPASDFGHJKLZXCVBNM' +DIGITS = '0123456789' +description_available_chars = CYR_LOWER + CYR_UPPER + EN_LOWER + EN_UPPER + DIGITS + ' _-' + +translit_table = ( + 'абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ', + 'abvgdeejzijklmnoprstufhzcss_y_euaABVGDEEJZIJKLMNOPRSTUFHZCSS_Y_EUA' +) + +teachers_names = { + 'Н.В.Андреева': 'nv-andreeva', + 'И.Н.Втюрина': 'in-vturina', + 'О.Д.Гоголева': 'od-gogoleva', + 'В.А.Саржин': 'va-sarzhin', + 'Р.К.Тимашев': 'rk-timashev', + 'А.С.Тимашева': 'as-timasheva', + # '': '', +} + +image_processing = True + +image_save_dir = './static_images' + +image_base_url = 'https://static.shburg.org/art/image/' +image_ext = '.jpg' +image_sizes = [ + ('original', None, None), + ('big', 1500, 667), + ('medium', 400, 300), + ('small', 250, 175), + ('little', 100, 100), + ('preview', 50, 50), +] + +date_formats = [ + '%Y', + '%m.%Y', + '%d.%m.%Y', + '%d.%m.%Y %H:%M', + '%d.%m.%Y %H:%M:%S' +] diff --git a/utils/Sync/sync.py b/utils/Sync/sync.py new file mode 100644 index 00000000..7cecd4cf --- /dev/null +++ b/utils/Sync/sync.py @@ -0,0 +1,223 @@ +from glob import glob +import os +import markdown as md +import lxml.html as html +from lxml.etree import tostring +import re +import pymongo +import requests +import img +import lxml_utils + +__author__ = 'tmshv' + +# db = pymongo.MongoClient('mongodb://localhost:27017')['stickers'] + +# images_dir = os.path.expanduser('~/Dropbox/Dev/Hud school/Static/images') +catalog_dir = os.path.expanduser('~/Dropbox/Dev/Hud school/Hudozka/Gallery') +catalog_files = os.listdir(catalog_dir) + + +def lesson_info(page): + lesson = list(filter(lambda h2: not h2.xpath('./a'), page.xpath('//h2')))[0] + content = lxml_utils.get_following_tags(lesson, 'h2') + for p in lxml_utils.get_following_tags(lesson, 'h2'): + print(p, tostring(p, encoding='utf-8').decode()) + + # print(content[0].xpath('./em/text()')[0].strip()) + # print(content[0].xpath('./text()')[0].strip()) + + # print(content[1].xpath('./text()')) + # return content + + date_str = '12.10.2013' + + #todo: make as `date` + date = date_str + + return { + 'name': 'Collage', + 'course': 'painting', + 'technology': ['pastel', 'huel', 'glue'], + 'date': date, + } + + +def drawings_info(page): + out = [] + pics = list(filter(lambda h2: h2.xpath('./a'), page.xpath('//h2'))) + for p in pics: + content = lxml_utils.get_following_tags(p, 'h2')[0] + author_info = content.xpath('./text()')[0].split('\n') + out.append({ + 'name': p.xpath('./a/text()')[0], + 'image': p.xpath('./a/@href')[0], + 'author': author_info[0], + 'author_age': int(author_info[1].split(' ')[0]) + }) + return out + + +def generate_image_filename(src, course, year, theme, author, size, i,ext): + if ext is None: + ext = os.path.splitext(src)[1] + + if i == 0: + filename = '{course}-{year}-{theme}-{author}-{size}.{ext}' + else: + filename = '{course}-{year}-{theme}-{author}-{index}-{size}.{ext}'\ + + filename = filename.format( + course=course, + year=year, + theme=theme, + author=author, + size=size, + index=i, + ext=ext + ) + return filename + + +for cf in catalog_files: + os.chdir(catalog_dir) + if os.path.isdir(cf): + print('======================================================================================') + print(cf) + + product_dir = os.path.join(catalog_dir, cf) + os.chdir(product_dir) + + def matching_files(param): + if isinstance(param, list): + return list(map(matching_files, param)) + else: + return glob(param) + + + product_file = matching_files('*.md')[0] + + def from_file(path): + f = open(path, 'r') + data = f.read() + f.close() + return data + + markdown_text = from_file(product_file) + html_text = md.markdown(markdown_text) + page = html.fromstring(html_text) + print(html_text) + + # name + name = page.xpath('//h1/text()')[0] + + # lesson + # filtering paragraph with no link in h2 title + lesson = lesson_info(page) + print(lesson) + + drawings = drawings_info(page) + for d in drawings: + print(d) + + products = list(map( + lambda drawing: { + 'image': drawing['image'], + 'name': drawing['name'], + 'author': drawing['author'], + 'authorAge': drawing['author_age'], + 'course': lesson['course'], + 'theme': lesson['name'], + 'rating': 10, + 'date': lesson['date'] + }, + drawings + )) + + for p in products: + print(p) + + # # price + # def str_price_to_int(text): + # items = text.split('\n') + # out = list(map(lambda p: int(re.sub('[^\d]+', '', p)), items)) + # return out + # + # + # price_text = page.xpath('//h2[contains(text(), "Цена")]/following-sibling::p/text()')[0] + # product_price = str_price_to_int(price_text) + # + # # colors + # def str_colors_to_code_list(text): + # cl = re.split('\s+', text) + # return ttcolor.color_by_code(cl) + # + # color_text = page.xpath('//h2[contains(text(), "Цвета")]/following-sibling::p/text()')[0] + # product_colors = str_colors_to_code_list(color_text) + # + # # text + # def format_text(text): + # try: + # res = requests.post("http://mdash.ru/api.v1.php", { + # 'text': text + # }) + # return res.json()['result'] + # + # except Exception as e: + # + # return text + # + # product_text = page.xpath('//h2[contains(text(), "Текст")]/following-sibling::p/text()')[0] + # # product_text = format_text(product_text) + # + # + # # qualities + # def get_quality(li): + # q = { + # 'image': li.xpath('./img/@src')[0], + # 'text': li.xpath('text()')[0].strip() + # } + # return q + # + # + # def qualities_list(elements): + # return list(map(get_quality, elements)) + # + # + # qualities_elements = page.xpath('//h2[contains(text(), "Свойства")]/following-sibling::ul/li') + # qualities = qualities_list(qualities_elements) + # + # + + product_images = [p['image']] + + image_sizes = [ + (50, 50, 'small'), + (300, 300, 'preview'), + (800, 800, 'medium'), + (2000, 2000, 'big'), + (0, 0, 'original') + ] + + images = [] + i = 0 + for image in product_images: + pi = {'source': image} + + for size in image_sizes: + size_name = size[2] + image_filename = generate_image_filename(image, size_name, product_sku, i, 'png') + d = os.path.join(images_dir, image_filename) + pi[size_name] = 'http://static.touchtwin.ru/images/{img}'.format(img=image_filename) + if size_name == 'original': + img.optimize(image, d, quality=90) + else: + img.minify(image, d, size[:2]) + + images.append(pi) + i += 1 + + p['images'] = images + del p['image'] + + # db['products'].update({'uri': product_uri}, p, upsert=True) \ No newline at end of file diff --git a/utils/Sync/sync_gallery.py b/utils/Sync/sync_gallery.py new file mode 100644 index 00000000..35b944a6 --- /dev/null +++ b/utils/Sync/sync_gallery.py @@ -0,0 +1,210 @@ +from glob import glob +import os +import re +from pymongo import MongoClient +import img +from read_gallery_1 import GalleryReader + +import settings +import validation + +__author__ = 'Roman Timashev' + +description_version_exp = re.compile('\[(\d+)\]\.md$') + +dir_gallery = settings.root_dir_gallery +catalog_dir = os.path.expanduser(dir_gallery) +catalog_files = os.listdir(catalog_dir) +os.makedirs(settings.image_save_dir, exist_ok=True) + + +def get_description_version(filename): + v = description_version_exp.search(filename) + return v.group(1) + + +def get_description_reader(version): + if version == '1': + return GalleryReader + + return None + + +def process_image(name, filename, sizes): + ext = settings.image_ext + + thumbs = {} + + for size, width, height in sizes: + source_image = img.read_image(filename) + sw, sh = source_image.size + if sw < sh: + width, height = height, width + + out_image_filename = '{name}-{size}{ext}'.format(name=name, size=size, ext=ext) + out_image_local_path = os.path.join(settings.image_save_dir, out_image_filename) + out_image_url = os.path.join(settings.image_base_url, out_image_filename) + + if width and height: + tw = width + th = height + else: + tw = sw + th = sh + + thumbs[size] = { + 'url': out_image_url, + 'size': size, + 'width': sw, + 'height': sh + } + + # print('generate %s for %s' % (size, filename), out_image_url) + + if settings.image_processing: + if width and height: + img.minify(source_image, out_image_local_path, (width, height)) + else: + img.optimize(source_image, out_image_local_path) + + return thumbs + + +def process_product(album, product): + tr = {ord(a):ord(b) for a, b in zip(*settings.translit_table)} + + author_name, author_age, filename, product_title = product + author_name_encoded = re.sub(r'[\s()]', '', author_name).lower().translate(tr) + image_id = '%s-%s-%s-%s' % ( + album.date.year, + re.sub(r'[/]', '', album.uri), + author_name_encoded, + os.path.splitext(filename)[0] + ) + + image = process_image(image_id, filename, settings.image_sizes) + return (author_name, author_age, image, product_title) + + +def get_db(): + client = MongoClient(settings.database_uri) + return client.hudozka + + +def clear_db(): + db = get_db() + db.products.drop() + db.albums.drop() + + +def sync_product(product, type): + db = get_db() + author_name, author_age, image, product_title = product + + product_record = db['products'].insert({ + 'author': author_name, + 'authorAge': author_age, + 'title': product_title, + 'type': type, + 'content': image + }) + + print('inserted', product_record) + + return product_record + +def sync_album(album): + print('syncing %s' % album.title) + db = get_db() + + product_ids = list(map( + lambda product: sync_product(product, album.type), + album.products + )) + + album_title = album.title + album_uri = album.uri + album_teacher = album.teacher + album_date = album.date + album_comment = album.comment + album_course = album.course + album_course_uri = album.course_uri + + db['albums'].insert({ + 'title': album_title, + 'uri': album_uri, + 'date': album_date, + 'description': album_comment, + 'course': album_course, + 'course_uri': album_course_uri, + 'teacher': album_teacher, + 'content': product_ids + }) + + +def read_gallery_item(dir_name, sync=True): + """ + Read directory with .md and images and return an instance of Album. + None if reads fails. + + :param dir_name: + :param sync: + :return: + """ + + set_path = os.path.join(dir_gallery, i) + os.chdir(set_path) + + md = glob('*.md') + if len(md) > 0: + description_filename = md[0] + description_path = os.path.join(set_path, description_filename) + + #if validation.check_description_filename(description_filename): + if True: + #v = get_description_version(description_filename) + v = '1' + DescriptionReader = get_description_reader(v) + if DescriptionReader is not None: + r = DescriptionReader(description_path) + album = None + try: + album = r.read() + + except Exception as e: + print('Error with reading description file %s' % (description_path)) + print(e) + return + + try: + album.products = list(map( + lambda p : process_product(album, p), + album.products + )) + except Exception as e: + print('Error with image processing %s' % (description_path)) + print(e) + + if sync: + try: + sync_album(album) + except Exception as e: + print('Cannot sync %s' % (description_path)) + print(e) + + else: + print('No reader for description file %s' % (description_path)) + + else: + new_name = validation.suggest_description_filename(description_filename) + os.rename(description_filename, new_name) + read_gallery_item(dir_name) + + +if __name__ == '__main__': + # clear_db() + for i in catalog_files: + read_gallery_item(i, sync=False) + print() + + exit() diff --git a/utils/Sync/sync_schedules.py b/utils/Sync/sync_schedules.py new file mode 100644 index 00000000..fc7125c6 --- /dev/null +++ b/utils/Sync/sync_schedules.py @@ -0,0 +1,31 @@ +from glob import glob +import json +import os +import re +from pymongo import MongoClient +import settings + +__author__ = 'tmshv' + + +db = MongoClient(settings.database_uri).hudozka +db.schedules.drop() + + +for schedule_path in glob(settings.root_dir_schedule + '/*.json'): + with open(schedule_path, 'r') as schedule_file: + name = os.path.basename(schedule_path) + + period = re.search('(\d{4}-\d{4})', name).group(1) + semester = re.search('([a-zA-Z]+)\.json$', name).group(1) + + schedule = json.loads(schedule_file.read()) + # print(name, period, semester, schedule) + + db.schedules.insert({ + 'period': period, + 'semester': semester, + 'schedule': schedule + }) + +print('schedule sync complete') \ No newline at end of file diff --git a/utils/Sync/validation.py b/utils/Sync/validation.py new file mode 100644 index 00000000..ac1d1889 --- /dev/null +++ b/utils/Sync/validation.py @@ -0,0 +1,18 @@ +import os +import re +import settings + +__author__ = 'Roman Timashev' + +__check_description_filename_exp = re.compile('^[%s]+(\[\d+\])\.md$' % settings.description_available_chars) + + +def check_description_filename(filename): + return __check_description_filename_exp.match(filename) + + +def suggest_description_filename(filename): + bn = os.path.basename(filename) + bn = os.path.splitext(bn)[0] + v = settings.default_description_version + return '%s [%s].md' % (bn, v)