From 2a8e57bedd6471b1dad574c179dc2ad39aa9651a Mon Sep 17 00:00:00 2001 From: Angelo Dini Date: Mon, 18 Jan 2016 15:45:01 +0100 Subject: [PATCH] update boilerplate --- .gitignore | 1 + README.rst | 2 +- gulpfile.js | 143 ++-- package.json | 56 +- tools/server/Makefile | 18 + tools/server/db.sqlite3 | Bin 0 -> 129024 bytes tools/server/manage.py | 10 + tools/server/requirements.txt | 3 + tools/server/src/__init__.py | 0 tools/server/src/settings.py | 190 +++++ tools/server/src/urls.py | 12 + tools/server/src/wsgi.py | 14 + tools/server/templates/bootstrap.html | 999 ++++++++++++++++++++++++++ tools/tasks/bower.js | 11 + tools/tasks/browser.js | 24 + tools/tasks/docs.js | 11 + tools/tasks/icons.js | 27 + tools/tasks/images.js | 21 + tools/tasks/lint/javascript.js | 23 + tools/tasks/sass.js | 39 + tools/tasks/tests/integration.js | 19 + tools/tasks/tests/unit.js | 12 + tools/tasks/tests/watch.js | 11 + 23 files changed, 1552 insertions(+), 94 deletions(-) mode change 100755 => 100644 gulpfile.js create mode 100644 tools/server/Makefile create mode 100644 tools/server/db.sqlite3 create mode 100755 tools/server/manage.py create mode 100644 tools/server/requirements.txt create mode 100644 tools/server/src/__init__.py create mode 100644 tools/server/src/settings.py create mode 100644 tools/server/src/urls.py create mode 100644 tools/server/src/wsgi.py create mode 100644 tools/server/templates/bootstrap.html create mode 100644 tools/tasks/bower.js create mode 100644 tools/tasks/browser.js create mode 100644 tools/tasks/docs.js create mode 100644 tools/tasks/icons.js create mode 100644 tools/tasks/images.js create mode 100644 tools/tasks/lint/javascript.js create mode 100644 tools/tasks/sass.js create mode 100644 tools/tasks/tests/integration.js create mode 100644 tools/tasks/tests/unit.js create mode 100644 tools/tasks/tests/watch.js diff --git a/.gitignore b/.gitignore index cbdf863..4e97998 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ data/ env/ node_modules/ tests/coverage/ +tools/server/env/ \ No newline at end of file diff --git a/README.rst b/README.rst index 6c3c5b2..bc3dcb6 100644 --- a/README.rst +++ b/README.rst @@ -42,7 +42,7 @@ Manual #. Choose a starting installation from above. #. Once you have created a project, copy all ``static/`` files from inside the django-cms-explorer project into your projects ``mysite/static/`` folder. -#. Next do the same with ``private/`` and ``templates/``. All pre-existing +#. Next do the same with ``private/``, ``tools/`` and ``templates/``. All pre-existing files can be removed and replaced. More about the file structure is documented in our `boilerplate guidelines `_. #. Restart your server and open your site using ``http://localhost:8000/en/``. diff --git a/gulpfile.js b/gulpfile.js old mode 100755 new mode 100644 index 9d7b292..ef073ae --- a/gulpfile.js +++ b/gulpfile.js @@ -1,96 +1,97 @@ -/*! - * @author: Divio AG - * @copyright: http://www.divio.ch +/* + * Copyright (c) 2013, Divio AG + * Licensed under BSD + * http://github.com/aldryn/aldryn-boilerplate-bootstrap3 */ 'use strict'; // ############################################################################# -// #IMPORTS# -var autoprefixer = require('gulp-autoprefixer'); +// IMPORTS +var argv = require('minimist')(process.argv.slice(2)); var gulp = require('gulp'); -var gutil = require('gulp-util'); -var karma = require('karma').server; -var sass = require('gulp-sass'); -var sourcemaps = require('gulp-sourcemaps'); -var minifyCss = require('gulp-minify-css'); -var protractor = require('gulp-protractor').protractor; -var webdriverUpdate = require('gulp-protractor').webdriver_update; // ############################################################################# -// #SETTINGS# +// SETTINGS var PROJECT_ROOT = __dirname; var PROJECT_PATH = { - 'sass': PROJECT_ROOT + '/private/sass', - 'css': PROJECT_ROOT + '/static/css', - 'tests': PROJECT_ROOT + '/tests' + bower: PROJECT_ROOT + '/static/vendor', + css: PROJECT_ROOT + '/static/css', + docs: PROJECT_ROOT + '/static/docs', + fonts: PROJECT_ROOT + '/static/fonts', + html: PROJECT_ROOT + '/templates', + images: PROJECT_ROOT + '/static/img', + icons: PROJECT_ROOT + '/private/icons', + js: PROJECT_ROOT + '/static/js', + sass: PROJECT_ROOT + '/private/sass', + tests: PROJECT_ROOT + '/tests' }; var PROJECT_PATTERNS = { - 'sass': [ + images: [ + PROJECT_PATH.images + '/**/*', + // exclude from preprocessing + '!' + PROJECT_PATH.images + '/dummy/*/**' + ], + js: [ + 'gulpfile.js', + PROJECT_PATH.js + '/**/*.js', + PROJECT_PATH.tests + '/**/*.js', + // exclude from linting + '!' + PROJECT_PATH.js + '/*.min.js', + '!' + PROJECT_PATH.js + '/**/*.min.js', + '!' + PROJECT_PATH.tests + '/coverage/**/*' + ], + sass: [ PROJECT_PATH.sass + '/**/*.{scss,sass}' ] }; -// ############################################################################# -// #TASKS# -gulp.task('sass', function () { - gulp.src(PROJECT_PATTERNS.sass) - .pipe(sourcemaps.init()) - .pipe(sass()) - .on('error', function (error) { - gutil.log(gutil.colors.red( - 'Error (' + error.plugin + '): ' + error.messageFormatted) - ); - }) - .pipe(autoprefixer({ - // browsers are coming from browserslist file - cascade: false - })) - .pipe(minifyCss({ - // fixes font imports from google fonts - rebase: false - })) - .pipe(sourcemaps.write()) - .pipe(gulp.dest(PROJECT_PATH.css)); -}); +var PORT = parseInt(process.env.PORT, 10) || 8000; +var DEBUG = argv.debug; -// ####################################### -// #TESTS# -gulp.task('tests', ['tests:unit', 'tests:integration']); -gulp.task('tests:unit', function (done) { - // run javascript tests - karma.start({ - configFile: PROJECT_PATH.tests + '/karma.conf.js', - singleRun: true - }, done); -}); +function task(id) { + return require('./tools/tasks/' + id)(gulp, { + PROJECT_ROOT: PROJECT_ROOT, + PROJECT_PATH: PROJECT_PATH, + PROJECT_PATTERNS: PROJECT_PATTERNS, + DEBUG: DEBUG, + PORT: PORT + }); +} -gulp.task('tests:webdriver', webdriverUpdate); -gulp.task('tests:integration', ['tests:webdriver'], function () { - return gulp.src([PROJECT_PATH.tests + '/integration/specs/*.js']) - .pipe(protractor({ - configFile: PROJECT_PATH.tests + '/protractor.conf.js', - args: [] - })) - .on('error', function (error) { - gutil.log(gutil.colors.red( - 'Error (' + error.plugin + '): ' + error.message) - ); - }); -}); +gulp.task('bower', task('bower')); +gulp.task('lint:javascript', task('lint/javascript')); +gulp.task('lint', ['lint:javascript']); +gulp.task('sass', task('sass')); +gulp.task('build', ['sass']); -gulp.task('tests:watch', function () { - // run javascript tests - karma.start({ - configFile: PROJECT_PATH.tests + '/karma.conf.js' - }); -}); +/** + * GULP_MODE === 'production' means we have a limited + * subset of tasks, namely sass, bower and lint to + * speed up the deployment / installation process. + */ +if (process.env.GULP_MODE !== 'production') { + gulp.task('images', task('images')); + gulp.task('docs', task('docs')); + gulp.task('preprocess', ['sass', 'images', 'docs']); + gulp.task('icons', task('icons')); + + gulp.task('browser', task('browser')); + + gulp.task('tests:lint', ['lint:javascript']); + gulp.task('tests:unit', task('tests/unit')); + gulp.task('tests:watch', ['tests:lint'], task('tests/watch')); + gulp.task('tests', ['tests:unit', 'tests:integration', 'tests:lint']); + + var webdriverUpdate = require('gulp-protractor').webdriver_update; + gulp.task('tests:webdriver', webdriverUpdate); + gulp.task('tests:integration', ['tests:webdriver'], task('tests/integration')); +} -// ############################################################################# -// #COMMANDS# gulp.task('watch', function () { gulp.watch(PROJECT_PATTERNS.sass, ['sass']); + gulp.watch(PROJECT_PATTERNS.js, ['lint']); }); -gulp.task('default', ['sass', 'watch']); +gulp.task('default', ['bower', 'sass', 'lint', 'watch']); diff --git a/package.json b/package.json index 5b2dee3..65adb0e 100644 --- a/package.json +++ b/package.json @@ -1,29 +1,41 @@ { "name": "package", "private": true, - "engines": { - "node": "0.9.0" + "dependencies": { + "gulp": "^3.9.0", + "gulp-autoprefixer": "^3.0.1", + "gulp-bower": "^0.0.10", + "gulp-if": "^1.2.5", + "gulp-util": "^3.0.6", + "gulp-minify-css": "^1.2.0", + "gulp-sass": "^2.0.4", + "gulp-jscs": "^2.0.0", + "gulp-jshint": "^1.11.2", + "jshint-stylish": "^2.0.1", + "gulp-sourcemaps": "^1.5.2", + "minimist": "^1.1.3" }, "devDependencies": { - "browserslist-saucelabs": "0.1.2", - "gulp": "3.9.0", - "gulp-autoprefixer": "2.3.1", - "gulp-minify-css": "1.2.0", - "gulp-protractor": "1.0.0", - "gulp-sass": "2.0.3", - "gulp-sourcemaps": "1.5.2", - "gulp-util": "3.0.6", - "jasmine-core": "2.3.4", - "karma": "0.12.37", - "karma-coverage": "0.4.2", - "karma-coveralls": "1.1.0", - "karma-fixture": "0.2.5", - "karma-html2js-preprocessor": "0.1.0", - "karma-jasmine": "0.3.6", - "karma-json-fixtures-preprocessor": "0.0.4", - "karma-phantomjs-launcher": "0.2.0", - "karma-sauce-launcher": "0.2.14", - "phantomjs": "1.9.17", - "protractor": "2.1.0" + "browser-sync": "^2.8.2", + "browserslist-saucelabs": "^0.1.4", + "gulp-cached": "^1.1.0", + "gulp-iconfont": "<5.0.0", + "gulp-iconfont-css": "^1.0.1", + "gulp-imagemin": "^2.3.0", + "gulp-protractor": "^1.0.0", + "gulp-scss-lint": "^0.3.0", + "gulp-yuidoc": "^0.1.2", + "jasmine-core": "^2.3.4", + "karma": "^0.13.8", + "karma-coverage": "^0.5.0", + "karma-coveralls": "^1.1.2", + "karma-fixture": "^0.2.5", + "karma-html2js-preprocessor": "^0.1.0", + "karma-jasmine": "^0.3.6", + "karma-json-fixtures-preprocessor": "^0.0.5", + "karma-phantomjs-launcher": "^0.2.1", + "karma-sauce-launcher": "^0.2.14", + "phantomjs": "^1.9.17", + "protractor": "^2.1.0" } } diff --git a/tools/server/Makefile b/tools/server/Makefile new file mode 100644 index 0000000..35e3977 --- /dev/null +++ b/tools/server/Makefile @@ -0,0 +1,18 @@ +SHELL := /bin/bash + +PORT = 8000 +ENV = env +VENV = source $(ENV)/bin/activate +PIP = $(VENV); $(ENV)/bin/pip +MANAGE = $(VENV); $(ENV)/bin/python + +all: + make run + +install: + virtualenv $(ENV) + $(PIP) install -r requirements.txt + $(MANAGE) manage.py migrate + +run: + $(MANAGE) manage.py runserver 0.0.0.0:$(PORT) diff --git a/tools/server/db.sqlite3 b/tools/server/db.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..c472e0597c4a1757f3e01aaf97664a58d8586bac GIT binary patch literal 129024 zcmeHw33MFCd1hBv1A`$6k{}2U4?!3L0>KdopnL8iMN1F_QjkQ@;vpVBT5~jjA?E;R z20UcT-T`D=b~au+QO=cf*c-3oyu|D0&9j}&$PNd->BU98kj@x|)+EJpu8sHE*_lVrPJ>`h zOc1RZCKQt2A^mFhD3bD}oN>K+r2zS(rr1T>!)DR>t7@z;Xqi$Cn?2=YuQ5@I3Y;JmS}Z z8a`9Ym*9D(z8#+9OYk^+8XoX@cqIhS`&aISr+N=O?n=NTI0}z_gYf9v3lIM`cx>MV zkFL$6ZX*1BcuF^*Ztj);Nd6&tM(#kLM(;t7qhaZ5(nqA4lp+MKPilLI)O%zyTdb<8 z8m9$R535>KO@*VnrfDj?#KzR*m>LhN$-}YaVKp%xNyOE-mfFSzjWq^UBdO+~@$sap zrIK1|D;G4{95m?_G?9u#)L5#U3mS0+jqBk^G~pFA25E~$Qd_v7VJ>J=i|blS^W++h zrBcbrI3V0RY{8`I`BJ`?PZye5#l}-fh)7j8bx48X$tqNO0&Lq5$y6d7OHKMaq`sL+ zQln^2RG_TqD+X&hNyAyy!6)p+GzqyCP2ArFQ9R6|fE+2*jEcTgg-0P>t?7mGe7>ZY zmI|JNgWTa%_&y)Rah$~gS>wb(A|jPZFE7@ro>C+dvA8zX2{D{tF+dJEF&M>kzMvP= z*Y$!?ny)Q*MiN(J(eQ)N+w`4dkw9M2NVukl3bIN}(MU{-J*ad@!^bDB4v4}?P}D0% zv3%8rmv&4#iPTf3a8irKR7~?Uoh#-`tL14T8G}kRAww#LSt{BVf zcv%qWxf_T4MWeJ-)wAjBf^pfn(Hp{JeyhKw^@+4i-TUzXf{sY98!C(F64|#Rq5S|M@=us)z^Cf;v~UIJ5@DmwR~y5x_=nYbP>n-LOGKzkf^vu zgf`Cs1xJv_u%r(!NS*%dmb-AjErtw$?W0VnjQBm$UK)F~magsIf)mt>yyUZ-z}pA# z2qgnS77I(z2yf}a1AaPqBEphf*gArT7$QWhJ{eCishkl9>Gpd&An^?Yuc=MoF(p?e z`~#fEugB+LY<@3J;RqhXBlz3+Yxt}9uV9q^Com@eUHsel*YJPEzk)x6-;bZgKaSsn z--VyTZ^74b1sCufeiT29r}2Kg5BK41*pIRN|K#W8@5o=5pOe2V{~5F;Uyy%K{*?UR z9;MF+eTK<%n?|21eNK?))^YkAqt8R+**!|1 zchhHxJhvRA&k_1OK%Vk2ecnZ%L-aXFpZm#kbC5m<=<`km`%yo6+(91uh~uWc^tp#V zcax_-K%cwlvyVKxcG4%*RQSDvJbgX%xt%_@k!R;t`s}99E#%p;nLansr=L8PF8cJ* zXD4~$4*FE+6O*SbW9;{LLwW0yk4Z2i|1#9^PvBp~{}F0*9{T@jXa#o3|0aJ^{*wF$ z@-NFjDnB951F8531R4++=u@O4eP&-sJ7VK{P0wC7a`{@hQiGSCor)Cbr+qo=$^*TM z)H?>$=|Vnjb#GJ!vU>-3On^sIf4Hv)d}6dSv^({RF=tfB+?37k%ou(Q9Jj0OQ$0B^^p#nMBCi~ZvpZ~Q?f&W z*Zt(xk-7&Hkm;}pMn#}CtK8TugJgX~P=H|vf|nsGwGAKX|NG?Q68-}IFzDc(mEVM; zIDr2eOY*nmKf~XUe?@*q{v1Ar-zp!M7w{$gx`wP5uL1$kFeyj+tWhVFFP&6*SN-qX zp#=JotN!oYt@MtO0diyg@7<&HP7sf#`oH52r8h==xG}O_|9iTX-T?8W^?!Sx(mO&) zUG;yv(n|;BtX0^$OX&?UGN&eWGe%zZe@l+bihuc?cA#L1?U^C{~f(b-+ub)NUcziUG*Pt zQF{AW`s5u-?+}@3aPX1-AK^<9{1+dAfI#3SL!jP^x~2MvKhWLX?e|YkE@m$0=E8b) zAsvpz?+SxrP`&Gf@#uxQ6Bi#nUYR_1S6V%lt)2=Wn<(a{AG@(|UdzrFAId#a(ek5@ z&gXKAXCkF*l|t(L!lP%8(n{Z?fsBGyITnpZT?+NoVO2e>Y2)#DREzQ5JFox|Q*^`p{mUQTZE1yU*W)aHhC zaLa^MF09kbRkyTCA0PCV(n>|sJy(lQO&^;+H9b2ueHzw(VbrZtT8m2vR&N~v*BF5l zz=_3P7`7#8ia8W|cynh!PptuOheMUeo`ii{ZS*1yseTD|EO@u7PzoZ`18qw%LBJ}s_0Vi7 zXc$^^sy!`o+akZEOsCPWt#KfvPOToaYjg81l-1f5yG3B!AxrJ(LZN%Nbp}q4t&XIL z3J0hK#12ybUAuZ-!Wt@~76=FgZZ8Cg{!i5Z+bd6mGy;K_3jxvpzg$QQJ_3Q;4*}8t z-+p-_BoYX`TnL!!e_xgGS6?oUf{#EzAnE+4ozQE)pdaAo&>4h#yaEpxg zTAO)vjPvPjwH(tJ#ml@fE`f%(bR*J&E@;8$!K{dU&(^!fr1 zr%?R}JsRvROY86^;{!^ClqCS1JP9Wr{H5ErKiOxJdS{A_5E7S_CJbg#OQN=)@0!z=lJB z8~<;(w2K4_1U5PXqW|CMB|xNqBO@UC|BamcBJCR;0n+~~QdyG9XfOI4UZVOx4ir%S zy_ovH`oVxNaC#EeXBt!}sMi z4V0rQYK*vl&7!in)*`9{7u9I3jO?LX$1ioCkpG z{m2=Zdii+veGk3OEwyI#OXpK37Q34+g8nbfExu zItG_Y)%-l1GvJR;z^#oXxca9Ehwb6??_khmWnKIT?5u-p=G|Sc9sT5DNPbJc$MrrI zFyzb+&1P44cDW=Uhg~dK$WXm&uc`RcXwhoS89k~c=Cq8KZS)v$7o$dRJDgc~8odeo z#*~Lh|BvwV68tBZFp7^rKp?RG5$M7JKW*y8_<#Lpwn(8spcMk5{%lR= zkNvA?H`$6nYwae}$A;<)chdXHmap-ua9;UoG3T9LB3nX^jUQXH-Dptgg;)!k9(Yl# z<}6PHeZ*|eQ+>`RZ)bghs<55cLHE)@qc7;0J(c3^EH3dGvHD(YkKAL*b*kRa8SWd8 z8Uc6vHry6xU%AsL6CZUbbaejj8lf@=KH3 z`uyF<&)*4d-uxXK*TC9kIIKMg7Xiqm|0ni8O%tH&A@L#&0s(=*8W2!0^2^=0Pr}kW zCFz}VM4rQaXe-((owP&Cedv>cPzb$!#8C@TEgLa8ZEtL(2B>`=N+Fxn(#|yBe{Ac7 zRz^mA^aAgGHz%7(tN2%s+QY#2>KAz5z87?dV^P<>*q7jjZqRgjUtkXVV?)}(&cMyx z-o2}SDC7$a4WZ=$ULQ+r<5-$J^0VQFcFyOPvN%@;qroL-J8^p*V2s;qOiXBhJrIkb zWw`kqjHQFc9IzwoHd5y0HteneUL;fp$IOQ5i?xckuG6j+P;~jN#3V}inpVdwRH*R* zYKF`mSL0S@&#>11-yeYePrJ^G9|8e^zy?5o*#GQ+bYlD+lG;b`_rdz_cW_YtuKZc~ zgYvTcM)`g@i2fCQ5xpN>K_}6O^l#Evq)$mdD^;aQ3m|n*hlC7u+G zBFfHuo#+7y?TF9fXst03i|rg&%QZ-xC$^gbEY=MHEcSeW&^8D#8uJku8mNgJJZW$% z6}Qt8hU5|_1lfvT8C@i+*b?+9S=pXJR?3g#X4=o&WCEsJ2hu2ah+6!Qb<6q z6%X&ThsxO0R_~@s=9}e!>0(7e+SXkZ1iRVo+o_-sYG`S9nvN`#*+llzsQ5N?2Q3~R zZDx<@VTI>fJFx$WMp0uMxQ)ilH+Nf27b^mi@@^`&-JETq`R{7MHk(dX7}^AFqD8`K zpZoy@O`zr$smpY?f;z?AM{#IqWjbjZ8k>|3)76TCwF+SS6N;&;p};h0a+X%XCt8%X zZu|iWp(iEuB>n*UbExaqKS`>nV4!UT)qCjv1a9_F-!bM39FL)T%=T%V9qE~H%t)s* zQ4*}tbDMjgj~9s@-rUIGMM7pj<~)c@dtk~Y|8@$RvhLeZGU+py@($)E#4kx>*DQamDzOeY8ni7 z!)VN?)$*nJsyDUONyO2`>^kN6LqeO=SY6s9BmC{%9^U#&TVQ@I+ZIp6A>=05bk|trzfJ=$NTAbtA zsHcGzE??3s#+9Xfg_x6Tv^7`A7op?6ny=E>#Mgq~;lPQ&gUcY#;-h>RC>1p0ohy6b5Z=r`H+v!W^Iq2iT2ym>GEyROS~} zp{P|1GXvU1W7Q&3?5cXMk|u1MAcW)cOE7HV6HYCtnhA%z26Q1S`CWZpB43}Y04{oY zkz_nX#^joHj@~b(D=-Ll#YA$aNy|mXS*!*?d2&)ge`T8^uy*Y=YRekpA>$HvSg#ZN z&8kPDWXl0ZmEJHsBV+U^R=5(OuV5DG;Rh$k~a~mwSCWSd^4Z zd(eeuD~37RBZi8-Zz?h;7&*N)#qBi6TjQw8<FnqU(QR|G!-m#1DbMhC+br|2I^+ zMPda40s%=P^>5wE8^50Xvl9KfL}%b7 zJ9P{^-XG}iNAET7gJaWu_Lu4LEz{J@`PQcR6<`*JuQt`cs+O6amL^l!m{3ue$8Cs) zM zJOtkv_&x~VAyVDkLta) zrk85MjYL>WCNy)S0*ouBn>D#EI!AL$oCy-ntt0gvS8u<2m+Jl3OrajO6W+LZuBXCU zIx`o`l2Xv**$hY%2@CIl(?~*rA~*ClE{KPg`>)e0mR3%9mCK4TXTW_V*~X0|w)^94 zOR7yq_(STfqsK4WwZ3i5l)1K2fFxr5AL^j^2m}NIH-UiA|K9{yf>a=|&JYmwf1PEh zNRB|@CJ-R{{|@P+lJrryBKyC~r}2I`1Ms75B51d#shuCURnN8nP9}t2yQtdjcdGkO z`T|oLs*l(Nz2VVlF6MR{~pQCQe^qS#x?>JOjt1%`*wvU9635tH~c z-sJZwkEyjqMo^~F-SkY_wiZRAAmJM&N56@_ z4K}?$57xeadhJ-`kHZ=%xBLB_$5#4$|c{{IG>iZ9UK6X5WciIrWQftxu&xHz#ASW}2F1LexZ%I-CVh_DcqiIqKT3PJ5K zlSTMyer2yatE@{9Q;|$EqNb88>S6Ca0Xm~|?*t$jXBy_@%xZ;-EBj1d`&`>2^l&(u z$j0XEO%Zpu;Kk_L^8(|trjf4D+{zs$ziv0bTqa^mQ zLz$I+lTnA8k(NuwVu@Iefq19|BSzQE$g#K^%C6jLGV!^YL~^GuDC$qibfu zSr(=D|6%D_NqQFT#h=HYUwfUuIm$OJpEJ#g580^!l&k|2@pvK~*JAYat?e3`x|J}e zrYFx#2f53f?D%xX#R0_jqvh8*fkb!Iyls3r?+XkJpm&YhZCEW|E6}qd^v6RM^4u|H z>V8Yj*s6Bztf<)$r^Y6Z?ga9rF%R+*lgN5o|5{ql8P#khPtErZ25Vrsnb~u$7MA8) zH?M6C+72$ju^h0ftP^wE*D7Fux7h&k8tm~g3&0*0pqW=Y6UPoswMK3J*@wW`J|J>A zDKrkN?-7DhV_5~aw-`CG(_d>hPt2DWvR4T#T!WSCEO(SGtVWZ}thRljs$Ez(p+g~U z`BG-U^k`H;81tcJlGi+dVIOqN%*|gZWqnK z;an!0Nk?g$NL`FpY#5~n8(M9FMah#zEu-Y=(ta3>l>dL#IC5M$=>mNJFBG= z_y6AJO_vZ)An;NmK>B}0`Y}oRF}W=N8eYIp;djYjz=!eAwBvf?b#SQqrf=tmody$u zkrDKCz#dRTBWBJ4NNZ-lteks-Uf=(A=g>B374uo{_IMJY+0kkWxe<92%`J`2+n>bF zmUA$uZ8b875nT;*6Pa?k5ab4%_L#S5)E3GxthK|dFy6B?A27blRnl`c_o&qKN?m9A zVx^FbCtD3iPfZ`2J~cf%HGLZP$CL4_XJ|0S-7p?*z=dwV=fi;(R@7;PUh6~9KC(Oiy+lfJ-A0@V|?v`tCUW7$kJnMhFmPLuCkvz$#db_|Y?O*BM8yG+sk zzk^)sF)g2$pTS%3JMfRRtNEUOPic3YBsz7f~%l*t+xu$&1wH$RTkqH zZ`DjYsmV?az17AbXDpKIPuOkWOQmXlzGUS1#-_AX%r4{$+%Xw1sy6d|%jicawS2lW zaAKt0T-45ZvxeKRCzh7an7Sgz_>1kS^V2We^+0pou>I^1PMxs*NRe}Y!H@%wI4|NqpshS~C~UjJWQ8SqqHCo;)& zb}k)VCeCc{U%Rj7kA1tI+xbq%%Z)@@R}Ap z8C^3^m^3exi%_idD}yGBRjx(4w*?D!eNrE$yF=6*^|4YFtZgYi|Oln!6?nw7Ca+~tFdVK!48Pz9E$|qr1(_#-Q9n$de zNghUmB8=#Zu#&;x)d{|^I9N11WeO*?SWLwBI6~`8s~U9RK5=#6Jo5em=1L2KVsIdrtxxyht;~>hCTc66pN08^mHVrg^es-bZt$h zH4nC16Weh*qvO`ZBm+Es$t4{1!#9-{7Ux>i!b*|3{|En^ zgujYE4S$}5W`um-4Bu<;y=wifS$~Ne7z>0M0bHmL-}~Up?*Baszhm$ngYO~uj>7kD z_`b<{C%caRtqQA+D6m*iKX4K?&M+B%VExT zvho4jH_~R&4^DMRXlS%AXA}%rj3IlnrqZRL`D$*_y5FQQ_rcl}<}0PxI|&s1!+q&o z&i01i)Q_D1CH8;OGWt9Dg!~&=!_UA9z(=K7djB`^ZT)%EGBUN6k1t1k(sI)G_;O-R z3JbOja0?2H%yN89ikAnP+fSE*#%U>uGbsa3nF(c=Crl>J<{uiE?Wtr%rrZcsBH* zE6bV*-6~qsRvOG((wZ)ZO`fZ0OWZsO{bQ2u=lks;Y{5(9w zM<5^&Smy{R82M#-{vQ&mu>OCYCt4&=ARrL%KtR-g4^V`YKwyI)AnN}H$!L*Gfq(}B zWc`om|HMZiAQ0Gi2#ET>@$y`xSRlX<=tln+y8q8g(r3{d}7 zWz;x5vch{@YfcaEZHIG`!g~{VvxWR(rkt+i$TopceX_pIEO#k;Qy6zriY_=h2dA!E z+_`OE9I>?zpn1){-R)CrGA&K^Rk`d_yDo1D-KcNBmE*L{P;!aUV@4{GN=0F1`{bk{#yzEGyX3A8vGC+fq+0@9U;)EC=x<)M<=F# zl@3{v{0Mg-@<%59zkDq@h8;F_&YEiO1HZ0?Bxljb^OUHwgftjj*NL-lv?utx4&t)IwbliHuG&F}^U}{1W5El`&sndKxV!Xkj)_?UEu) z4&&-5Kp?O#5I6|tKzjTq zjS{u`o=s;L3~KaAFM*}Xs&15Y4gQg3QM3MkS;Ajl7YP@M5C{ka90Ufye8`?XUHu42 zbLBEvbuypqI{Z!_8UG{v4-)(rAAx{CU?U)~N!cU$&6dDi|NoYR{|SG~y!Qk7kk1A| zT&-bRT6AtvXu6_Mt{GBchw!z-;AGD;7IjvWx&nn|co-(+&^Yk+YMEJudtvZ~Fo(uyOa zY|D`pFi2pozS(5w7#Ot>O~)f(p4DMjZN*NrC^>drxDOEnWU>$U`Nc2Jr|A7Q%fW${2AQ0F<2w*Jv&H4ZHQ2+7s z8z|`_sRDtGjDUi>k&JP-pRWJOB}p#H&unBsMA~0G1kkUXc$+bKg*HQ$i)Zd!xta89GQJ!GBSJS@{JRh3JWKmSWL_mXKPt4wQ%vcwwNiTo=BfR zRhYR{zW&J6Lvt6-Kc=RSrL=7Lu^Z>Zh0EZcKXH1dYK2iV;Z*fP@fi4>TFi!z%=RxOnaeOF)?(w4L_8H!MgRZem3tABK;Tt^fP%Y7|KH_| z|DP8cfLBT02{8o%FBAc*{`;N!FXsO*6jKpiAn9lB9iIl3$YiJzZTA z^835`0_j{aUt+o}HO_Qd(eXq$l1xRKePZJ(=)O|0LC@5G@nMp&cr+fFnSF5j)XW*U z4@Xs1jWVbsxk-pFB80!a5XpEXmWnmA0wKbwNWxaawGjej2vZpV$~@ozsdwW5GTaId z(eY$BmW)O1)Y^&N1k-*Qe^{lBRH8zA3B5(NST zfzFODzeMW4-w*qL@n69C|Bp-fha~xL()mJ!izCbLn{4?R?dJFx>5FhcQowyFJOle&hOLzGCP(dK$eRUzzX) zLLsy~!WqF~{M~^sS!~Zt-v7vSaM0~ZZ%eSGzHERwnycwbb|GCk80D-p1-Uy9;FbeB zmFZf#!F~<+@^S`=w6%QE2r_d;q56fDaZ~alm7Ls&1?F+cl~};v{g!b{?)H3TXl3c_-o_wxSG_|JMkoH_GR1usr~Og z(j?sfi9dsX23PTeI4FNt{;d2#d0Bp=e7_t-|BAkd-jA-JlW0WxH|ZjxjP_f;*@*U6hwYMA@0I6Foqo9r0Nlv*l9FDAj5=7Wsr(u0i5FvE2+{ zv2F-pvF8JXwn2c=n2*TNKuzS}NrPLdxSf_TB$v3f(@g6&DJ<@c!eUEa_ih1-{^3r- zj(HP4mq6aS4Gs4M4}142AMM z^MsvjwKJPiSbl898aXk zs4Xx&NoTmLhR~u~B62^B+KvoQn$t&m)g5pBcGWmkHKwX57|rz_nS{_FWSCA;bt0o0 zR}*?Tth)B;F@cldnM$T$m}dvoxS&xjrE97h_eyIbLAK=G1LMEmNsFth7xVKK&=Qcb ziqkoIg^s1vl&T(r5n}ItGqjq5TeK_lh9`9-8jGb;FivD*s!2{vEv)H)fol^WOJOV$ zjwQk=7&>|e4MRj>E$SIGnn)$0sT7PU?Vt&pYgALiNnHc6yabMh6A3j&=Kn*~{x>>~ zbaV~96a6ImF#2`$=ja>g|H<3s1M)rcqjFxZ%kP!{ll*b{cjYh1U&9jKgTwd%d;yp6 zllVX2pU0oTe}exWJ&ER|=cLa_KQBEk6&fqgJ_RLEH#baihEI3zR*;6e=_m`vFOElO zzk;UF7B+w^lr!nVqKo37Nnu4h??Ewgr-F{6EhKU;?*sh`I)Y?k#u*Akx|YxCi;ltX z;T;MZMzVDyq`sKmsrW|`71SZx7f}2fVkvXn@1X8%T z9Xk~iLJcG1&VYg@kiwv_hvGidor!O|cTt&~fxVx~)M16E!~0F9lNFRYZKi11Q;sbZ zn@%ebz*^}xU92#~Wh+fXy{4lT z-g4YY#kMD+eKaaR3kcKEU8V~Q1ulVI3K~OAbLHK86cj;TlkPpH50`Rl+Fjk-tDq6I znG`W-flce+car{pr*ulf{{#O5zKV~-?EiaE$3HATEnkw4$(zv^phcKQJEgyrJ}A8v z2v_}#j*;n2YO9qjQqTzg-0bQsyao>vkI?WTGQo*#W#yhx!h4V-i;V(VVzS#xmAe7p z=2)+VIJrq#>~1p{CyLXuZ~`?1n+QQL?TANfM8Xi!8UoyZ5CTk{Y}ZOP3TZY(oUHec zm~mLLdNovy5;w(h&jE+Z+n^vnCBpG(c5YP;aIL!}7ACI zlYj$k><&uK%B7p!l7S;1*$3pK5n4&yw4^X{ger^$5h&vHi0$ zzn9R%D1++g1L$|qU!i}IcgZ37UimD{1fG^ZAb$*6gg=x23Gc=C;Pdzz{&CO|{2~4Z zia~d>UHVrD{twchN*|Y=mEIyf?rtDxAJuEglP=`bR>MPd4~3(quLVP+?>&1J;LuA_ z-RO0M_UJpTXq&F&K5Tkh@!HM%P$4pl) z5>mFtXZAIP``f!_)-@eMUuWl5kokU<(XkSD6|6XZa!e4|jd>(7KSN@j#Ir-i4!*Un; zWAqF26o`%-Z`G7=BGAUdYU``V{5|6)EqW?1j5E9J)0pWWOJw^ zhauF_<1Je#PFyqh`BwZ$$_#9Y+f+O_d7A^rk`OpC>0K5;h8F4!}uoJ$v?%M_``;9js+x{!2ELkX;|#Zi;3Kqm*kw zl`rX~^ws=4jcG8LDVGcUc7|$suBKPO7*VrV#Q*~jpq9z!8uo>l?44M3=$koGPWy*C-pE&(JVJC z!Y)D4;=1.8.0 +django-cms>=3.1.0 +djangocms-text-ckeditor>=2.5.2 diff --git a/tools/server/src/__init__.py b/tools/server/src/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tools/server/src/settings.py b/tools/server/src/settings.py new file mode 100644 index 0000000..61f7160 --- /dev/null +++ b/tools/server/src/settings.py @@ -0,0 +1,190 @@ +from django.utils.translation import ugettext_lazy as _ + +""" +Django settings for this project. + +For more information on this file, see +https://docs.djangoproject.com/en/1.7/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/1.7/ref/settings/ +""" + +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +import os +BASE_DIR = os.path.dirname(os.path.dirname(__file__)) +DATA_DIR = os.path.join(BASE_DIR, 'data') + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = '^7o%@!ta#o$n!72cxl#&4n!!qog7727duk$nu*!$^7prnoxb-w' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +TEMPLATE_DEBUG = True + +ALLOWED_HOSTS = ['*'] + + +# Application definition + +INSTALLED_APPS = ( + # djangocms_admin_style needs to be before django.contrib.admin! + # https://django-cms.readthedocs.org/en/develop/how_to/install.html#configuring-your-project-for-django-cms + 'djangocms_admin_style', + # django defaults + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + # django cms + 'django.contrib.sites', + 'cms', + 'treebeard', + 'menus', + 'sekizai', + # django CMS addons + 'djangocms_text_ckeditor', +) + +MIDDLEWARE_CLASSES = ( + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', + # django CMS additions + 'django.contrib.sites.middleware.CurrentSiteMiddleware', + 'django.middleware.locale.LocaleMiddleware', + 'cms.middleware.user.CurrentUserMiddleware', + 'cms.middleware.page.CurrentPageMiddleware', + 'cms.middleware.toolbar.ToolbarMiddleware', + 'cms.middleware.language.LanguageCookieMiddleware', +) + +ROOT_URLCONF = 'src.urls' + +WSGI_APPLICATION = 'src.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/1.7/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + } +} + +# Internationalization +# https://docs.djangoproject.com/en/1.7/topics/i18n/ + +LANGUAGE_CODE = 'en' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/1.7/howto/static-files/ + +STATIC_URL = '/static/' +MEDIA_URL = '/media/' +MEDIA_ROOT = os.path.join(DATA_DIR, 'media') +STATIC_ROOT = os.path.join(DATA_DIR, 'static_collected') + +STATICFILES_DIRS = ( + os.path.join(BASE_DIR, '../../static'), +) + + +# Templates +# https://docs.djangoproject.com/en/1.7/ref/settings/#template-context-processors + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [ + os.path.join(BASE_DIR, '../../templates'), + os.path.join(BASE_DIR, 'templates'), + ], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + # Insert your TEMPLATE_CONTEXT_PROCESSORS here or use this + # list if you haven't customized them: + 'django.contrib.auth.context_processors.auth', + 'django.template.context_processors.debug', + 'django.template.context_processors.i18n', + 'django.template.context_processors.media', + 'django.template.context_processors.static', + 'django.template.context_processors.tz', + 'django.contrib.messages.context_processors.messages', + # django CMS additions + 'django.core.context_processors.request', + 'sekizai.context_processors.sekizai', + 'cms.context_processors.cms_settings', + ], + }, + }, +] + + +# django CMS settings +# http://docs.django-cms.org/en/latest/ + +SITE_ID = 1 + +CMS_PERMISSION = True + +CMS_PLACEHOLDER_CONF = {} + +CMS_TOOLBAR_SIMPLE_STRUCTURE_MODE = True + + +# django CMS internationalization +# http://docs.django-cms.org/en/latest/topics/i18n.html + +LANGUAGES = ( + ('en', _('English')), +) + +CMS_LANGUAGES = { + # Customize this + 'default': { + 'public': True, + 'hide_untranslated': False, + 'redirect_on_fallback': True, + }, + 1: [ + { + 'public': True, + 'code': 'en', + 'hide_untranslated': False, + 'name': _('English'), + 'redirect_on_fallback': True, + }, + ], +} + +# django CMS templates +# http://docs.django-cms.org/en/latest/how_to/templates.html + +CMS_TEMPLATES = ( + # Customize this + ('bootstrap.html', 'Bootstrap'), +) diff --git a/tools/server/src/urls.py b/tools/server/src/urls.py new file mode 100644 index 0000000..4f18475 --- /dev/null +++ b/tools/server/src/urls.py @@ -0,0 +1,12 @@ +from django.conf import settings +from django.conf.urls import patterns, include, url +from django.conf.urls.i18n import i18n_patterns +from django.contrib import admin + +urlpatterns = patterns('', + url(r'^static/(?P.*)$', 'django.contrib.staticfiles.views.serve', { 'insecure': True }), + url(r'^media/(?P.*)$', 'django.views.static.serve', { 'document_root': settings.MEDIA_ROOT }), +) + i18n_patterns('', + url(r'^admin/', include(admin.site.urls)), + url(r'^', include('cms.urls')), +) diff --git a/tools/server/src/wsgi.py b/tools/server/src/wsgi.py new file mode 100644 index 0000000..149506b --- /dev/null +++ b/tools/server/src/wsgi.py @@ -0,0 +1,14 @@ +""" +WSGI config for this project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/1.7/howto/deployment/wsgi/ +""" + +import os +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings") + +from django.core.wsgi import get_wsgi_application +application = get_wsgi_application() diff --git a/tools/server/templates/bootstrap.html b/tools/server/templates/bootstrap.html new file mode 100644 index 0000000..86de909 --- /dev/null +++ b/tools/server/templates/bootstrap.html @@ -0,0 +1,999 @@ +{% extends "base_root.html" %} +{% load sekizai_tags %} + +{% block extend_root %} +
+ {# Navbar #} + + + + + {# Buttons #} + + + + {# Typography #} + +
+
+

Heading 1

+

Heading 2

+

Heading 3

+

Heading 4

+
Heading 5
+
Heading 6
+

Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.

+
+
+

Example body text

+

Nullam quis risus eget urna mollis ornare vel eu leo. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nullam id dolor id nibh ultricies vehicula.

+

This line of text is meant to be treated as fine print.

+

The following snippet of text is rendered as bold text.

+

The following snippet of text is rendered as italicized text.

+

An abbreviation of the word attribute is attr.

+
+
+

Emphasis classes

+

Fusce dapibus, tellus ac cursus commodo, tortor mauris nibh.

+

Nullam id dolor id nibh ultricies vehicula ut id elit.

+

Etiam porta sem malesuada magna mollis euismod.

+

Donec ullamcorper nulla non metus auctor fringilla.

+

Duis mollis, est non commodo luctus, nisi erat porttitor ligula.

+

Maecenas sed diam eget risus varius blandit sit amet non magna.

+
+
+

Blockquotes

+
+
+
+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.

+ Someone famous in Source Title +
+
+
+
+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.

+ Someone famous in Source Title +
+
+
+ + {# Tables #} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#Column headingColumn headingColumn heading
1Column contentColumn contentColumn content
2Column contentColumn contentColumn content
3Column contentColumn contentColumn content
4Column contentColumn contentColumn content
5Column contentColumn contentColumn content
6Column contentColumn contentColumn content
7Column contentColumn contentColumn content
+ + {# Forms #} + +
+
+
+
+
+ Legend +
+ +
+ +
+
+
+ +
+ +
+ +
+
+
+
+ +
+ + A longer block of help text that breaks onto a new line and may extend beyond one line. +
+
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+ +
+ +
+
+
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ $ + + + + +
+
+
+
+
+ + {# Navs #} + +
+
+ + +
+
+

Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.

+
+
+

Food truck fixie locavore, accusamus mcsweeney's marfa nulla single-origin coffee squid. Exercitation +1 labore velit, blog sartorial PBR leggings next level wes anderson artisan four loko farm-to-table craft beer twee. Qui photo booth letterpress, commodo enim craft beer mlkshk aliquip jean shorts ullamco ad vinyl cillum PBR. Homo nostrud organic, assumenda labore aesthetic magna delectus mollit.

+
+ + +
+
+ +
+ + + + +
+
+
+
+

Pagination

+ + + +
+
+

Pager

+ + +
+
+
+
+ + {# Indicators #} + +

Alerts

+
+ +

Warning!

+

Best check yo self, you're not looking too good. Nulla vitae elit libero, a pharetra augue. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.

+
+
+
+
+ + Oh snap! Change a few things up and try submitting again. +
+
+
+
+ + Well done! You successfully read this important alert message. +
+
+
+
+ + Heads up! This alert needs your attention, but it's not super important. +
+
+
+
+
+

Labels

+

+ Default + Primary + Success + Warning + Danger + Info +

+
+
+

Badges

+ +
+
+ + {# Progress bars #} + +

Basic

+
+
+
+

Contextual alternatives

+
+
+
+
+
+
+
+
+
+
+
+
+

Striped

+
+
+
+
+
+
+
+
+
+
+
+
+

Animated

+
+
+
+

Stacked

+
+
+
+
+
+ + {# Containers #} + +
+

Jumbotron

+

This is a simple hero unit, a simple jumbotron-style component for calling extra attention to featured content or information.

+

Learn more

+
+

List groups

+ +

Panels

+
+
+
+
+ Basic panel +
+
+
+
Panel heading
+
+ Panel content +
+
+
+
+ Panel content +
+ +
+
+
+
+
+

Panel primary

+
+
+ Panel content +
+
+
+
+

Panel success

+
+
+ Panel content +
+
+
+
+

Panel warning

+
+
+ Panel content +
+
+
+
+
+
+

Panel danger

+
+
+ Panel content +
+
+
+
+

Panel info

+
+
+ Panel content +
+
+
+
+

Wells

+
+
+
+ Look, I'm in a well! +
+
+
+
+ Look, I'm in a small well! +
+
+
+
+ Look, I'm in a large well! +
+
+
+ + {# Dialogs #} + +
+
+

Modals

+ +
+
+

Popovers

+

+ + + + +

+

Tooltips

+

+ + + + +

+
+
+ + {# Icons #} + +
+
+

Styles

+

+ fa-lg + fa-2x + fa-3x + fa-4x + fa-5x +

+ +
+ +

+   +   +   +   + +

+ +
+ +

+ + + + + fa-twitter on fa-square-o
+ + + + + fa-flag on fa-circle
+ + + + + fa-terminal on fa-square
+ + + + + fa-ban on fa-camera +

+ +
+ +

+ +

+
+
+

Bootstrap

+

+ Delete + Settings +

+ +

+ Font Awesome
Icons
+

+ +

+ + + + +

+ +

+ + +

+ +

+ + +

+ + +
+
+ +
+ +
+ +
+ +{% addtoblock "js" %} + +{% endaddtoblock %} +{% endblock extend_root %} diff --git a/tools/tasks/bower.js b/tools/tasks/bower.js new file mode 100644 index 0000000..d691db9 --- /dev/null +++ b/tools/tasks/bower.js @@ -0,0 +1,11 @@ +var bower = require('gulp-bower'); + +module.exports = function (gulp, opts) { + 'use strict'; + + return function () { + gulp.task('bower', function () { + return bower(gulp.dest(opts.PROJECT_ROOT + opts.PROJECT_PATH.bower)); + }); + }; +}; diff --git a/tools/tasks/browser.js b/tools/tasks/browser.js new file mode 100644 index 0000000..8592668 --- /dev/null +++ b/tools/tasks/browser.js @@ -0,0 +1,24 @@ +var browserSync = require('browser-sync'); + +module.exports = function (gulp, opts) { + 'use strict'; + + return function () { + var files = [ + opts.PROJECT_PATH.css + '*.css', + opts.PROJECT_PATH.html + '**/*.html', + opts.PROJECT_PATH.js + '**/*.js' + ]; + + // DOCS: http://www.browsersync.io/docs/options/ + setTimeout(function () { + browserSync.init(files, { + proxy: '0.0.0.0:' + opts.PORT, + port: opts.PORT + 1, + ui: { + 'port': opts.PORT + 2 + } + }); + }, 1000); + }; +}; diff --git a/tools/tasks/docs.js b/tools/tasks/docs.js new file mode 100644 index 0000000..87da628 --- /dev/null +++ b/tools/tasks/docs.js @@ -0,0 +1,11 @@ +var yuidoc = require('gulp-yuidoc'); + +module.exports = function (gulp, opts) { + 'use strict'; + + return function () { + gulp.src(opts.PROJECT_PATTERNS.js) + .pipe(yuidoc()) + .pipe(gulp.dest(opts.PROJECT_PATH.docs)); + }; +}; diff --git a/tools/tasks/icons.js b/tools/tasks/icons.js new file mode 100644 index 0000000..95da588 --- /dev/null +++ b/tools/tasks/icons.js @@ -0,0 +1,27 @@ +var gutil = require('gulp-util'); +var iconfont = require('gulp-iconfont'); +var iconfontCss = require('gulp-iconfont-css'); + +module.exports = function (gulp, opts) { + 'use strict'; + + return function () { + gulp.src(opts.PROJECT_PATH.icons + '/**/*.svg') + .pipe(iconfontCss({ + fontName: 'iconfont', + appendUnicode: true, + formats: ['ttf', 'eot', 'woff', 'svg'], + fontPath: 'static/fonts/', + path: opts.PROJECT_PATH.sass + '/libs/_iconfont.scss', + targetPath: '../../../private/sass/layout/_iconography.scss' + })) + .pipe(iconfont({ + fontName: 'iconfont', + normalize: true + })) + .on('glyphs', function (glyphs, options) { + gutil.log.bind(glyphs, options); + }) + .pipe(gulp.dest(opts.PROJECT_PATH.fonts)); + }; +}; diff --git a/tools/tasks/images.js b/tools/tasks/images.js new file mode 100644 index 0000000..24bf608 --- /dev/null +++ b/tools/tasks/images.js @@ -0,0 +1,21 @@ +var gutil = require('gulp-util'); +var cache = require('gulp-cached'); +var imagemin = require('gulp-imagemin'); + +module.exports = function (gulp, opts) { + 'use strict'; + + return function () { + var options = { + interlaced: true, + optimizationLevel: 5, + progressive: true + }; + + gulp.src(opts.PROJECT_PATTERNS.images) + .pipe(cache(imagemin(options))) + .pipe(gulp.dest(opts.PROJECT_PATH.images)).on('error', function (error) { + gutil.log('\n' + error.message); + }); + }; +}; diff --git a/tools/tasks/lint/javascript.js b/tools/tasks/lint/javascript.js new file mode 100644 index 0000000..f43aa9d --- /dev/null +++ b/tools/tasks/lint/javascript.js @@ -0,0 +1,23 @@ +var gutil = require('gulp-util'); +var jscs = require('gulp-jscs'); +var jshint = require('gulp-jshint'); +var jscs = require('gulp-jscs'); + +module.exports = function (gulp, opts) { + 'use strict'; + + return function () { + // DOCS: http://jshint.com/docs/ + return gulp.src(opts.PROJECT_PATTERNS.js) + .pipe(jshint()) + .pipe(jscs()) + .on('error', function (error) { + gutil.log('\n' + error.message); + if (process.env.CI) { + // force the process to exit with error code + process.exit(1); + } + }) + .pipe(jshint.reporter('jshint-stylish')); + }; +}; diff --git a/tools/tasks/sass.js b/tools/tasks/sass.js new file mode 100644 index 0000000..d39a6b1 --- /dev/null +++ b/tools/tasks/sass.js @@ -0,0 +1,39 @@ +var sass = require('gulp-sass'); +var minifyCss = require('gulp-minify-css'); +var autoprefixer = require('gulp-autoprefixer'); +var sourcemaps = require('gulp-sourcemaps'); +var gutil = require('gulp-util'); +var gulpif = require('gulp-if'); + +module.exports = function (gulp, opts) { + 'use strict'; + + return function () { + gulp.task('sass', function () { + gulp.src(opts.PROJECT_PATTERNS.sass) + // sourcemaps can be activated through `gulp sass --debug´ + .pipe(gulpif(opts.DEBUG, sourcemaps.init())) + .pipe(sass()) + .on('error', function (error) { + gutil.log(gutil.colors.red( + 'Error (' + error.plugin + '): ' + error.messageFormatted) + ); + // used on Aldryn to inform aldryn client about the errors in + // SASS compilation + if (process.env.EXIT_ON_ERRORS) { + process.exit(1); + } + }) + .pipe(autoprefixer({ + // browsers are coming from browserslist file + cascade: false + })) + .pipe(minifyCss({ + rebase: false + })) + // sourcemaps can be activated through `gulp sass --debug´ + .pipe(gulpif(opts.DEBUG, sourcemaps.write())) + .pipe(gulp.dest(opts.PROJECT_PATH.css)); + }); + }; +}; diff --git a/tools/tasks/tests/integration.js b/tools/tasks/tests/integration.js new file mode 100644 index 0000000..45b0945 --- /dev/null +++ b/tools/tasks/tests/integration.js @@ -0,0 +1,19 @@ +var gutil = require('gulp-util'); +var protractor = require('gulp-protractor').protractor; + +module.exports = function (gulp, opts) { + 'use strict'; + + return function () { + return gulp.src([opts.PROJECT_PATH.tests + '/integration/specs/*.js']) + .pipe(protractor({ + configFile: opts.PROJECT_PATH.tests + '/protractor.conf.js', + args: [] + })) + .on('error', function (error) { + gutil.log(gutil.colors.red( + 'Error (' + error.plugin + '): ' + error.message + )); + }); + }; +}; diff --git a/tools/tasks/tests/unit.js b/tools/tasks/tests/unit.js new file mode 100644 index 0000000..3f01239 --- /dev/null +++ b/tools/tasks/tests/unit.js @@ -0,0 +1,12 @@ +var karma = require('karma').server; + +module.exports = function (gulp, opts) { + 'use strict'; + + return function (done) { + karma.start({ + configFile: opts.PROJECT_PATH.tests + '/karma.conf.js', + singleRun: true + }, done); + }; +}; diff --git a/tools/tasks/tests/watch.js b/tools/tasks/tests/watch.js new file mode 100644 index 0000000..c6093d7 --- /dev/null +++ b/tools/tasks/tests/watch.js @@ -0,0 +1,11 @@ +var karma = require('karma').server; + +module.exports = function (gulp, opts) { + 'use strict'; + + return function () { + karma.start({ + configFile: opts.PROJECT_PATH.tests + '/karma.conf.js' + }); + }; +};