├── .circleci
└── config.yml
├── .dockerignore
├── .ebextensions
└── 10docker.config
├── .editorconfig
├── .env.sample
├── .eslintrc
├── .gitignore
├── .sailsrc
├── Dockerfile
├── Dockerrun.aws.json.in
├── Gruntfile.js
├── LICENSE.md
├── Procfile
├── README.md
├── api
├── _apidoc.js
├── controllers
│ ├── .gitkeep
│ ├── AuthController.js
│ ├── BadgeController.js
│ ├── CampusController.js
│ ├── CollaboratorController.js
│ ├── ExampleController.js
│ ├── HomeController.js
│ ├── PackageController.js
│ ├── PackageVersionController.js
│ ├── ReviewController.js
│ ├── RstudioController.js
│ ├── SearchController.js
│ ├── TaskViewController.js
│ ├── TopicController.js
│ ├── TrendsController.js
│ ├── UserController.js
│ └── WorkerController.js
├── hooks
│ ├── aws
│ │ └── index.js
│ ├── elasticsearch
│ │ └── index.js
│ ├── redis
│ │ └── index.js
│ └── worker
│ │ └── index.js
├── models
│ ├── .gitkeep
│ ├── Alias.js
│ ├── ApiToken.js
│ ├── Argument.js
│ ├── BiocDownloadStatistics.js
│ ├── Collaborator.js
│ ├── Dependency.js
│ ├── DownloadStatistic.js
│ ├── Example.js
│ ├── Package.js
│ ├── PackageVersion.js
│ ├── ParsingJob.js
│ ├── Percentile.js
│ ├── Repository.js
│ ├── Review.js
│ ├── Section.js
│ ├── Star.js
│ ├── Tag.js
│ ├── TaskView.js
│ ├── Topic.js
│ └── User.js
├── policies
│ ├── api_auth.js
│ ├── flash.js
│ └── sessionAuth.js
├── responses
│ ├── badRequest.js
│ ├── created.js
│ ├── forbidden.js
│ ├── notFound.js
│ ├── ok.js
│ ├── rstudio_redirect.js
│ └── serverError.js
└── services
│ ├── .gitkeep
│ ├── AuthorService.js
│ ├── CronService.js
│ ├── DownloadStatsService.js
│ ├── ElasticSearchService.js
│ ├── FlashService.js
│ ├── PackageService.js
│ ├── PackageVersionService.js
│ ├── RStudioService.js
│ ├── RecoverService.js
│ ├── RedisService.js
│ ├── TopicService.js
│ ├── Utils.js
│ ├── passport.js
│ └── s3Service.js
├── apidoc.json
├── app.js
├── assets
├── css
│ ├── bootstrap-glyphicons.css
│ ├── bootstrap-treeview.css
│ └── nv.d3.min.css
├── favicon.ico
├── images
│ ├── .gitkeep
│ ├── GitHub-Mark-32px.png
│ ├── logo-dark.png
│ ├── logo.png
│ └── placeholder.png
├── js
│ ├── dependencies
│ │ ├── async_loader.js
│ │ ├── highlight.pack.js
│ │ ├── highlightjs-line-numbers.js
│ │ └── rstudio_navigator.js
│ ├── helpers
│ │ ├── boot.js
│ │ ├── downloadStats.js
│ │ ├── list-table-filtering.js
│ │ ├── toggle.js
│ │ └── utils.js
│ ├── libs
│ │ ├── bootstrap-treeview.js
│ │ ├── countUp.min.js
│ │ ├── experiment.js
│ │ ├── jquery.cookie-1.4.1.min.js
│ │ ├── marked.min.js
│ │ └── tooltip.js
│ ├── pages
│ │ ├── collaborator.js
│ │ ├── examples.js
│ │ ├── package.js
│ │ ├── search.js
│ │ ├── source.js
│ │ ├── task_views.js
│ │ ├── trending.js
│ │ └── user.js
│ └── search.js
├── robots.txt
├── sitemap
│ ├── sitemap-1.xml.gz
│ ├── sitemap-2.xml.gz
│ ├── sitemap-3.xml.gz
│ ├── sitemap-4.xml.gz
│ ├── sitemap-5.xml.gz
│ └── sitemapindex.xml.gz
├── styles
│ ├── application.scss
│ ├── jquery-ui
│ │ ├── core.scss
│ │ └── tabs.scss
│ ├── pages
│ │ ├── _authentication.scss
│ │ ├── _collaborator.scss
│ │ ├── _error-page.scss
│ │ ├── _examples.scss
│ │ ├── _home.scss
│ │ ├── _package-details.scss
│ │ ├── _package-header.scss
│ │ ├── _package-readme.scss
│ │ ├── _package-source.scss
│ │ ├── _package-vignettes.scss
│ │ ├── _package.scss
│ │ ├── _search.scss
│ │ ├── _shared.scss
│ │ ├── _task-view-sidebar.scss
│ │ ├── _task-views.scss
│ │ ├── _topic-header.scss
│ │ ├── _topic.scss
│ │ ├── _trends.scss
│ │ └── _user.scss
│ ├── styleguide
│ │ ├── _base.scss
│ │ ├── _globals.scss
│ │ ├── _normalize.scss
│ │ └── partials
│ │ │ ├── _buttons.scss
│ │ │ ├── _flash.scss
│ │ │ ├── _footer.scss
│ │ │ ├── _forms.scss
│ │ │ ├── _grid.scss
│ │ │ ├── _labels.scss
│ │ │ ├── _lists.scss
│ │ │ ├── _navbar.scss
│ │ │ ├── _rstudio.scss
│ │ │ ├── _tables.scss
│ │ │ ├── _tooltip.scss
│ │ │ └── _typography.scss
│ └── widgets
│ │ ├── _big-number.scss
│ │ ├── _github-markdown.scss
│ │ ├── _loader.scss
│ │ ├── _modal.scss
│ │ ├── _search.scss
│ │ └── mono-blue.css
└── templates
│ └── .gitkeep
├── build.sh
├── catalog-info.yaml
├── config
├── blueprints.js
├── bootstrap.js
├── connections.js
├── cors.js
├── csrf.js
├── elasticsearch.js
├── env
│ ├── development.js
│ ├── docker.js
│ ├── production.js
│ ├── staging.js
│ └── worker.js
├── globals.js
├── http.js
├── i18n.js
├── locales
│ ├── _README.md
│ ├── de.json
│ ├── en.json
│ ├── es.json
│ └── fr.json
├── log.js
├── models.js
├── policies.js
├── redis.js
├── routes.js
├── session.js
├── sockets.js
└── views.js
├── cron.yaml
├── database.json
├── deploy_worker.sh
├── docker-compose.yml
├── ecs.json
├── ecs.worker.json
├── jake
├── Jakefile.js
└── sails-lifter.js
├── migrations
├── 20160603105133-initial.js
├── 20160607121610-indexAliases.js
├── 20160609193515-title-allow-null.js
├── 20160610094821-argument-description.js
├── 20160612100705-users.js
├── 20160612150901-package-type.js
├── 20160612161712-package-type-allow-null.js
├── 20160612162625-topic-add-sourceJSON.js
├── 20160613085210-comments.js
├── 20160614083536-review-model.js
├── 20160621104843-task-views.js
├── 20160624081405-download-statistics.js
├── 20160626120528-token-table.js
├── 20160626154713-unique-review.js
├── 20160708081226-readme-in-versions.js
├── 20160711142622-splitted-downloads.js
├── 20160714072116-downloads-per-day.js
├── 20160714100838-stringToText.js
├── 20160714102013-add-dependency-enum.js
├── 20160714113658-cascading-delete-of-sections.js
├── 20160812141926-BiocDownloads.js
├── 20160821202039-stars.js
├── 20160822080118-examples.js
├── 20160830084534-percentiles.js
├── 20170809033252-parser-version.js
├── 20170809222533-parsing-jobs.js
└── sqls
│ ├── 20160603105133-migration-name-down.sql
│ ├── 20160603105133-migration-name-up.sql
│ ├── 20160609193515-title-allow-null-down.sql
│ ├── 20160609193515-title-allow-null-up.sql
│ ├── 20160610094821-argument-description-down.sql
│ ├── 20160610094821-argument-description-up.sql
│ ├── 20160612150901-package-type-down.sql
│ ├── 20160612150901-package-type-up.sql
│ ├── 20160612161712-package-type-allow-null-down.sql
│ ├── 20160612161712-package-type-allow-null-up.sql
│ ├── 20160612162625-topic-add-sourceJSON-down.sql
│ ├── 20160612162625-topic-add-sourceJSON-up.sql
│ ├── 20160613085210-comments-down.sql
│ ├── 20160613085210-comments-up.sql
│ ├── 20160614083536-review-model-down.sql
│ ├── 20160614083536-review-model-up.sql
│ ├── 20160621104843-task-views-down.sql
│ ├── 20160621104843-task-views-up.sql
│ ├── 20160624081405-download-statistics-down.sql
│ ├── 20160624081405-download-statistics-up.sql
│ ├── 20160626120528-token-table-down.sql
│ ├── 20160626120528-token-table-up.sql
│ ├── 20160708081226-readme-in-versions-down.sql
│ ├── 20160708081226-readme-in-versions-up.sql
│ ├── 20160711142622-splitted-downloads-down.sql
│ ├── 20160711142622-splitted-downloads-up.sql
│ ├── 20160714072116-downloads-per-day-down.sql
│ ├── 20160714072116-downloads-per-day-up.sql
│ ├── 20160714100838-stringToText-down.sql
│ ├── 20160714100838-stringToText-up.sql
│ ├── 20160714102013-add-dependency-enum-down.sql
│ ├── 20160714102013-add-dependency-enum-up.sql
│ ├── 20160714113658-cascading-delete-of-sections-down.sql
│ ├── 20160714113658-cascading-delete-of-sections-up.sql
│ ├── 20160812141926-BiocDownloads-down.sql
│ ├── 20160812141926-BiocDownloads-up.sql
│ ├── 20160821202039-stars-down.sql
│ ├── 20160821202039-stars-up.sql
│ ├── 20160822080118-examples-down.sql
│ ├── 20160822080118-examples-up.sql
│ ├── 20160830084534-percentiles-down.sql
│ ├── 20160830084534-percentiles-up.sql
│ ├── 20170809033252-parser-version-down.sql
│ ├── 20170809033252-parser-version-up.sql
│ ├── 20170809222533-parsing-jobs-down.sql
│ └── 20170809222533-parsing-jobs-up.sql
├── newrelic.js
├── package-lock.json
├── package.json
├── proxy
└── conf.d
│ └── default.conf
├── tasks
├── README.md
├── config
│ ├── apidoc.js
│ ├── clean.js
│ ├── coffee.js
│ ├── concat.js
│ ├── copy.js
│ ├── cssmin.js
│ ├── jst.js
│ ├── sails-linker.js
│ ├── sails-tasks.js
│ ├── sass.js
│ ├── sync.js
│ ├── uglify.js
│ ├── versioning.js
│ └── watch.js
├── pipeline.js
└── register
│ ├── build.js
│ ├── buildProd.js
│ ├── compileAssets.js
│ ├── default.js
│ ├── linkAssets.js
│ ├── linkAssetsBuild.js
│ ├── linkAssetsBuildProd.js
│ ├── prod.js
│ └── syncAssets.js
├── test
└── test-version-ordering.js
└── views
├── 403.ejs
├── 404.ejs
├── 500.ejs
├── README.md
├── auth
├── login.ejs
├── modalLogin.ejs
└── register.ejs
├── badges
├── downloads_badge.ejs
└── version_badge.ejs
├── campus
└── help.ejs
├── collaborator
└── show.ejs
├── homepage.ejs
├── inner_layout.ejs
├── layout.ejs
├── package
└── show.ejs
├── package_version
├── _details.ejs
├── _header.ejs
├── readme.ejs
├── show.ejs
├── source.ejs
└── vignette.ejs
├── rStudio
├── list_options.ejs
├── make_default.ejs
├── package_not_found.ejs
├── topic_not_found.ejs
├── update.ejs
└── view.ejs
├── rstudio_layout.ejs
├── search
├── function_results.ejs
├── keyword_result.ejs
├── package_results.ejs
└── result.ejs
├── shared
├── _dc_footer.ejs
├── _example.ejs
├── _flash.ejs
├── _footer.ejs
├── _loader.ejs
├── _navbar.ejs
├── _navigation.ejs
├── _percentile.ejs
├── _post_example.ejs
└── _snowplow.ejs
├── task_view
├── _sidebar.ejs
├── index.ejs
└── show.ejs
├── topic
├── _header.ejs
└── show.ejs
├── trends
└── show.ejs
└── user
└── show.ejs
/.dockerignore:
--------------------------------------------------------------------------------
1 | .tmp/
2 | node_modules/
3 | .env
4 | .newrelic_agent.log
5 | Procfile
6 | docker-compose.yml
7 | err.log
8 |
--------------------------------------------------------------------------------
/.ebextensions/10docker.config:
--------------------------------------------------------------------------------
1 | files:
2 | "/etc/cron.d/docker-cleanup":
3 | mode: "000644"
4 | owner: root
5 | group: root
6 | content: "0 * * * * root /var/lib/docker-cleanup/docker_cleanup.sh --actually-run 3"
7 |
8 | "/var/lib/docker-cleanup/docker_cleanup.sh":
9 | mode: "000755"
10 | owner: root
11 | group: root
12 | source: https://bitbucket.org/datamind/docker-cleanup/raw/master/docker_cleanup.sh
13 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
--------------------------------------------------------------------------------
/.env.sample:
--------------------------------------------------------------------------------
1 | ELASTICSEARCH_URL=http://elasticsearch_url
2 | AWS_BUCKET=assets.rdocumentation.org
3 | BASE_URL=http://localhost:3000
4 | PORT=3000
5 |
6 | DATABASE_HOST=127.0.0.1
7 | DATABASE_USERNAME=root
8 | DATABASE_PASSWORD=password
9 | DATABASE_NAME=rdocs
10 | DATABASE_PORT=3306
11 |
12 | REDIS_URL=redis://127.0.0.1:6379
13 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "eslint-config-es5",
3 | "globals": {
4 | "BiocDownloadStatistics": false,
5 | "Package": false,
6 | "PackageVersion": false,
7 | "ElasticSearchService": false,
8 | "Collaborator": false,
9 | "Dependency": false,
10 | "Repository": false,
11 | "Percentile": false,
12 | "PackageService": false,
13 | "PackageVersionService": false,
14 | "DownloadStatistic": false,
15 | "Example": false,
16 | "RedisService": false,
17 | "FlashService": false,
18 | "Utils": false,
19 | "TaskView": false,
20 | "Star": false,
21 | "Promise": false,
22 | "ParsingJob": false,
23 | "sequelize": false,
24 | "Sequelize": false,
25 | "sails": false,
26 | "s3Service": false,
27 | "Review": false,
28 | "es": false
29 | },
30 | "rules": {
31 | "no-shadow": [
32 | 2,
33 | {
34 | "allow": ["packages"]
35 | }
36 | ]
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/.sailsrc:
--------------------------------------------------------------------------------
1 | {
2 | "generators": {
3 | "modules": {}
4 | },
5 |
6 | "hooks": {
7 | "orm": false,
8 | "blueprints": false,
9 | "pubsub": false,
10 | "sockets":false
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:8.17
2 |
3 | RUN sed -i -e 's/deb.debian.org/archive.debian.org/g' -e 's|security.debian.org|archive.debian.org/|g' -e '/stretch-updates/d' /etc/apt/sources.list && \
4 | apt-get update && \
5 | apt-get install -y python3 build-essential
6 |
7 | RUN npm install -g pm2 node-gyp sails grunt bower jake npm-check-updates
8 |
9 | ARG VERSION
10 | ENV VERSION=${VERSION}
11 |
12 | ENV NODE_ENV production
13 |
14 | # use changes to package.json to force Docker not to use the cache
15 | # when we change our application's nodejs dependencies:
16 | ADD package.json /tmp/package.json
17 | ADD package-lock.json /tmp/package-lock.json
18 | RUN cd /tmp && npm install --unsafe-perm --production
19 | RUN mkdir -p /opt/app && cp -a /tmp/node_modules /opt/app/
20 |
21 | # From here we load our application's code in, therefore the previous docker
22 | # "layer" thats been cached will be used if possible
23 | WORKDIR /opt/app
24 | ADD . /opt/app
25 |
26 | #Expose port
27 | EXPOSE 3000
28 |
29 | CMD bash -c "npm start"
30 |
--------------------------------------------------------------------------------
/Dockerrun.aws.json.in:
--------------------------------------------------------------------------------
1 | {
2 | "AWSEBDockerrunVersion": 2,
3 |
4 | "authentication": {
5 | "bucket": "elasticbeanstalk-us-west-1-352211034136",
6 | "key": "resources/dockercfg"
7 | },
8 |
9 | "volumes": [
10 | {
11 | "name": "nginx-proxy-conf",
12 | "host": {
13 | "sourcePath": "/var/app/current/proxy/conf.d"
14 | }
15 | }
16 | ],
17 |
18 | "containerDefinitions": [
19 | {
20 | "name": "rdocsv2",
21 | "image": "dockerhub.datacamp.com:443/rdocsv2:$version",
22 | "environment": [ ],
23 | "essential": true,
24 | "memory": $memory,
25 | "portMappings": [
26 | {
27 | "hostPort": 1337,
28 | "containerPort": 1337
29 | }
30 | ],
31 | "mountPoints": [ ]
32 | },
33 | {
34 | "name": "nginx-proxy",
35 | "image": "nginx",
36 | "essential": true,
37 | "memory": 128,
38 | "portMappings": [
39 | {
40 | "hostPort": 80,
41 | "containerPort": 80
42 | },
43 | {
44 | "hostPort": 81,
45 | "containerPort": 81
46 | }
47 | ],
48 | "links": [
49 | "rdocsv2"
50 | ],
51 | "mountPoints": [
52 | {
53 | "sourceVolume": "nginx-proxy-conf",
54 | "containerPath": "/etc/nginx/conf.d",
55 | "readOnly": true
56 | },
57 | {
58 | "sourceVolume": "awseb-logs-nginx-proxy",
59 | "containerPath": "/var/log/nginx"
60 | }
61 | ]
62 | }
63 | ]
64 | }
65 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 DataCamp Inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/Procfile:
--------------------------------------------------------------------------------
1 | web: NODE_ENV=production PORT=5000 node app.js
2 | dev: NODE_ENV=locals PORT=5000 node app.js
3 | migrate: node -r dotenv/config node_modules/db-migrate/bin/db-migrate up
4 | debug: NODE_ENV=production PORT=5000 node -r dotenv/config node_modules/sails/bin/sails debug
5 | console: node -r dotenv/config node_modules/sails/bin/sails console
6 | clean-task: grunt sails_tasks:authorCleaning
7 | recover-maintainers: grunt sails_tasks:maintainerRecover
8 |
--------------------------------------------------------------------------------
/api/_apidoc.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @apiDefine Timestamps
3 | *
4 | * @apiSuccess {DateTime} created_at Date of creation
5 | * @apiSuccess {DateTime} updated_at Date of last update
6 |
7 | */
8 |
--------------------------------------------------------------------------------
/api/controllers/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datacamp/rdocumentation-app/3642111a3bfcae6c934e8aca4889c005ca90167d/api/controllers/.gitkeep
--------------------------------------------------------------------------------
/api/controllers/AuthController.js:
--------------------------------------------------------------------------------
1 | /**
2 | * AuthController
3 | *
4 | */
5 | var passport = require('passport');
6 | module.exports = {
7 |
8 | login: function(req, res) {
9 | if (req.allParams().rdr) {
10 | req.session.rdr = req.allParams().rdr;
11 | }
12 | res.view();
13 | },
14 |
15 | modalLogin: function(req, res) {
16 | if (req.allParams().rdr) {
17 | req.session.rdr = req.allParams().rdr;
18 | }
19 | res.view('auth/modalLogin.ejs', {layout: null});
20 | },
21 |
22 | register: function(req, res) {
23 | req.session.rdr = req.allParams().rdr;
24 | res.view();
25 | },
26 |
27 | process: function(req, res) {
28 | var successRedirect = req.session.rdr || '/';
29 | passport.authenticate('local', {
30 | failureRedirect: '/login',
31 | failureFlash: 'Invalid Username or password.'
32 | })(req, res, function() {
33 | return res.rstudio_redirect(303, successRedirect);
34 | });
35 | },
36 |
37 | rstudioProcess: function(req, res) {
38 | req.session.rdr || '/';
39 | passport.authenticate('local', function cb(err, user) {
40 | if (err || !user) {
41 | return res.json({status: 'invalid', message: 'Not Logged'});
42 | }
43 | req.logIn(user, function(err) {
44 | if (err) { return res.json({status: "invalid", message: "Not Logged"}) }
45 | return res.json({status :"succes", message: "Logged"})
46 | });
47 | return null;
48 | })(req, res);
49 | },
50 |
51 | modalProcess: function(req, res) {
52 | passport.authenticate('local', function cb(err, user) {
53 | if (err) {
54 | return res.json({ status: 'error' });
55 | }
56 | if (!user) {
57 | return res.json({ status: 'invalid' });
58 | }
59 | req.logIn(user, function(error) {
60 | if (error) { return res.json({ status: 'error' }); }
61 | return res.json({ status: 'success' });
62 | });
63 | return null;
64 | })(req, res);
65 | },
66 |
67 | logout: function(req, res) {
68 | req.session.rdr = null; // Reset the session rdr
69 | req.logout();
70 | res.rstudio_redirect(303, '/');
71 | }
72 | };
73 |
--------------------------------------------------------------------------------
/api/controllers/CampusController.js:
--------------------------------------------------------------------------------
1 | /**
2 | * CampusController
3 | *
4 | * @description :: Server-side logic for the integration of the campus-app with Rdocs
5 | */
6 |
7 | module.exports = {
8 |
9 | /**
10 | * @api {get} /campus/help
11 | * @apiName Get help in the campus-app via Rdocumentation-> needs to redirect or do an ajax request to retrieve the credentials
12 | * @apiGroup Rstudio
13 | *
14 | * @apiParam {String} query
15 | */
16 | help: function(req, res) {
17 | return res.redirect(302, 'https://rdocumentation.org/campus/help/' + req.param('package') + '/' + req.param('topic'));
18 | },
19 |
20 | path: function(req, res) {
21 | res.ok({ path: req.param('path')}, 'campus/help');
22 | }
23 | };
24 |
--------------------------------------------------------------------------------
/api/controllers/HomeController.js:
--------------------------------------------------------------------------------
1 | /**
2 | * HomeController
3 | *
4 | * @description :: Server-side logic for the home page statistics
5 | * @help :: See http://sailsjs.org/#!/documentation/concepts/Controllers
6 | */
7 | var Promise = require('bluebird');
8 | var numeral = require('numeral');
9 |
10 | module.exports = {
11 |
12 | index: function(req, res) {
13 | return res.redirect(302, "https://rdocumentation.org");
14 | },
15 |
16 | status: function(req, res) {
17 | return res.send(200, 'ok');
18 | }
19 | };
20 |
21 |
--------------------------------------------------------------------------------
/api/hooks/aws/index.js:
--------------------------------------------------------------------------------
1 | module.exports = function aws_init(sails) {
2 | global['AWS'] = require('aws-sdk');
3 | AWS.config.setPromisesDependency(require('bluebird'));
4 |
5 | return {
6 |
7 | initialize: function(next) {
8 | var s3 = new AWS.S3();
9 | global['s3'] = s3;
10 |
11 | next();
12 | }
13 |
14 | };
15 | };
16 |
--------------------------------------------------------------------------------
/api/hooks/elasticsearch/index.js:
--------------------------------------------------------------------------------
1 | module.exports = function es_init(sails) {
2 | global['Elasticsearch'] = require('elasticsearch');
3 |
4 | return {
5 |
6 | initialize: function(next) {
7 | var config = sails.config[this.configKey];
8 | var host = config.host;
9 | if (host === null) {
10 | throw new Error('Host not found in config/elasticsearch');
11 | }
12 |
13 | var es = new Elasticsearch.Client(config);
14 | global['es'] = es;
15 |
16 | next();
17 | }
18 |
19 | };
20 | };
21 |
--------------------------------------------------------------------------------
/api/hooks/redis/index.js:
--------------------------------------------------------------------------------
1 | var bluebird = require('bluebird');
2 |
3 | module.exports = function redis_init(sails) {
4 | global['Redis'] = require('redis');
5 |
6 | return {
7 |
8 | initialize: function(next) {
9 | var config = sails.config[this.configKey];
10 | var url = config.url;
11 | var options = config.options;
12 |
13 | bluebird.promisifyAll(Redis.RedisClient.prototype);
14 | bluebird.promisifyAll(Redis.Multi.prototype);
15 |
16 | var redisClient;
17 | if (url) {
18 | redisClient = Redis.createClient(url, options);
19 | } else {
20 | redisClient = Redis.createClient(options);
21 | }
22 |
23 | global['RedisClient'] = redisClient;
24 |
25 | if(config.logging) {
26 | redisClient.on('error', function (err) {
27 | console.log('Error ' + err);
28 | });
29 | }
30 |
31 | // redisClient.flushdb();
32 | // redisClient.flushall();
33 | if(process.env.NODE_ENV === 'production') {
34 | redisClient.flushdb();
35 | redisClient.flushall();
36 | }
37 |
38 | next();
39 | }
40 |
41 | };
42 | };
43 |
--------------------------------------------------------------------------------
/api/hooks/worker/index.js:
--------------------------------------------------------------------------------
1 | var cron = require('node-cron');
2 |
3 | module.exports = function worker(sails) {
4 |
5 | return {
6 |
7 | initialize: function (next) {
8 |
9 | if (process.env.NODE_ENV === 'worker') {
10 | cron.schedule('0 */12 * * *', function() {
11 | console.log('Indexing latest stats');
12 | CronService.indexDownloadCounts().then(function(resp) {
13 | console.log('Latest stats indexed.');
14 | }).catch({ message: 'empty' }, function() {
15 | console.log('No stats for this time range yet');
16 | });
17 | });
18 |
19 | cron.schedule('30 */12 * * *', function() {
20 | console.log('Updating percentiles');
21 | CronService.updatePercentile().then(function(resp) {
22 | console.log("Updated percentiles");
23 | });
24 | });
25 | }
26 | next();
27 | }
28 |
29 | };
30 | };
31 |
--------------------------------------------------------------------------------
/api/models/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datacamp/rdocumentation-app/3642111a3bfcae6c934e8aca4889c005ca90167d/api/models/.gitkeep
--------------------------------------------------------------------------------
/api/models/ApiToken.js:
--------------------------------------------------------------------------------
1 | /**
2 | * ApiToken.js
3 | *
4 | * @description :: TODO: You might write a short summary of how this model works and what it represents here.
5 | * @docs :: http://sailsjs.org/documentation/concepts/models-and-orm/models
6 | */
7 |
8 | module.exports = {
9 |
10 | attributes: {
11 |
12 | token: {
13 | type: Sequelize.STRING,
14 | unique: true,
15 | allowNull: false
16 | },
17 |
18 | can_create: {
19 | type: Sequelize.BOOLEAN,
20 | allowNull: false
21 | },
22 |
23 | can_update: {
24 | type: Sequelize.BOOLEAN,
25 | allowNull: false
26 | },
27 |
28 | can_delete: {
29 | type: Sequelize.BOOLEAN,
30 | allowNull: false
31 | }
32 |
33 | },
34 |
35 | options: {
36 | underscored: true,
37 | timestamps: false
38 | }
39 | };
40 |
41 |
--------------------------------------------------------------------------------
/api/models/Argument.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Argument.js
3 | *
4 | * @description :: TODO: You might write a short summary of how this model works and what it represents here.
5 | * @docs :: http://sailsjs.org/documentation/concepts/models-and-orm/models
6 | */
7 |
8 | module.exports = {
9 |
10 | attributes: {
11 |
12 | description: {
13 | type: Sequelize.TEXT,
14 | },
15 |
16 | name: {
17 | type: Sequelize.STRING,
18 | allowNull: false
19 | }
20 |
21 | },
22 |
23 | options: {
24 | underscored: true,
25 | timestamps: false
26 | }
27 | };
28 |
29 |
--------------------------------------------------------------------------------
/api/models/BiocDownloadStatistics.js:
--------------------------------------------------------------------------------
1 | /**
2 | * BiocDownloadStatistic.js
3 | *
4 | * @description :: downloadstatistics for the bioconductor packages
5 | * @docs :: http://sailsjs.org/documentation/concepts/models-and-orm/models
6 | */
7 |
8 | module.exports = {
9 |
10 | attributes: {
11 |
12 | package_name: {
13 | type: Sequelize.STRING,
14 | allowNull: false
15 | },
16 |
17 | date: {
18 | type: Sequelize.DATE,
19 | allowNull: false
20 | },
21 |
22 | distinct_ips: {
23 | type: Sequelize.INTEGER,
24 | allowNull: false
25 | },
26 | downloads: {
27 | type: Sequelize.INTEGER,
28 | allowNull: false
29 | }
30 | },
31 |
32 | associations: function() {
33 | BiocDownloadStatistics.belongsTo(Package,
34 | {
35 | as: 'package',
36 | foreignKey: {
37 | allowNull: false,
38 | name: 'package_name',
39 | as: 'package'
40 | },
41 | onDelete: 'CASCADE'
42 | });
43 | },
44 |
45 |
46 | options: {
47 | underscored: true,
48 |
49 | indexes: [
50 | {
51 | type: 'UNIQUE',
52 | fields: ['package_name', 'date' ]
53 | }
54 | ],
55 | classMethods:{
56 | lastYearsSplittedDownloadsPerMonth:function(package_name,years){
57 | return BiocDownloadStatistics.findAll({
58 | where:{
59 | package_name:package_name,
60 | date:{
61 | $gte:new Date(new Date()-years*365*24*60*60*1000),
62 | $lt:new Date()
63 | }
64 | },
65 | });
66 | },
67 | getMonthlySplittedDownloads:function(package_name){
68 | return BiocDownloadStatistics.findAll({
69 | where:{
70 | package_name:package_name,
71 | date:{
72 | $gte: sequelize.literal("current_date() - interval '1' month")
73 | }
74 | },
75 | });
76 | }
77 | }
78 | }
79 | };
80 |
81 |
--------------------------------------------------------------------------------
/api/models/Example.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Example.js
3 | *
4 | * @description :: TODO: You might write a short summary of how this model works and what it represents here.
5 | * @docs :: http://sailsjs.org/documentation/concepts/models-and-orm/models
6 | */
7 |
8 | module.exports = {
9 |
10 | attributes: {
11 |
12 | example: {
13 | type: Sequelize.TEXT,
14 | allowNull: false
15 | }
16 |
17 | },
18 |
19 | associations: function() {
20 |
21 | Example.belongsTo(Topic, {
22 | foreignKey: 'topic_id',
23 | as: 'topic'
24 | });
25 |
26 | Example.belongsTo(User, {
27 | foreignKey: 'user_id',
28 | as: 'user'
29 | });
30 | },
31 |
32 |
33 | options: {
34 | underscored: true,
35 |
36 | classMethods: {
37 | findPackageExamples: function(packageName, topic) {
38 | return Example.findAll({
39 | include:[
40 | { model: Topic, as: 'topic', where: { name: topic }, attributes:['package_version_id'], required:true,
41 | include: [{ model: PackageVersion, as: 'package_version', where: { package_name: packageName }, required: true }]
42 | },
43 | { model: User, as: 'user', attributes: ['username'] }
44 | ],
45 |
46 | });
47 | }
48 | }
49 | }
50 | };
51 |
52 |
--------------------------------------------------------------------------------
/api/models/ParsingJob.js:
--------------------------------------------------------------------------------
1 | /**
2 | * ParsingJob.js
3 | *
4 | * @description :: TODO: You might write a short summary of how this model works and what it represents here.
5 | * @docs :: http://sailsjs.org/documentation/concepts/models-and-orm/models
6 | */
7 |
8 | module.exports = {
9 | autoCreatedAt: false,
10 | autoUpdatedAt: false,
11 | attributes: {
12 | package_name: {
13 | type: Sequelize.STRING,
14 | allowNull: false
15 | },
16 |
17 | package_version: {
18 | type: Sequelize.STRING,
19 | allowNull: false
20 | },
21 |
22 | parser_version: {
23 | type: Sequelize.INTEGER
24 | },
25 |
26 | parsed_at: {
27 | type: Sequelize.DATE,
28 | allowNull: false
29 | },
30 |
31 | parsing_status: {
32 | type: Sequelize.TEXT,
33 | allowNull: false
34 | },
35 |
36 | error: {
37 | type: Sequelize.TEXT,
38 | },
39 |
40 | },
41 | options: {
42 | indexes: [
43 | {
44 | type: 'UNIQUE',
45 | fields: ['package_name', 'package_version']
46 | }
47 | ],
48 | timestamps: false
49 | },
50 | }
51 |
--------------------------------------------------------------------------------
/api/models/Percentile.js:
--------------------------------------------------------------------------------
1 | /**
2 | * DownloadStatistic.js
3 | *
4 | * @description :: TODO: You might write a short summary of how this model works and what it represents here.
5 | * @docs :: http://sailsjs.org/documentation/concepts/models-and-orm/models
6 | */
7 |
8 | module.exports = {
9 |
10 | attributes: {
11 |
12 | id: {
13 | type: Sequelize.INTEGER,
14 | primaryKey: true,
15 | allowNull: false,
16 | unique: true
17 | },
18 |
19 | percentile: {
20 | type: Sequelize.DOUBLE,
21 | allowNull: false,
22 | unique: true
23 | },
24 |
25 | value: {
26 | type: Sequelize.INTEGER,
27 | allowNull: false
28 | }
29 |
30 | },
31 |
32 |
33 | options: {
34 | underscored: true
35 | }
36 | };
37 |
--------------------------------------------------------------------------------
/api/models/Repository.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Repository.js
3 | *
4 | * @description :: TODO: You might write a short summary of how this model works and what it represents here.
5 | * @docs :: http://sailsjs.org/documentation/concepts/models-and-orm/models
6 | */
7 |
8 | module.exports = {
9 |
10 | attributes: {
11 | name: {
12 | type: Sequelize.STRING,
13 | required: true,
14 | }
15 | },
16 |
17 | options: {
18 | underscored: true,
19 | timestamps: false
20 | }
21 | };
22 |
23 |
--------------------------------------------------------------------------------
/api/models/Review.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Review.js
3 | *
4 | * @description :: TODO: You might write a short summary of how this model works and what it represents here.
5 | * @docs :: http://sailsjs.org/documentation/concepts/models-and-orm/models
6 | */
7 |
8 | module.exports = {
9 |
10 | attributes: {
11 |
12 | rating: {
13 | type: Sequelize.INTEGER,
14 | allowNull: false,
15 | validate: { min: 1, max: 5 }
16 | },
17 |
18 | title: {
19 | type: Sequelize.STRING,
20 | allowNull: true
21 | },
22 |
23 | text: {
24 | type: Sequelize.TEXT,
25 | allowNull: true
26 | },
27 |
28 | reviewable: Sequelize.STRING,
29 |
30 | reviewable_id: {
31 | type: Sequelize.INTEGER,
32 | allowNull: false
33 | },
34 |
35 | user_id: {
36 | type: Sequelize.INTEGER,
37 | allowNull: false
38 | }
39 | },
40 |
41 | associations: function() {
42 | Review.belongsTo(PackageVersion, {
43 | foreignKey: 'reviewable_id',
44 | constraints: false,
45 | as: 'package_version'
46 | });
47 |
48 | Review.belongsTo(Topic, {
49 | foreignKey: 'reviewable_id',
50 | constraints: false,
51 | as: 'topic'
52 | });
53 |
54 | Review.belongsTo(User, {
55 | foreignKey: 'user_id',
56 | as: 'user'
57 | });
58 | },
59 |
60 | options: {
61 | indexes: [
62 | {
63 | type: 'UNIQUE',
64 | fields: ['user_id', 'reviewable', 'reviewable_id']
65 | }
66 | ],
67 | underscored: true
68 | }
69 | };
70 |
71 |
--------------------------------------------------------------------------------
/api/models/Section.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Section.js
3 | *
4 | * @description :: TODO: You might write a short summary of how this model works and what it represents here.
5 | * @docs :: http://sailsjs.org/documentation/concepts/models-and-orm/models
6 | */
7 |
8 | module.exports = {
9 |
10 | attributes: {
11 |
12 | description: {
13 | type: Sequelize.TEXT,
14 | },
15 |
16 | name: {
17 | type: Sequelize.STRING,
18 | allowNull: false
19 | }
20 |
21 | },
22 |
23 |
24 | associations: function() {
25 |
26 | },
27 |
28 | options: {
29 | underscored: true,
30 | timestamps: false
31 | }
32 | };
33 |
34 |
--------------------------------------------------------------------------------
/api/models/Star.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 |
3 |
4 |
5 | attributes: {
6 |
7 | user_id: {
8 | type: Sequelize.INTEGER,
9 | allowNull: false,
10 | primaryKey: true
11 | },
12 |
13 | package_name: {
14 | type: Sequelize.STRING,
15 | allowNull: false,
16 | primaryKey: true
17 | }
18 |
19 | },
20 |
21 |
22 | associations: function() {
23 |
24 | },
25 |
26 | options: {
27 | underscored: true
28 | }
29 |
30 |
31 | };
32 |
--------------------------------------------------------------------------------
/api/models/Tag.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Tag.js
3 | *
4 | * @description :: TODO: You might write a short summary of how this model works and what it represents here.
5 | * @docs :: http://sailsjs.org/documentation/concepts/models-and-orm/models
6 | */
7 |
8 | module.exports = {
9 |
10 | attributes: {
11 |
12 | name: {
13 | type: Sequelize.STRING,
14 | allowNull: false,
15 | unique: true
16 | }
17 |
18 | },
19 |
20 | associations: function() {
21 | Tag.belongsToMany(Topic, { as: 'tags', foreignKey: 'tag_id', through: 'TopicTags', timestamps: false});
22 | },
23 |
24 | options: {
25 | underscored: true,
26 | timestamps: false
27 | }
28 | };
29 |
30 |
--------------------------------------------------------------------------------
/api/models/TaskView.js:
--------------------------------------------------------------------------------
1 | /**
2 | * TaskView.js
3 | *
4 | * @description :: TODO: You might write a short summary of how this model works and what it represents here.
5 | * @docs :: http://sailsjs.org/documentation/concepts/models-and-orm/models
6 | */
7 |
8 | module.exports = {
9 |
10 | attributes: {
11 | name: {
12 | type: Sequelize.STRING,
13 | unique: true,
14 | allowNull: false
15 | },
16 |
17 | url: {
18 | type: Sequelize.STRING,
19 | allowNull: false
20 | }
21 |
22 | },
23 | associations: function() {
24 |
25 | TaskView.belongsToMany(Package,
26 | {
27 | as: 'packages',
28 | through: 'TaskViewPackages',
29 | foreignKey: 'task_id',
30 | timestamps: false
31 | });
32 | },
33 |
34 | options: {
35 | underscored: true
36 | }
37 | };
38 |
39 |
--------------------------------------------------------------------------------
/api/policies/api_auth.js:
--------------------------------------------------------------------------------
1 | var passport = require('passport');
2 | /**
3 | * sessionAuth
4 | *
5 | * @module :: Policy
6 | * @description :: Simple policy to check authorization through token
7 | *
8 | */
9 | module.exports = function(req, res, next) {
10 | if(req.method === 'GET' || req.method === 'HEAD') return next();
11 | passport.authenticate('bearer', function(err, authorizations, info) {
12 | if (err) { return next(err); }
13 | if (!authorizations) { return res.send(401, info); }
14 | else {
15 | var authorized;
16 | switch (req.method) {
17 | case 'POST':
18 | authorized = authorizations.can_create === true;
19 | break;
20 | case 'PUT':
21 | authorized = authorizations.can_update === true;
22 | break;
23 | case 'DELETE':
24 | authorized = authorizations.can_delete === true;
25 | break;
26 | }
27 | if (authorized) {
28 | next();
29 | } else {
30 | res.send(403);
31 | }
32 | }
33 | })(req, res, next);
34 | };
35 |
--------------------------------------------------------------------------------
/api/policies/flash.js:
--------------------------------------------------------------------------------
1 | var _ = require('lodash');
2 |
3 | // flash.js policy
4 | module.exports = function(req, res, next) {
5 | res.locals.messages = { success: [], error: [], warning: [] };
6 |
7 | if(!req.session.messages) {
8 | req.session.messages = { success: [], error: [], warning: [] };
9 | return next();
10 | }
11 |
12 | if(req.session.flash) {
13 | res.locals.messages = _.clone(_.merge(req.session.messages, req.session.flash));
14 | req.session.flash = {};
15 | } else {
16 | res.locals.messages = _.clone(req.session.messages);
17 | }
18 |
19 | // Clear flash
20 | req.session.messages = { success: [], error: [], warning: [] };
21 |
22 | return next();
23 | };
24 |
--------------------------------------------------------------------------------
/api/policies/sessionAuth.js:
--------------------------------------------------------------------------------
1 | /**
2 | * sessionAuth
3 | *
4 | * @module :: Policy
5 | * @description :: Simple policy to allow any authenticated user
6 | * Assumes that your login action in one of your controllers sets `req.session.authenticated = true;`
7 | * @docs :: http://sailsjs.org/#!/documentation/concepts/Policies
8 | *
9 | */
10 | module.exports = function(req, res, next) {
11 |
12 | // User is allowed, proceed to the next policy,
13 | // or if this is the last policy, the controller
14 | if (req.isAuthenticated()) {
15 | return next();
16 | }
17 |
18 | // User is not allowed
19 | // (default res.forbidden() behavior can be overridden in `config/403.js`)
20 | return res.forbidden('You are not permitted to perform this action.');
21 | };
22 |
--------------------------------------------------------------------------------
/api/responses/created.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 201 (CREATED) Response
3 | *
4 | * Usage:
5 | * return res.created();
6 | * return res.created(data);
7 | * return res.created(data, 'auth/login');
8 | *
9 | * @param {Object} data
10 | * @param {String|Object} options
11 | * - pass string to render specified view
12 | */
13 |
14 | module.exports = function created (data, options) {
15 |
16 | // Get access to `req`, `res`, & `sails`
17 | var req = this.req;
18 | var res = this.res;
19 | var sails = req._sails;
20 |
21 | sails.log.silly('res.created() :: Sending 201 ("CREATED") response');
22 |
23 | // Set status code
24 | res.status(201);
25 |
26 | // If appropriate, serve data as JSON(P)
27 | // If views are disabled, revert to json
28 | if (req.wantsJSON || sails.config.hooks.views === false) {
29 | return res.jsonx(data);
30 | }
31 |
32 | // If second argument is a string, we take that to mean it refers to a view.
33 | // If it was omitted, use an empty object (`{}`)
34 | options = (typeof options === 'string') ? { view: options } : options || {};
35 |
36 | // Attempt to prettify data for views, if it's a non-error object
37 | var viewData = data;
38 | if (!(viewData instanceof Error) && 'object' == typeof viewData) {
39 | try {
40 | viewData = require('util').inspect(data, {depth: null});
41 | }
42 | catch(e) {
43 | viewData = undefined;
44 | }
45 | }
46 |
47 | // If a view was provided in options, serve it.
48 | // Otherwise try to guess an appropriate view, or if that doesn't
49 | // work, just send JSON.
50 | if (options.view) {
51 | return res.view(options.view, { data: viewData, title: 'Created' });
52 | }
53 |
54 | // If no second argument provided, try to serve the implied view,
55 | // but fall back to sending JSON(P) if no view can be inferred.
56 | else return res.guessView({ data: viewData, title: 'Created' }, function couldNotGuessView () {
57 | return res.jsonx(data);
58 | });
59 |
60 | };
61 |
--------------------------------------------------------------------------------
/api/responses/ok.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 200 (OK) Response
3 | *
4 | * Usage:
5 | * return res.ok();
6 | * return res.ok(data);
7 | * return res.ok(data, 'auth/login');
8 | *
9 | * @param {Object} data
10 | * @param {String|Object} options
11 | * - pass string to render specified view
12 | */
13 |
14 | module.exports = function sendOK (data, options) {
15 |
16 | // Get access to `req`, `res`, & `sails`
17 | var req = this.req;
18 | var res = this.res;
19 | var sails = req._sails;
20 |
21 | sails.log.silly('res.ok() :: Sending 200 ("OK") response');
22 |
23 | // Set status code
24 | res.status(200);
25 |
26 | if(req.path.startsWith('/api/')) {
27 | return res.jsonx(data);
28 | }
29 |
30 | // If appropriate, serve data as JSON(P)
31 | // If views are disabled, revert to json
32 | // if (req.wantsJSON || sails.config.hooks.views === false) {
33 | // return res.jsonx(data);
34 | // }
35 |
36 | // If second argument is a string, we take that to mean it refers to a view.
37 | // If it was omitted, use an empty object (`{}`)
38 | options = (typeof options === 'string') ? { view: options } : options || {};
39 |
40 | // If a view was provided in options, serve it.
41 | // Otherwise try to guess an appropriate view, or if that doesn't
42 | // work, just send JSON.
43 | if (options.view) {
44 | return res.view(options.view, { data: data, cache: true });
45 | }
46 |
47 | // If no second argument provided, try to serve the implied view,
48 | // but fall back to sending JSON(P) if no view can be inferred.
49 | else return res.guessView({ data: viewData }, function couldNotGuessView () {
50 | return res.jsonx(data);
51 | });
52 |
53 | };
54 |
--------------------------------------------------------------------------------
/api/responses/rstudio_redirect.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 303 (See Other) Handler for Rstudio-api (passes parameters)
3 | *
4 | * Usage:
5 | * return res.rstudio_redirect(uri)
6 | *
7 | * e.g.:
8 | * ```
9 | * return res.rstudio_redirect(uri)
10 | * ```
11 | *
12 | * NOTE:
13 | * This response is needed if the viewer_pane parameter, the Rstudio_port and/or the session_shared_secret for Rstudio or important
14 | * This is for example the case when refering to topics, as topic/show.ejs has viewer_pane-specifid code.
15 | */
16 |
17 | module.exports = function rstudio_redirect(code,uri) {
18 |
19 | // Get access to `req`, `res`, & `sails`
20 | var req = this.req;
21 | var res = this.res;
22 | var sails = req._sails;
23 |
24 | var fromRstudio = req.headers['x-rstudio-ajax'] === 'true';
25 | var urlParams= ['viewer_pane'].map(function(p) {
26 | return req.param(p) ? p + '=' + encodeURIComponent(req.param(p)) : '';
27 | }).filter(function(p) {
28 | return p !== '';
29 | }).join('&');
30 | if(uri.indexOf('?')>0){
31 | var redirectURL = uri.substring(0,uri.indexOf('?'))
32 | }
33 | else{
34 | var redirectURL = uri
35 | }
36 |
37 |
38 | sails.log.silly('res.rstudio_redirect() :: Sending '+code+ ' (redirect) response');
39 |
40 | if(fromRstudio) {
41 | res.location(redirectURL);
42 | res.set('X-RStudio-Redirect', redirectURL);
43 | res.json({ status: 'success'});
44 | } else {
45 | res.redirect(code,uri+ (urlParams.length > 0 ? "?"+ urlParams : ""));
46 | }
47 |
48 | };
49 |
--------------------------------------------------------------------------------
/api/services/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datacamp/rdocumentation-app/3642111a3bfcae6c934e8aca4889c005ca90167d/api/services/.gitkeep
--------------------------------------------------------------------------------
/api/services/CronService.js:
--------------------------------------------------------------------------------
1 | // CronService.js - in api/services
2 |
3 | /**
4 | * All async tasks
5 | */
6 |
7 | var Promise = require('bluebird');
8 |
9 | module.exports = {
10 |
11 | indexDownloadCounts: function () {
12 | return DownloadStatistic.getNotIndexedDates().then(function (days) {
13 | return days.map(function (day) {
14 | var date = new Date(day.absents);
15 | return date;
16 | });
17 | }).then(function (diffs) {
18 | if (diffs.length <= 0) {
19 | console.log("Nothing new");
20 | return res.send(200, "done");
21 | }
22 | DownloadStatsService.reverseDependenciesCache = {}; //clean old cache
23 | return Promise.map(diffs, function (day) {
24 | console.log(`Started indexing for ${day}.`);
25 | return Promise.promisify(DownloadStatsService.getDailyDownloads)(day)
26 | .catch({ message: "empty" }, function () {
27 | console.log("No stats for this time range yet");
28 | return 1;
29 | })
30 | .catch(function (err) {
31 | console.log("Undefined response");
32 | return 1;
33 | });
34 | }, { concurrency: 1 })
35 | .then(function (result) {
36 | console.log("Finished indexing splitted stats");
37 | DownloadStatsService.reverseDependenciesCache = {}; //clean cache
38 | })
39 |
40 | }).catch(function (err) {
41 | console.error(err);
42 | });
43 |
44 | },
45 |
46 | updatePercentile: function () {
47 | return DownloadStatsService.updateLastMonthPercentiles().then(function () {
48 | console.log("Finished updating percentiles");
49 | }).catch(function (err) {
50 | console.error(err);
51 | });
52 | }
53 |
54 | };
55 |
56 |
57 |
--------------------------------------------------------------------------------
/api/services/FlashService.js:
--------------------------------------------------------------------------------
1 | // FlashService.js
2 | module.exports = {
3 | success: function(req, message) {
4 | req.session.messages['success'].push(message);
5 | },
6 | warning: function(req, message) {
7 | req.session.messages['warning'].push(message);
8 | },
9 | error: function(req, message) {
10 | req.session.messages['error'].push(message);
11 | }
12 | };
13 |
--------------------------------------------------------------------------------
/api/services/PackageVersionService.js:
--------------------------------------------------------------------------------
1 | function getSourceList(res, package_name, version) {
2 | var key = 'rdocs_source_' + package_name + '_' + version + '_tree';
3 | return RedisService.getJSONFromCache(key, res, RedisService.DAILY, function () {
4 | var prefix = "rpackages/unarchived/" + package_name + "/" + version + "/R/";
5 | return s3Service.getAllFilesInFolder(prefix, true)
6 | .then(function (data) {
7 | var url = process.env.BASE_URL + "/packages/" + package_name + "/versions/" + version
8 | + "/source/";
9 |
10 | var list = data.list.map(function (item) {
11 | var name = item.Key.substring(prefix.length, item.Key.length);
12 | var parts = name.split('/');
13 | return {
14 | 'name': name,
15 | 'parts': parts
16 | }
17 | });
18 | var data = {};
19 | for (var item of list) {
20 | setObjectValue(data, item.parts, item.name);
21 | }
22 | var tree = [];
23 | toTreeStructure(tree, data);
24 | return {
25 | tree: tree
26 | }
27 | });
28 |
29 | });
30 | }
31 |
32 | function setObjectValue(obj, indices, value) {
33 | if (indices.length == 1)
34 | return obj[indices[0]] = value;
35 | else if (indices.length == 0)
36 | return obj;
37 | else {
38 | if (obj[indices[0]] === undefined)
39 | obj[indices[0]] = {};
40 | return setObjectValue(obj[indices[0]], indices.slice(1), value);
41 | }
42 | }
43 |
44 | function toTreeStructure(tree, data) {
45 | if (typeof (data) !== 'object')
46 | return;
47 | for (var key of Object.keys(data)) {
48 | var nodes = [];
49 | toTreeStructure(nodes, data[key]);
50 | var node = {
51 | text: key,
52 | selectable: nodes.length === 0,
53 | state: {
54 | selected: false
55 | }
56 | };
57 | if (nodes.length === 0)
58 | node.href = data[key];
59 | else
60 | node.nodes = nodes;
61 | tree.push(node);
62 | }
63 | }
64 | module.exports = {
65 | getSourceList,
66 | setObjectValue,
67 | toTreeStructure
68 | }
69 |
--------------------------------------------------------------------------------
/api/services/RedisService.js:
--------------------------------------------------------------------------------
1 | // RedisService.js - in api/services
2 |
3 | /**
4 | * Abstract away boilerplate code to work with Redis
5 | */
6 |
7 | var Promise = require('bluebird');
8 |
9 |
10 | module.exports = {
11 |
12 | DAILY: 86400,
13 |
14 | WEEKLY: 604800,
15 |
16 | // missFn must be a function that return either a json or a Promise resolving to a json
17 | // it will be executed if nothing is found in cache
18 | getJSONFromCache: function(key, res, expire, missFn) {
19 | var env = process.env.AWS_ENV || 'dev';
20 | //if (env === 'dev') return Promise.resolve(missFn());
21 | key = env + '_' + key;
22 | return RedisClient.getAsync(key).then(function(response){
23 | if(res) res.set('Cache-Control', 'max-age=' + expire);
24 | if(response) {
25 | var json = JSON.parse(response);
26 | json.fromCache = true;
27 | if(res) res.set('X-Cache', 'hit');
28 | return json;
29 | } else {
30 | return Promise.resolve(missFn()).then(function(value) {
31 | if (value) RedisClient.set(key, JSON.stringify(value));
32 | if(res) res.set('X-Cache', 'miss');
33 | RedisClient.expire(key, expire);
34 | return value;
35 | });
36 | }
37 | });
38 | },
39 |
40 | del: function(key) {
41 | var env = process.env.AWS_ENV || 'dev';
42 | key = env + '_' + key;
43 | RedisClient.del(key);
44 | },
45 |
46 | delPrefix: function(prefix){
47 | var env = process.env.AWS_ENV || 'dev';
48 | var key = env + '_' + prefix + '*';
49 | RedisClient.keys(key,function(err,rows){
50 | Promise.map(rows,function(row){
51 | RedisClient.del(row);
52 | });
53 | })
54 | },
55 |
56 | invalidateTopicById: function(id) {
57 | RedisService.del('view_topic_' + id);
58 | Topic.findById(id, { include: [{model: PackageVersion, as: 'package_version'}]}).then(function(topic) {
59 | if (topic) {
60 | RedisService.del('view_topic_' + topic.package_version.package_name + '_' + topic.package_version.version + '_' + topic.name);
61 | }
62 | });
63 | }
64 |
65 |
66 | };
67 |
--------------------------------------------------------------------------------
/apidoc.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Rdocumentation JSON API",
3 | "version": "0.1.0",
4 | "title": "Rdocumentation JSON API",
5 | "url" : "http://rdocumentation.org/api"
6 | }
7 |
--------------------------------------------------------------------------------
/app.js:
--------------------------------------------------------------------------------
1 | /**
2 | * app.js
3 | *
4 | * Use `app.js` to run your app without `sails lift`.
5 | * To start the server, run: `node app.js`.
6 | *
7 | * This is handy in situations where the sails CLI is not relevant or useful.
8 | *
9 | * For example:
10 | * => `node app.js`
11 | * => `forever start app.js`
12 | * => `node debug app.js`
13 | * => `modulus deploy`
14 | * => `heroku scale`
15 | *
16 | *
17 | * The same command-line arguments are supported, e.g.:
18 | * `node app.js --silent --port=80 --prod`
19 | */
20 |
21 | // Ensure we're in the project directory, so relative paths work as expected
22 | // no matter where we actually lift from.
23 | process.chdir(__dirname);
24 | // Ensure a "sails" can be located:
25 | //var newrelic = require('newrelic');
26 | require('dotenv').config({silent: true});
27 |
28 | (function() {
29 | var sails;
30 | try {
31 | sails = require('sails');
32 | } catch (e) {
33 | console.error('To run an app using `node app.js`, you usually need to have a version of `sails` installed in the same directory as your app.');
34 | console.error('To do that, run `npm install sails`');
35 | console.error('');
36 | console.error('Alternatively, if you have sails installed globally (i.e. you did `npm install -g sails`), you can use `sails lift`.');
37 | console.error('When you run `sails lift`, your app will still use a local `./node_modules/sails` dependency if it exists,');
38 | console.error('but if it doesn\'t, the app will run with the global sails instead!');
39 | return;
40 | }
41 |
42 | // Try to get `rc` dependency
43 | var rc;
44 | try {
45 | rc = require('rc');
46 | } catch (e0) {
47 | try {
48 | rc = require('sails/node_modules/rc');
49 | } catch (e1) {
50 | console.error('Could not find dependency: `rc`.');
51 | console.error('Your `.sailsrc` file(s) will be ignored.');
52 | console.error('To resolve this, run:');
53 | console.error('npm install rc --save');
54 | rc = function () { return {}; };
55 | }
56 | }
57 |
58 |
59 | // Start server
60 | sails.lift(rc('sails'));
61 | })();
62 |
--------------------------------------------------------------------------------
/assets/css/bootstrap-treeview.css:
--------------------------------------------------------------------------------
1 | /* =========================================================
2 | * bootstrap-treeview.css v1.2.0
3 | * =========================================================
4 | * Copyright 2013 Jonathan Miles
5 | * Project URL : http://www.jondmiles.com/bootstrap-treeview
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * you may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | * ========================================================= */
19 |
20 | .treeview .list-group-item {
21 | cursor: pointer;
22 | }
23 |
24 | .treeview span.indent {
25 | margin-left: 10px;
26 | margin-right: 10px;
27 | }
28 |
29 | .treeview span.icon {
30 | width: 12px;
31 | margin-right: 5px;
32 | }
33 |
34 | .treeview .node-disabled {
35 | color: silver;
36 | cursor: not-allowed;
37 | }
--------------------------------------------------------------------------------
/assets/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datacamp/rdocumentation-app/3642111a3bfcae6c934e8aca4889c005ca90167d/assets/favicon.ico
--------------------------------------------------------------------------------
/assets/images/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datacamp/rdocumentation-app/3642111a3bfcae6c934e8aca4889c005ca90167d/assets/images/.gitkeep
--------------------------------------------------------------------------------
/assets/images/GitHub-Mark-32px.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datacamp/rdocumentation-app/3642111a3bfcae6c934e8aca4889c005ca90167d/assets/images/GitHub-Mark-32px.png
--------------------------------------------------------------------------------
/assets/images/logo-dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datacamp/rdocumentation-app/3642111a3bfcae6c934e8aca4889c005ca90167d/assets/images/logo-dark.png
--------------------------------------------------------------------------------
/assets/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datacamp/rdocumentation-app/3642111a3bfcae6c934e8aca4889c005ca90167d/assets/images/logo.png
--------------------------------------------------------------------------------
/assets/images/placeholder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datacamp/rdocumentation-app/3642111a3bfcae6c934e8aca4889c005ca90167d/assets/images/placeholder.png
--------------------------------------------------------------------------------
/assets/js/helpers/boot.js:
--------------------------------------------------------------------------------
1 | (function($){
2 |
3 | $(window).on("load", function() {
4 | window.boot();
5 | });
6 |
7 | window.boot = function() {
8 | bootDownloadStats();
9 | bootListTableFiltering();
10 | bootToggle();
11 | bootCollaborator();
12 | bootTaskViews();
13 | bootRstudioNavigator();
14 | bootAsyncLoader();
15 | bootPackage();
16 | bootExamples();
17 | bootTrending();
18 | bootUser();
19 | bootSource();
20 | bindUpvoteButton();
21 | window.bindFade();
22 | window.counter();
23 | window.dcFooter();
24 | hljs.initHighlighting.called = false;
25 | hljs.initHighlighting();
26 | };
27 |
28 | })($jq);
29 |
30 |
--------------------------------------------------------------------------------
/assets/js/helpers/list-table-filtering.js:
--------------------------------------------------------------------------------
1 | (function($) {
2 |
3 | var addExpr = function(){
4 | // Make :eq case insensitive
5 | $.expr[':'].containsRaw = function(a, i, m) {
6 | return $(a).text().toUpperCase()
7 | .indexOf(m[3].toUpperCase()) >= 0;
8 | };
9 | };
10 |
11 | function filterFunction(index) {
12 | return function () {
13 | addExpr();
14 | var indexColumn = index, // Search for values in the first column
15 | searchWords = this.value.split(" "),
16 | rows = $("#filterableItems").find("tr").not(".no-results");
17 |
18 | rows.hide();
19 | //Recusively filter the jquery object to get results.
20 | var filteredRows = rows.filter(function (i, v) {
21 | var $t = $(this).children(":eq("+indexColumn+")");
22 | for (var d = 0; d < searchWords.length; ++d) {
23 | if ($t.is(":containsRaw('" + searchWords[d].toLowerCase() + "')")) {
24 | return true;
25 | }
26 | }
27 | return false;
28 | });
29 |
30 | if(filteredRows.length === 0) {
31 | $('.no-results').show();
32 | } else {
33 | $('.no-results').hide();
34 | filteredRows.show();
35 | }
36 | };
37 | }
38 |
39 | window.tableSort = function() {
40 | $("table.packagetable").tablesorter();
41 | };
42 |
43 | window.bindFilter = function() {
44 | $('#filter').keyup(filterFunction(0));
45 | $('#packagefilter').keyup(filterFunction(1));
46 | };
47 |
48 | window.bootListTableFiltering = function() {
49 | window.bindFilter();
50 | window.tableSort();
51 | };
52 | })($jq);
53 |
--------------------------------------------------------------------------------
/assets/js/helpers/toggle.js:
--------------------------------------------------------------------------------
1 | (function($) {
2 | bootToggle = function() {
3 | $('[data-toggle]').click(function(event){
4 | event.preventDefault();
5 | var target = $($(this).data('target')),
6 | toggledText = $(this).data('toggled-text');
7 |
8 | $(this).data('toggled-text', $(this).text());
9 | $(this).text(toggledText);
10 |
11 | if(target.data('toggle-hidden') === true){
12 | target.show();
13 | target.data('toggle-hidden', false);
14 | } else {
15 | target.hide();
16 | target.data('toggle-hidden', true);
17 | }
18 | });
19 | };
20 | })($jq);
21 |
--------------------------------------------------------------------------------
/assets/js/libs/experiment.js:
--------------------------------------------------------------------------------
1 | (function(){
2 | window.Experiment = function(experimentName, experimentClass) {
3 | this.EXPERIMENT_NAME = experimentName;
4 | this.variants = [];
5 | this.experimentClass = experimentClass;
6 |
7 | this.addVariant = function(name, weight) {
8 | this.variants.push({
9 | experiment_name: this.EXPERIMENT_NAME,
10 | name: name,
11 | weight: weight
12 | })
13 | }
14 |
15 | this.chooseVariant = function() {
16 | var savedVariant = window.localStorage.getItem(this.EXPERIMENT_NAME);
17 | if(savedVariant) { return savedVariant }
18 |
19 | // Use a CDF to select a variant based on weight.
20 | var total = 0;
21 | var weights = [];
22 | for(i = 0; i < this.variants.length; i++) {
23 | total += this.variants[i].weight;
24 | weights[i] = total;
25 | }
26 | var random = Math.random() * weights[weights.length - 1];
27 | selectedVariantIndex = weights.findIndex(function(weight) {
28 | return random < weight;
29 | });
30 | var selectedVariant = this.variants[selectedVariantIndex];
31 | this.variant = selectedVariant;
32 | window.localStorage.setItem(this.EXPERIMENT_NAME, selectedVariant.name);
33 | this.sendSnowplowTrackingEvent();
34 | return selectedVariant.name;
35 | }
36 |
37 | this.sendSnowplowTrackingEvent = function() {
38 | // Snowplow requires variant weights to be integers, so let's 10x them until they are.
39 | while(this.variants.some(function(variant) { return variant.weight % 1 !== 0 })) {
40 | this.variants.forEach(function(variant) { variant.weight *= 10 })
41 | }
42 |
43 | window.snowplow('trackSelfDescribingEvent', {
44 | schema: 'iglu:com.datacamp/experiment/jsonschema/1-0-0',
45 | data: {
46 | name: this.EXPERIMENT_NAME,
47 | status: 'start',
48 | alternative: this.variant,
49 | alternatives: this.variants,
50 | }
51 | });
52 | }
53 |
54 | this.execute = function() {
55 | this.experimentClass.execute(this.chooseVariant());
56 | }
57 | }
58 | })();
59 |
--------------------------------------------------------------------------------
/assets/js/libs/jquery.cookie-1.4.1.min.js:
--------------------------------------------------------------------------------
1 | /*! jquery.cookie v1.4.1 | MIT */
2 | !function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof exports?a(require("jquery")):a(jQuery)}(function(a){function b(a){return h.raw?a:encodeURIComponent(a)}function c(a){return h.raw?a:decodeURIComponent(a)}function d(a){return b(h.json?JSON.stringify(a):String(a))}function e(a){0===a.indexOf('"')&&(a=a.slice(1,-1).replace(/\\"/g,'"').replace(/\\\\/g,"\\"));try{return a=decodeURIComponent(a.replace(g," ")),h.json?JSON.parse(a):a}catch(b){}}function f(b,c){var d=h.raw?b:e(b);return a.isFunction(c)?c(d):d}var g=/\+/g,h=a.cookie=function(e,g,i){if(void 0!==g&&!a.isFunction(g)){if(i=a.extend({},h.defaults,i),"number"==typeof i.expires){var j=i.expires,k=i.expires=new Date;k.setTime(+k+864e5*j)}return document.cookie=[b(e),"=",d(g),i.expires?"; expires="+i.expires.toUTCString():"",i.path?"; path="+i.path:"",i.domain?"; domain="+i.domain:"",i.secure?"; secure":""].join("")}for(var l=e?void 0:{},m=document.cookie?document.cookie.split("; "):[],n=0,o=m.length;o>n;n++){var p=m[n].split("="),q=c(p.shift()),r=p.join("=");if(e&&e===q){l=f(r,g);break}e||void 0===(r=f(r))||(l[q]=r)}return l};h.defaults={},a.removeCookie=function(b,c){return void 0===a.cookie(b)?!1:(a.cookie(b,"",a.extend({},c,{expires:-1})),!a.cookie(b))}});
--------------------------------------------------------------------------------
/assets/js/pages/collaborator.js:
--------------------------------------------------------------------------------
1 | (function($) {
2 | bootCollaborator = function(){
3 | var depsyurl = $(".depsy").data("url");
4 | if(depsyurl) {
5 | $.get(depsyurl,function(data){
6 | if(data.impact) {
7 | $("#impactnr").html(Math.round(data.impact*100)+"th");
8 | $(".depsy").show();
9 | } else {
10 | $(".depsy").css('visibility', 'hidden');
11 | }
12 |
13 | if(data.top_collabs) {
14 | $(".top-collab-list").append("
Top collaborators
");
15 | data.top_collabs.forEach(function(collab){
16 | $(".top-collab-list").append(""+collab.name+"");
17 | });
18 | }
19 |
20 | if(data.icon) {
21 | $('#collaborator-gravatar').attr('src', data.icon);
22 | }
23 |
24 | if(data.github_login) {
25 | $('#collaborator_github_link').attr('href', "https://github.com/"+ data.github_login);
26 | }
27 | $(document).trigger('content-changed');
28 | });
29 | }
30 |
31 | var downurl = $(".direct-downloads").data("url");
32 | if(downurl) {
33 | $.get(downurl,function(data){
34 | if(data.totalStr){
35 | $("#direct-downloadsnr").html(data.totalStr);
36 | $(".direct-downloads").show();
37 | }
38 | });
39 | }
40 |
41 | $('span.collaborator-type i.fa.fa-user').tooltip();
42 | $('span.collaborator-type i.fa.fa-users').tooltip();
43 | $('.impact-info').tooltip();
44 | };
45 | })($jq);
46 |
--------------------------------------------------------------------------------
/assets/js/pages/user.js:
--------------------------------------------------------------------------------
1 | (function($){
2 |
3 | window.User = {
4 | bindButtons: function() {
5 | User.bindDeleteButton();
6 | User.bindEditButton();
7 | },
8 |
9 | bindEditButton: function() {
10 | $(".edit-example").click(function(){
11 | $(this).unbind("click");
12 | var $example = $(this).parents(".example");
13 | var $text = $example.find(".example--text");
14 | $text.replaceWith("");
15 |
16 | var $element = $example.find("textarea")[0];
17 |
18 | var simplemde = Examples.loadMDEWidget($element);
19 |
20 | $example.find(".example--body").append("");
21 | $example.find(".submit-edit").click(function(){
22 | $this = $(this);
23 | var value = simplemde.value();
24 | $.post("/api/examples/"+$example.data("exampleid"),{text: value},function(response){
25 | var string = ""+value+"
";
26 | $example.find(".example--body").html(string);
27 |
28 | Examples.renderExamples('.example--text');
29 | User.bindEditButton();
30 | });
31 | });
32 | });
33 | },
34 |
35 | bindDeleteButton: function() {
36 | $(".delete-example").click(function(){
37 | var $this = $(this);
38 | var confimed = confirm("Are you sure you want to delete this example ?");
39 | if (!confimed) return;
40 | $.ajax({
41 | url: "api/examples/"+$(this).parents(".example").data("exampleid"),
42 | type: "delete",
43 | success: function(response){
44 | if(response.status === "done"){
45 | $this.parents(".example-wrapper").remove();
46 | }
47 | }
48 | });
49 | });
50 | }
51 | };
52 |
53 | bootUser = function(){
54 | User.bindButtons();
55 | };
56 |
57 | })($jq);
58 |
--------------------------------------------------------------------------------
/assets/robots.txt:
--------------------------------------------------------------------------------
1 | # The robots.txt file is used to control how search engines index your live URLs.
2 | # See http://sailsjs.org/documentation/anatomy/my-app/assets/robots-txt for more information.
3 |
4 |
5 |
6 | # To prevent search engines from seeing the site altogether, uncomment the next two lines:
7 | # User-Agent: *
8 | # Disallow: /
9 |
--------------------------------------------------------------------------------
/assets/sitemap/sitemap-1.xml.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datacamp/rdocumentation-app/3642111a3bfcae6c934e8aca4889c005ca90167d/assets/sitemap/sitemap-1.xml.gz
--------------------------------------------------------------------------------
/assets/sitemap/sitemap-2.xml.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datacamp/rdocumentation-app/3642111a3bfcae6c934e8aca4889c005ca90167d/assets/sitemap/sitemap-2.xml.gz
--------------------------------------------------------------------------------
/assets/sitemap/sitemap-3.xml.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datacamp/rdocumentation-app/3642111a3bfcae6c934e8aca4889c005ca90167d/assets/sitemap/sitemap-3.xml.gz
--------------------------------------------------------------------------------
/assets/sitemap/sitemap-4.xml.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datacamp/rdocumentation-app/3642111a3bfcae6c934e8aca4889c005ca90167d/assets/sitemap/sitemap-4.xml.gz
--------------------------------------------------------------------------------
/assets/sitemap/sitemap-5.xml.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datacamp/rdocumentation-app/3642111a3bfcae6c934e8aca4889c005ca90167d/assets/sitemap/sitemap-5.xml.gz
--------------------------------------------------------------------------------
/assets/sitemap/sitemapindex.xml.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datacamp/rdocumentation-app/3642111a3bfcae6c934e8aca4889c005ca90167d/assets/sitemap/sitemapindex.xml.gz
--------------------------------------------------------------------------------
/assets/styles/application.scss:
--------------------------------------------------------------------------------
1 | @import "styleguide/normalize";
2 | @import "styleguide/globals";
3 | @import "styleguide/base";
4 |
5 | @import "styleguide/partials/*";
6 | @import "widgets/*";
7 | @import "pages/*";
8 | @import "jquery-ui/*";
9 |
--------------------------------------------------------------------------------
/assets/styles/jquery-ui/core.scss:
--------------------------------------------------------------------------------
1 | /*!
2 | * jQuery UI CSS Framework @VERSION
3 | * http://jqueryui.com
4 | *
5 | * Copyright jQuery Foundation and other contributors
6 | * Released under the MIT license.
7 | * http://jquery.org/license
8 | *
9 | * http://api.jqueryui.com/category/theming/
10 | */
11 |
12 | /* Layout helpers
13 | ----------------------------------*/
14 | .ui-helper-hidden {
15 | display: none;
16 | }
17 | .ui-helper-hidden-accessible {
18 | border: 0;
19 | clip: rect(0 0 0 0);
20 | height: 1px;
21 | margin: -1px;
22 | overflow: hidden;
23 | padding: 0;
24 | position: absolute;
25 | width: 1px;
26 | }
27 | .ui-helper-reset {
28 | margin: 0;
29 | padding: 0;
30 | border: 0;
31 | outline: 0;
32 | line-height: 1.3;
33 | text-decoration: none;
34 | font-size: 100%;
35 | list-style: none;
36 | }
37 | .ui-helper-clearfix:before,
38 | .ui-helper-clearfix:after {
39 | content: "";
40 | display: table;
41 | border-collapse: collapse;
42 | }
43 | .ui-helper-clearfix:after {
44 | clear: both;
45 | }
46 | .ui-helper-zfix {
47 | width: 100%;
48 | height: 100%;
49 | top: 0;
50 | left: 0;
51 | position: absolute;
52 | opacity: 0;
53 | filter:Alpha(Opacity=0); /* support: IE8 */
54 | }
55 |
56 | .ui-front {
57 | z-index: 100;
58 | }
59 |
60 |
61 | /* Interaction Cues
62 | ----------------------------------*/
63 | .ui-state-disabled {
64 | cursor: default !important;
65 | pointer-events: none;
66 | }
67 |
68 |
69 | /* Icons
70 | ----------------------------------*/
71 | .ui-icon {
72 | display: inline-block;
73 | vertical-align: middle;
74 | margin-top: -.25em;
75 | position: relative;
76 | text-indent: -99999px;
77 | overflow: hidden;
78 | background-repeat: no-repeat;
79 | }
80 |
81 | .ui-widget-icon-block {
82 | left: 50%;
83 | margin-left: -8px;
84 | display: block;
85 | }
86 |
87 | /* Misc visuals
88 | ----------------------------------*/
89 |
90 | /* Overlays */
91 | .ui-widget-overlay {
92 | position: fixed;
93 | top: 0;
94 | left: 0;
95 | width: 100%;
96 | height: 100%;
97 | }
98 |
--------------------------------------------------------------------------------
/assets/styles/jquery-ui/tabs.scss:
--------------------------------------------------------------------------------
1 | /*!
2 | * jQuery UI Tabs @VERSION
3 | * http://jqueryui.com
4 | *
5 | * Copyright jQuery Foundation and other contributors
6 | * Released under the MIT license.
7 | * http://jquery.org/license
8 | *
9 | * http://api.jqueryui.com/tabs/#theming
10 | */
11 | .ui-tabs {
12 | position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
13 | padding: .2em;
14 | }
15 | .ui-tabs .ui-tabs-nav {
16 | margin: 0;
17 | padding: .2em .2em 0;
18 | }
19 | .ui-tabs .ui-tabs-nav li {
20 | list-style: none;
21 | float: left;
22 | position: relative;
23 | top: 0;
24 | margin: 1px .2em 0 0;
25 | border-bottom-width: 0;
26 | padding: 0;
27 | white-space: nowrap;
28 | }
29 | .ui-tabs .ui-tabs-nav .ui-tabs-anchor {
30 | float: left;
31 | padding: .5em 1em;
32 | text-decoration: none;
33 | }
34 | .ui-tabs .ui-tabs-nav li.ui-tabs-active {
35 | margin-bottom: -1px;
36 | padding-bottom: 1px;
37 | }
38 | .ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,
39 | .ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,
40 | .ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor {
41 | cursor: text;
42 | }
43 | .ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor {
44 | cursor: pointer;
45 | }
46 | .ui-tabs .ui-tabs-panel {
47 | display: block;
48 | border-width: 0;
49 | padding: 1em 1.4em;
50 | background: none;
51 | }
52 |
--------------------------------------------------------------------------------
/assets/styles/pages/_authentication.scss:
--------------------------------------------------------------------------------
1 | .authentication {
2 | min-height: 82%;
3 | .container {
4 | margin-top: $default-space;
5 | }
6 | }
7 |
8 | .authentication--form {
9 | fieldset {
10 | width: 100%;
11 | }
12 |
13 | fieldset .btn {
14 | width: auto;
15 | }
16 | }
17 |
18 | .authentication--title {
19 | margin-bottom: $default-space;
20 | text-align: center;
21 | }
--------------------------------------------------------------------------------
/assets/styles/pages/_error-page.scss:
--------------------------------------------------------------------------------
1 | .error-page {
2 | min-height: 85%;
3 | display: flex;
4 |
5 | h1 {
6 | margin-bottom: 2 * $default-space;
7 | font-size: 7rem;
8 | }
9 |
10 | .error-page--content {
11 | margin: auto;
12 | text-align: center;
13 | }
14 | }
--------------------------------------------------------------------------------
/assets/styles/pages/_examples.scss:
--------------------------------------------------------------------------------
1 | .user-examples {
2 | margin-top: $default-space;
3 | h3 {
4 | margin-bottom: $default-space / 2.0;
5 | }
6 | }
7 | // ********************
8 | // One review
9 | // ********************
10 | .example {
11 | margin-bottom: 1rem;
12 | border: 2px solid $primary-lighter;
13 | border-radius: 4px;
14 | }
15 |
16 | .example.old {
17 | border: 2px solid #efefef;
18 | }
19 |
20 | .example--title {
21 | padding: 1rem;
22 | background-color: $primary-extra-light;
23 | border-bottom: 2px solid $primary-lighter;
24 | .rating {
25 | margin: 0 1rem;
26 | }
27 | }
28 |
29 | .example.old .example--title {
30 | border: 2px solid #efefef;
31 | background-color: #efefef;
32 | }
33 |
34 | .example--body {
35 | p {
36 | margin: 0;
37 | white-space: pre-wrap;
38 | }
39 | }
40 | .markdown-body {
41 | box-sizing: border-box;
42 | margin: 0 auto;
43 | padding: 10px 20px;
44 | font-size: 14px;
45 | }
46 |
47 | // ********************
48 | // Placeholder if there are no examples
49 | // ********************
50 | .example--placeholder {
51 | border: 1px solid $primary-extra-light;
52 | border-radius: 4px;
53 | padding: 1rem;
54 | background-color: $primary-ultra-light;
55 | margin-bottom: 1rem;
56 | }
57 |
58 | // ********************
59 | // Form to create a example
60 | // ********************
61 | .example--form {
62 | margin-top: $default-space;
63 | fieldset {
64 | width: 100%;
65 | }
66 | }
67 |
68 | $filled-star-color: black;
69 | $empty-star-color: black;
70 | $star-size: 17px;
71 |
72 | .example--form-title {
73 | padding: 1rem;
74 | background-color: $primary-ultra-light;
75 | border-bottom: 1px solid $primary-extra-light;
76 | }
77 |
78 | .example--form-body {
79 | padding: 1rem 0;
80 | }
81 |
82 | .editor-toolbar.fullscreen, .CodeMirror-fullscreen, .editor-preview-side {
83 | margin-top: 30px !important;
84 | }
85 |
86 | .buttons{
87 | margin-left: 1rem;
88 | float : right;
89 | }
90 |
91 | .submit-edit{
92 | margin-top: 1.5em;
93 | }
94 |
95 | .edit-example:hover, .delete-example:hover{
96 | cursor: pointer;
97 | }
98 |
--------------------------------------------------------------------------------
/assets/styles/pages/_package-readme.scss:
--------------------------------------------------------------------------------
1 | .package--readme {
2 | img {
3 | max-width: 100%;
4 | }
5 | a {
6 | border-bottom: none;
7 | }
8 | }
9 |
10 | .package--readme .markdown-container {
11 | border: 1px solid #efefef;
12 | }
13 |
--------------------------------------------------------------------------------
/assets/styles/pages/_package-source.scss:
--------------------------------------------------------------------------------
1 | .source--explorer {
2 | flex: 1 1 auto;
3 | display: flex;
4 | margin-bottom: 5px;
5 | }
6 | .source--tree {
7 | overflow-y: scroll;
8 | width: 240px;
9 | }
10 |
11 | .source--code {
12 | overflow-y: scroll;
13 | flex-grow: 1;
14 | background-color: #f6f7f9;
15 | }
16 | #tree {
17 | .list-group {
18 | margin-top: -0.5px;
19 | overflow: hidden;
20 | li:last-child {
21 | margin-bottom: 0px;
22 | }
23 | }
24 | .node-tree:not(.node-selected){
25 | .glyphicon:before{
26 | color: #3ac;
27 | }
28 | }
29 | }
30 | .source-header {
31 | width: 100%;
32 | height: 45px;
33 | flex-shrink: 0;
34 | }
35 |
36 | #source-container {
37 | pre{
38 | margin-top: 0px;
39 | }
40 | td.hljs-ln-numbers {
41 | -webkit-touch-callout: none;
42 | -webkit-user-select: none;
43 | -khtml-user-select: none;
44 | -moz-user-select: none;
45 | -ms-user-select: none;
46 | user-select: none;
47 |
48 | text-align: center;
49 | color: #ccc;
50 | border-right: 1px solid #CCC;
51 | vertical-align: top;
52 | padding-right: 5px;
53 |
54 | /* your custom style here */
55 | }
56 | td.hljs-ln-code {
57 | padding-left: 10px;
58 | }
59 | pre code.hljs{
60 | padding: 0px;
61 | }
62 | tr:nth-of-type(2n){
63 | background: #f6f7f9;
64 | }
65 | }
66 | #source-not-found {
67 | display:none;
68 | }
69 | .source{
70 | display: flex;
71 | flex-direction: column;
72 | height: 100%;
73 | }
74 |
75 | .scroll::-webkit-scrollbar {
76 | width: 5px;
77 | margin-top: -5px;
78 | }
79 |
80 | .scroll::-webkit-scrollbar-track {
81 | background: #ddd;
82 | }
83 |
84 | .scroll::-webkit-scrollbar-thumb {
85 | background: #666;
86 | }
87 |
--------------------------------------------------------------------------------
/assets/styles/pages/_package-vignettes.scss:
--------------------------------------------------------------------------------
1 | .package--vignette {
2 | img {
3 | max-width: 100%;
4 | }
5 | a {
6 | border-bottom: none;
7 | }
8 | }
9 |
10 | .package--vignette .markdown-container {
11 | border: 1px solid #efefef;
12 | }
13 |
14 | .vignette-header {
15 | @include clearfix;
16 |
17 | h1 {
18 | display: inline-block;
19 | vertical-align: middle;
20 | }
21 |
22 | .vignette--header-content {
23 | padding-top: 15px;
24 | border-bottom: 2px solid #ebf4f7;
25 | padding-bottom: 10px;
26 | }
27 | }
28 |
29 | .ph-flex-position {
30 | display: flex;
31 | flex-flow: row wrap;
32 | align-items: center;
33 | justify-content: space-between;
34 | }
35 |
36 | .vignette--title--container {
37 | display: flex;
38 | align-items: baseline;
39 | margin-bottom: 1rem;
40 | }
41 |
42 | .vignette--title {
43 | margin: 0;
44 | font-size: 2rem;
45 | }
46 |
--------------------------------------------------------------------------------
/assets/styles/pages/_package.scss:
--------------------------------------------------------------------------------
1 | .package {
2 | min-height: 85%;
3 |
4 | .package--badge {
5 | margin-top: $default-space;
6 | }
7 | .content {
8 | margin-top: 1rem;
9 | }
10 | }
11 |
12 | .anchor {
13 | visibility: hidden;
14 | top: -70px;
15 | position: relative;
16 | }
17 |
18 | i.fa.fa-user{
19 | font-size: 2rem;
20 | }
21 |
22 | #show:hover {
23 | cursor: pointer;
24 | }
25 | #info.col-md-8 {
26 | float:right;
27 | dd{
28 | margin-left: 0px;
29 | }
30 | dl{
31 | -webkit-margin-after: 0.4em;
32 | }
33 | .links{
34 | -webkit-margin-before: 0.2em;
35 | }
36 | }
37 |
38 | .table-title{
39 | display: inline-block;
40 | margin-right: 1rem;
41 | margin-left: auto;
42 | }
43 |
44 | .table-top{
45 | position: absolute;
46 | left: 50%;
47 | transform: translateX(-50%);
48 | }
49 |
50 | #filter{
51 | display:inline-block;
52 | }
53 |
54 | .package--stats {
55 | dd a {
56 | margin-right: $default-space / 3.0;
57 | &:last-child {
58 | margin-right: 0;
59 | }
60 | }
61 | }
62 |
63 | .package--dependencies {
64 | margin-top: $default-space;
65 | }
66 |
67 | .package--details-container {
68 | min-height: 400px;
69 | margin-top: 1rem;
70 | }
71 | .package-description {
72 | margin-top: $default-space;
73 | }
74 |
75 | .rating {
76 | display: inline-block;
77 | }
78 |
79 | .icon-green {
80 | color: #00cc00;
81 | font-size: 1.5em;
82 | margin-right: 0.5rem;
83 | }
84 |
--------------------------------------------------------------------------------
/assets/styles/pages/_shared.scss:
--------------------------------------------------------------------------------
1 | .body {
2 | height: 100%;
3 | }
4 |
5 | #content {
6 | height: 100%;
7 | }
8 |
9 | .page-wrap {
10 | bottom: 55px;
11 | top: 30px;
12 | left: 0;
13 | right: 0;
14 | position: static; /* TODO: Remove after promo? */
15 | overflow-y: scroll;
16 | }
17 |
18 | .stats {
19 | dd a {
20 | margin-right: $default-space / 3;
21 | &:last-child {
22 | margin-right: 0;
23 | }
24 | }
25 | }
26 |
27 | .no-padding {
28 | padding: 0;
29 | }
30 |
31 | .fading-text {
32 | line-height: 1.5rem;
33 | position: relative;
34 | height: 4.5rem;
35 | }
36 |
37 | .fading-text:after {
38 | content: "";
39 | text-align: right;
40 | position: absolute;
41 | bottom: 0;
42 | right: 0;
43 | width: 70%;
44 | height: 1.5rem;
45 | background: linear-gradient(
46 | to right,
47 | rgba(255, 255, 255, 0),
48 | rgba(255, 255, 255, 1) 50%
49 | );
50 | }
51 |
52 | .downloads,
53 | .percentile-widget {
54 | visibility: hidden;
55 | vertical-align: middle;
56 | margin-left: 0.2rem;
57 | display: inline-block;
58 | p {
59 | -webkit-margin-before: -0.7em;
60 | -webkit-margin-after: 0em;
61 | }
62 | i {
63 | font-size: 1.4rem;
64 | margin-left: 0.6rem;
65 | }
66 | }
67 |
68 | .percentile-task {
69 | visibility: hidden;
70 | }
71 |
72 | .downloads-nr,
73 | .percentile-th {
74 | display: flex;
75 | align-items: center;
76 | span:first-child {
77 | font-size: $h3-size;
78 | }
79 |
80 | &.small span:first-child {
81 | font-size: $h3-size;
82 | }
83 | }
84 |
85 | .downloads-ind {
86 | display: block;
87 | span {
88 | font-weight: bold;
89 | }
90 | }
91 | .downloads-credits {
92 | font-size: 0.6rem;
93 | }
94 |
95 | .table-list {
96 | input {
97 | width: 300px;
98 | padding: 0.375em 0.75em;
99 | margin: $default-space auto $default-space / 2 auto;
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/assets/styles/pages/_task-view-sidebar.scss:
--------------------------------------------------------------------------------
1 | .sliding-sidebar{
2 | position: fixed;
3 | height: 100%;
4 | width:265px;
5 | padding-right: 15px;
6 | overflow-y: auto;
7 | }
8 |
9 | .sidebar-slider-icon{
10 | font-size: 2.5rem;
11 | position: absolute;
12 | top: 50%;
13 | right: 0;
14 | transform: translateY(-50%);
15 | cursor: pointer;
16 | }
17 |
18 | .list-group-item {
19 | position:relative;
20 | display:block;
21 | padding:10px 15px;
22 | margin-bottom:-1px;
23 | background-color:#fff;
24 | border:1px solid #ddd
25 | }
26 |
27 | a.list-group-item{
28 | color: #666666;
29 | }
30 |
31 | .list-group{
32 | padding-left:0;
33 | overflow-y: scroll;
34 | }
35 |
36 | .list-group-item.highlight{
37 | background-color: #f5f5f5
38 | }
39 |
40 | .list-group .list-group-item:hover{
41 | background-color: #f5f5f5
42 | }
43 |
--------------------------------------------------------------------------------
/assets/styles/pages/_task-views.scss:
--------------------------------------------------------------------------------
1 | .view {
2 | position: relative;
3 | margin-left: 265px;
4 | width: calc(100% - 265px);
5 | padding: 1rem;
6 | }
7 | .percentile-number{
8 | font-size:1.5rem;
9 | }
10 | .view td[data-column="2"] {
11 | width: 115px;
12 | }
13 |
--------------------------------------------------------------------------------
/assets/styles/pages/_topic-header.scss:
--------------------------------------------------------------------------------
1 | .topic-header {
2 | margin-top: 2rem;
3 | margin-bottom:15px;
4 | }
5 |
6 | .th--flex-position {
7 | display: flex;
8 | align-items: center;
9 | justify-content: space-between;
10 | margin-top: 20px;
11 | flex-flow: row wrap;
12 | }
13 |
14 | .th--pkg-info {
15 | font-size: 1rem;
16 | background-color: #ebf4f7;
17 | border-radius: 5px;
18 | padding: 6px;
19 | display: flex;
20 | align-items: center;
21 | }
22 |
23 | .th--origin span {
24 | display: block;
25 | }
26 |
27 | .th--percentile {
28 | margin-left: 20px;
29 | font-weight: 200;
30 | }
31 |
--------------------------------------------------------------------------------
/assets/styles/pages/_topic.scss:
--------------------------------------------------------------------------------
1 | .topic {
2 | min-height: 84%;
3 |
4 | h5 {
5 | text-transform: capitalize;
6 | }
7 | .run-example {
8 | display: block;
9 | margin: 10px 0;
10 | }
11 | }
12 |
13 | .topic--title {
14 | margin-top: $default-space;
15 | }
16 |
17 | // Override and support custom entries in topic--value (?)
18 | .topic--value {
19 | dl {
20 | dd {
21 | float: none;
22 | }
23 | dt {
24 | float: none;
25 | }
26 | }
27 | ul {
28 | @include clearfix;
29 | display: block;
30 | list-style: none;
31 | margin-top: 1em;
32 | margin-bottom: 1em;
33 | margin-left: 0;
34 | margin-right: 0;
35 | padding-left: 0;
36 |
37 | li {
38 | margin-bottom: 1rem;
39 | name {
40 | display: block;
41 | font-weight: bold;
42 | float: left;
43 | }
44 |
45 | .description {
46 | display: block;
47 | margin-left: 40px;
48 | margin-left: 130px;
49 | }
50 | }
51 | }
52 | }
53 |
54 |
55 | // Override DCL style
56 | .topic .powered-by-datacamp {
57 | background: white;
58 | margin: 0;
59 | a {
60 | margin-left: 5px;
61 | margin-top: 5px;
62 | display: inline-flex;
63 | font-size: 12px !important;
64 | }
65 | .logo {
66 | height: 18px;
67 | max-resolution: 0;
68 | }
69 | }
70 |
71 | .topic .dcl-exercise-area .clearfix:before{
72 | content: none;
73 | }
74 |
--------------------------------------------------------------------------------
/assets/styles/pages/_trends.scss:
--------------------------------------------------------------------------------
1 | .trends {
2 | #topkeywords {
3 | height: 400px;
4 | }
5 | #packagesperrange {
6 | height: 400px;
7 | }
8 | h1{
9 | margin-top: .65em;
10 | }
11 |
12 | .previous, .next{
13 | margin-top:10px;
14 | }
15 |
16 | #dependencygraph {
17 | height: 900px;
18 | overflow-y: auto;
19 | }
20 |
21 | .graph {
22 | margin-top: 2em;
23 | margin-bottom: 5em;
24 | }
25 |
26 | .data .fa{
27 | padding-left: 2px;
28 | display: inline;
29 | }
30 |
31 | .row.top10{
32 | margin-top: 2em;
33 | }
34 |
35 | .row.metrics {
36 | margin-top: 3rem;
37 | margin-bottom: 5rem;
38 | }
39 |
40 | .info-trends{
41 | float: right;
42 | margin-top :0em;
43 | margin-bottom :0em;
44 | }
45 |
46 | .transp {
47 | display: none;
48 | position:absolute;
49 | left:0;
50 | top:0;
51 | background: rgba(255,255,255,.5);
52 | width:100%;
53 | height:100%;
54 | }
55 | }
56 |
57 | @media (max-width: 991px){
58 | .trends .col-md-6{
59 | margin-bottom: 4.2rem;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/assets/styles/pages/_user.scss:
--------------------------------------------------------------------------------
1 | .user {
2 | min-height: 82%;
3 | .container {
4 | margin-top: $default-space;
5 | }
6 |
7 | header {
8 | margin-bottom: $default-space;
9 | }
10 | }
11 |
12 | .user--reviews {
13 | h3 {
14 | margin-bottom: $default-space / 2.0;
15 | }
16 | }
17 |
18 | .example {
19 | .clearfix:before, .container:before, .container-fluid:before, .row:before{
20 | display: none;
21 | }
22 | }
--------------------------------------------------------------------------------
/assets/styles/styleguide/partials/_labels.scss:
--------------------------------------------------------------------------------
1 | .label {
2 | color: $text-invert;
3 | display: inline-block;
4 | font-size: $small-font-size;
5 | margin-left: 5px;
6 | padding: 0.25em 0.4375em;
7 | position: relative;
8 | text-transform: uppercase;
9 | top: -3px;
10 | border-radius: 0;
11 | font-weight: 400;
12 | }
13 |
14 | .label-accent {
15 | background-color: $accent;
16 | }
--------------------------------------------------------------------------------
/assets/styles/styleguide/partials/_lists.scss:
--------------------------------------------------------------------------------
1 | ul.no-style,
2 | ol.no-style {
3 | list-style: none;
4 | margin: 0;
5 | padding: 0;
6 | }
7 |
8 |
9 | ul.inline,
10 | ol.inline {
11 | list-style: none;
12 | margin: 0;
13 | padding: 0;
14 | @include clearfix;
15 | li {
16 | float: left;
17 | margin-right:10px;
18 | }
19 |
20 | li:last-child {
21 | margin-right: 0;
22 | }
23 | }
--------------------------------------------------------------------------------
/assets/styles/styleguide/partials/_rstudio.scss:
--------------------------------------------------------------------------------
1 | html.rstudio {
2 | font-size: 14px;
3 |
4 | .topic {
5 | h1 {font-size: $h1-size * 0.6}
6 | h2 {font-size: $h2-size * 0.7}
7 | h3 {font-size: $h3-size * 0.7}
8 | h4 {font-size: $h4-size * 0.6}
9 | h5 {font-size: $h5-size * 0.9}
10 | .container-fluid {
11 | margin-top: 0.5rem;
12 | }
13 | }
14 |
15 | }
16 |
17 |
--------------------------------------------------------------------------------
/assets/styles/styleguide/partials/_tables.scss:
--------------------------------------------------------------------------------
1 | table {
2 | border-collapse: collapse;
3 | text-align: left;
4 | width: 100%
5 | }
6 |
7 | thead {
8 | font-weight: bold;
9 | }
10 | tr {
11 | border-bottom: $table-border-width solid $primary-extra-light;
12 | }
13 | tr:nth-of-type(2n) {
14 | background: $primary-ultra-light;
15 | }
16 | th {
17 | border-bottom: $table-border-width solid $text-tertiary;
18 | color: $primary;
19 | }
20 | td,
21 | th {
22 | padding: $table-spacing;
23 | }
24 | td {
25 | color: $text-secondary;
26 | }
27 |
28 | tr.no-results {
29 | border-bottom: none;
30 | text-align: center;
31 | display: none;
32 | td {
33 | padding: $default-space 0;
34 | }
35 | }
--------------------------------------------------------------------------------
/assets/styles/widgets/_big-number.scss:
--------------------------------------------------------------------------------
1 | .big-number {
2 | .number {
3 | line-height: 9rem;
4 | height: 100%;
5 | text-align: center;
6 | display: block;
7 | font-size: 9rem;
8 | }
9 | .big-number-label {
10 | display: block;
11 | text-align: center;
12 | line-height: 2rem;
13 | font-size: 2rem;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/assets/styles/widgets/_loader.scss:
--------------------------------------------------------------------------------
1 | .loader-outer {
2 | display: table;
3 | height: 100%;
4 | width: 100%;
5 | }
6 |
7 | .loader-middle {
8 | display: table-cell;
9 | vertical-align: middle;
10 | }
11 |
12 | .loader {
13 | margin-left: auto;
14 | margin-right: auto;
15 | border: 16px solid #f3f3f3; /* Light grey */
16 | border-top: 16px solid $primary;
17 | border-radius: 50%;
18 | width: 120px;
19 | height: 120px;
20 | animation: spin 2s linear infinite;
21 | }
22 |
23 | @keyframes spin {
24 | 0% { transform: rotate(0deg); }
25 | 100% { transform: rotate(360deg); }
26 | }
27 |
--------------------------------------------------------------------------------
/assets/styles/widgets/_modal.scss:
--------------------------------------------------------------------------------
1 | .jquery-modal.blocker{
2 | z-index:1050;
3 | .modal a.close-modal{
4 | border-bottom: none;
5 | }
6 | }
7 |
8 | .jquery-modal .modal{
9 | width:550px;
10 | }
11 |
12 | @media(max-width: 600px){
13 | .jquery-modal .modal{
14 | width: 92%;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/assets/styles/widgets/mono-blue.css:
--------------------------------------------------------------------------------
1 | /*
2 | Five-color theme from a single blue hue.
3 | */
4 | .hljs {
5 | display: block;
6 | overflow-x: auto;
7 | padding: 0.5em;
8 | background: #eaeef3;
9 | }
10 |
11 | .hljs {
12 | color: #00193a;
13 | }
14 |
15 | .hljs-keyword,
16 | .hljs-selector-tag,
17 | .hljs-title,
18 | .hljs-section,
19 | .hljs-doctag,
20 | .hljs-name,
21 | .hljs-strong {
22 | font-weight: bold;
23 | }
24 |
25 | .hljs-comment {
26 | color: #738191;
27 | }
28 |
29 | .hljs-string,
30 | .hljs-title,
31 | .hljs-section,
32 | .hljs-built_in,
33 | .hljs-literal,
34 | .hljs-type,
35 | .hljs-addition,
36 | .hljs-tag,
37 | .hljs-quote,
38 | .hljs-name,
39 | .hljs-selector-id,
40 | .hljs-selector-class {
41 | color: #0048ab;
42 | }
43 |
44 | .hljs-meta,
45 | .hljs-subst,
46 | .hljs-symbol,
47 | .hljs-regexp,
48 | .hljs-attribute,
49 | .hljs-deletion,
50 | .hljs-variable,
51 | .hljs-template-variable,
52 | .hljs-link,
53 | .hljs-bullet {
54 | color: #4c81c9;
55 | }
56 |
57 | .hljs-emphasis {
58 | font-style: italic;
59 | }
60 |
--------------------------------------------------------------------------------
/assets/templates/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datacamp/rdocumentation-app/3642111a3bfcae6c934e8aca4889c005ca90167d/assets/templates/.gitkeep
--------------------------------------------------------------------------------
/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | if [ -n "$(git status --porcelain)" ]; then
5 | echo "Your git directory is not clean, commit your changes before building";
6 | exit 1;
7 | fi
8 |
9 | docker login --username="$1" --password="$2" --email=a dockerhub.datacamp.com:443
10 | #build new docker image
11 | docker build -t dockerhub.datacamp.com:443/rdocsv2:$BUILD_NUMBER .
12 | #push image to docker registery
13 | docker push dockerhub.datacamp.com:443/rdocsv2:$BUILD_NUMBER
14 |
15 | sed -e "s/\$version/$BUILD_NUMBER/" -e "s/\$memory/1500/" < Dockerrun.aws.json.in > Dockerrun.aws.json
16 |
17 |
--------------------------------------------------------------------------------
/catalog-info.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: backstage.io/v1alpha1
2 | kind: Component
3 | metadata:
4 | description: "rdoc-app service, code: rdocumentation-app infra: RDocumentation-app-infra "
5 | name: rdoc-app
6 | annotations:
7 | github.com/project-slug: "datacamp/rdocumentation-app"
8 | circleci.com/project-slug: "github/datacamp/rdocumentation-app"
9 | tags:
10 | - infrastructure-data
11 | spec:
12 | lifecycle: "production"
13 | owner: "infrastructure-data"
14 | type: "service"
15 |
--------------------------------------------------------------------------------
/config/bootstrap.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Bootstrap
3 | * (sails.config.bootstrap)
4 | *
5 | * An asynchronous bootstrap function that runs before your Sails app gets lifted.
6 | * This gives you an opportunity to set up your data model, run jobs, or perform some special logic.
7 | *
8 | * For more information on bootstrapping your app, check out:
9 | * http://sailsjs.org/#!/documentation/reference/sails.config/sails.config.bootstrap.html
10 | */
11 |
12 | var _ = require('lodash');
13 | module.exports.bootstrap = function(cb) {
14 |
15 | // It's very important to trigger this callback method when you are finished
16 | // with the bootstrap! (otherwise your server will never lift, since it's waiting on the bootstrap)
17 | _.extend(sails.hooks.http.app.locals, sails.config.http.locals);
18 | cb();
19 | };
20 |
--------------------------------------------------------------------------------
/config/elasticsearch.js:
--------------------------------------------------------------------------------
1 | var bluebird = require('bluebird');
2 |
3 | module.exports.elasticsearch = {
4 |
5 | host: process.env.ELASTICSEARCH_URL,
6 |
7 | log: 'error',
8 |
9 | defer: function () {
10 | return bluebird.defer();
11 | }
12 |
13 | };
14 |
--------------------------------------------------------------------------------
/config/env/development.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Development environment settings
3 | *
4 | * This file can include shared settings for a development team,
5 | * such as API keys or remote database passwords. If you're using
6 | * a version control solution for your Sails app, this file will
7 | * be committed to your repository unless you add it to your .gitignore
8 | * file. If your repository will be publicly viewable, don't add
9 | * any private information to this file!
10 | *
11 | */
12 |
13 | module.exports = {
14 |
15 | /***************************************************************************
16 | * Set the default database connection for models in the development *
17 | * environment (see config/connections.js and config/models.js ) *
18 | ***************************************************************************/
19 | connections: {
20 | sequelize_mysql: {
21 | database: process.env.DATABASE_NAME,
22 | user: process.env.DATABASE_USERNAME,
23 | password: process.env.DATABASE_PASSWORD,
24 | options: {
25 | dialect: 'mysql',
26 | host: process.env.DATABASE_HOST,
27 | port: process.env.DATABASE_PORT,
28 | pool: {
29 | max: 10,
30 | min: 4,
31 | idle: 10000
32 | }
33 | }
34 | }
35 | },
36 |
37 | models: {
38 | migrate: 'safe'
39 | },
40 |
41 | session: {
42 | secret: '652c68f88144e6a99b9522ea1193a645'
43 | },
44 |
45 | redis: {
46 |
47 | logging: true,
48 |
49 | url: process.env.REDIS_URL
50 |
51 | },
52 |
53 | cors: {
54 | allRoutes: true,
55 |
56 | origin: '*',
57 |
58 | credentials: true,
59 |
60 | exposeHeaders: 'X-RStudio-Ajax, X-RStudio-Redirect, X-Rstudio-Session',
61 |
62 | methods: 'GET, POST, PUT, DELETE, OPTIONS, HEAD',
63 |
64 | headers: 'Content-Type, Accept-Encoding, X-Shared-Secret, X-Requested-With, Cache-Control, X-RStudio-Ajax, X-RStudio-Redirect, X-Rstudio-Session'
65 | }
66 |
67 | };
68 |
--------------------------------------------------------------------------------
/config/env/docker.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Development environment settings
3 | *
4 | * This file can include shared settings for a development team,
5 | * such as API keys or remote database passwords. If you're using
6 | * a version control solution for your Sails app, this file will
7 | * be committed to your repository unless you add it to your .gitignore
8 | * file. If your repository will be publicly viewable, don't add
9 | * any private information to this file!
10 | *
11 | */
12 |
13 | module.exports = {
14 |
15 | /***************************************************************************
16 | * Set the default database connection for models in the development *
17 | * environment (see config/connections.js and config/models.js ) *
18 | ***************************************************************************/
19 | connections: {
20 | sequelize_mysql: {
21 | database: process.env.DATABASE_NAME,
22 | user: process.env.DATABASE_USERNAME,
23 | password: process.env.DATABASE_PASSWORD,
24 | options: {
25 | dialect: 'mysql',
26 | host : process.env.DATABASE_HOST,
27 | port : process.env.DATABASE_PORT,
28 | pool: {
29 | max: 10,
30 | min: 4,
31 | idle: 10000
32 | }
33 | }
34 | }
35 | },
36 |
37 | models: {
38 | migrate: 'safe'
39 | },
40 |
41 | session: {
42 | url: 'redis://redis:6379',
43 | prefix: 'sess:'
44 | },
45 |
46 | grunt: {
47 | _hookTimeout: 60000
48 | },
49 |
50 | routes: {
51 | 'post /tasks': 'WorkerController.processMessage',
52 | 'get /last-day-splitted-stats': 'WorkerController.lastDaySplittedDownloads'
53 | }
54 |
55 |
56 | };
57 |
--------------------------------------------------------------------------------
/config/env/production.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Production environment settings
3 | *
4 | * This file can include shared settings for a production environment,
5 | * such as API keys or remote database passwords. If you're using
6 | * a version control solution for your Sails app, this file will
7 | * be committed to your repository unless you add it to your .gitignore
8 | * file. If your repository will be publicly viewable, don't add
9 | * any private information to this file!
10 | *
11 | */
12 |
13 | module.exports = {
14 |
15 | connections: {
16 | sequelize_mysql: {
17 | database: process.env.DATABASE_NAME,
18 | user: process.env.DATABASE_USERNAME,
19 | password: process.env.DATABASE_PASSWORD,
20 | options: {
21 | dialect: 'mysql',
22 | host : process.env.DATABASE_HOST,
23 | port : process.env.DATABASE_PORT,
24 | pool: {
25 | max: 15,
26 | min: 4,
27 | idle: 10000
28 | }
29 | }
30 | },
31 |
32 | },
33 |
34 | models: {
35 | migrate: 'safe'
36 | },
37 |
38 | session: {
39 | url: process.env.REDIS_URL,
40 | prefix: 'sess:',
41 | },
42 |
43 | grunt: {
44 | _hookTimeout: 60000
45 | }
46 |
47 |
48 | };
49 |
--------------------------------------------------------------------------------
/config/env/staging.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Staging environment settings
3 | *
4 | * This file can include shared settings for a staging environment,
5 | * such as API keys or remote database passwords. If you're using
6 | * a version control solution for your Sails app, this file will
7 | * be committed to your repository unless you add it to your .gitignore
8 | * file. If your repository will be publicly viewable, don't add
9 | * any private information to this file!
10 | *
11 | */
12 |
13 | module.exports = {
14 |
15 | connections: {
16 | sequelize_mysql: {
17 | database: process.env.DATABASE_NAME,
18 | user: process.env.DATABASE_USERNAME,
19 | password: process.env.DATABASE_PASSWORD,
20 | options: {
21 | dialect: 'mysql',
22 | host : process.env.DATABASE_HOST,
23 | port : process.env.DATABASE_PORT,
24 | pool: {
25 | max: 5,
26 | min: 2,
27 | idle: 10000
28 | },
29 | benchmark:true
30 | }
31 | },
32 |
33 | },
34 |
35 | models: {
36 | migrate: 'safe'
37 | },
38 |
39 | session: {
40 | url: process.env.REDIS_URL,
41 | prefix: 'sess:'
42 | },
43 |
44 | grunt: {
45 | _hookTimeout: 60000
46 | },
47 |
48 | cors: {
49 | allRoutes: true,
50 | origin: '*',
51 | credentials: true,
52 | exposeHeaders: 'X-RStudio-Ajax, X-RStudio-Redirect, X-Rstudio-Session',
53 | methods: 'GET, POST, PUT, DELETE, OPTIONS, HEAD',
54 | headers: 'Content-Type, Accept-Encoding, X-Shared-Secret, X-Requested-With, Cache-Control, X-RStudio-Ajax, X-RStudio-Redirect, X-Rstudio-Session'
55 | }
56 |
57 | };
58 |
--------------------------------------------------------------------------------
/config/env/worker.js:
--------------------------------------------------------------------------------
1 |
2 | module.exports = {
3 |
4 | connections: {
5 | sequelize_mysql: {
6 | database: process.env.DATABASE_NAME,
7 | user: process.env.DATABASE_USERNAME,
8 | password: process.env.DATABASE_PASSWORD,
9 | options: {
10 | dialect: 'mysql',
11 | host : process.env.DATABASE_HOST,
12 | port : process.env.DATABASE_PORT,
13 | pool: {
14 | max: 10,
15 | min: 3,
16 | idle: 10000
17 | }
18 | }
19 | },
20 |
21 | },
22 |
23 | models: {
24 | migrate: 'safe'
25 | },
26 |
27 | grunt: {
28 | _hookTimeout: 60000
29 | },
30 |
31 |
32 | session: {
33 | url: process.env.REDIS_URL,
34 | prefix: 'sess:'
35 | },
36 |
37 | routes: {
38 | 'post /tasks': 'WorkerController.processMessage',
39 | 'get /status': 'HomeController.status'
40 | }
41 |
42 | };
43 |
--------------------------------------------------------------------------------
/config/locales/_README.md:
--------------------------------------------------------------------------------
1 | # Internationalization / Localization Settings
2 |
3 | > Also see the official docs on internationalization/localization:
4 | > http://links.sailsjs.org/docs/config/locales
5 |
6 | ## Locales
7 | All locale files live under `config/locales`. Here is where you can add translations
8 | as JSON key-value pairs. The name of the file should match the language that you are supporting, which allows for automatic language detection based on request headers.
9 |
10 | Here is an example locale stringfile for the Spanish language (`config/locales/es.json`):
11 | ```json
12 | {
13 | "Hello!": "Hola!",
14 | "Hello %s, how are you today?": "¿Hola %s, como estas?",
15 | }
16 | ```
17 | ## Usage
18 | Locales can be accessed in controllers/policies through `res.i18n()`, or in views through the `__(key)` or `i18n(key)` functions.
19 | Remember that the keys are case sensitive and require exact key matches, e.g.
20 |
21 | ```ejs
22 | <%= __('Welcome to PencilPals!') %>
23 | <%= i18n('Hello %s, how are you today?', 'Pencil Maven') %>
24 | <%= i18n('That\'s right-- you can use either i18n() or __()') %>
25 | ```
26 |
27 | ## Configuration
28 | Localization/internationalization config can be found in `config/i18n.js`, from where you can set your supported locales.
29 |
--------------------------------------------------------------------------------
/config/locales/de.json:
--------------------------------------------------------------------------------
1 | {
2 | "Welcome": "Willkommen",
3 | "A brand new app.": "Eine neue App."
4 | }
5 |
--------------------------------------------------------------------------------
/config/locales/en.json:
--------------------------------------------------------------------------------
1 | {
2 | "Welcome": "Welcome",
3 | "A brand new app.": "A brand new app."
4 | }
5 |
--------------------------------------------------------------------------------
/config/locales/es.json:
--------------------------------------------------------------------------------
1 | {
2 | "Welcome": "Bienvenido",
3 | "A brand new app.": "Una nueva aplicación."
4 | }
5 |
--------------------------------------------------------------------------------
/config/locales/fr.json:
--------------------------------------------------------------------------------
1 | {
2 | "Welcome": "Bienvenue",
3 | "A brand new app.": "Une toute nouvelle application."
4 | }
5 |
--------------------------------------------------------------------------------
/config/log.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Built-in Log Configuration
3 | * (sails.config.log)
4 | *
5 | * Configure the log level for your app, as well as the transport
6 | * (Underneath the covers, Sails uses Winston for logging, which
7 | * allows for some pretty neat custom transports/adapters for log messages)
8 | *
9 | * For more information on the Sails logger, check out:
10 | * http://sailsjs.org/#!/documentation/concepts/Logging
11 | */
12 |
13 | module.exports.log = {
14 |
15 | /***************************************************************************
16 | * *
17 | * Valid `level` configs: i.e. the minimum log level to capture with *
18 | * sails.log.*() *
19 | * *
20 | * The order of precedence for log levels from lowest to highest is: *
21 | * silly, verbose, info, debug, warn, error *
22 | * *
23 | * You may also set the level to "silent" to suppress all logs. *
24 | * *
25 | ***************************************************************************/
26 |
27 | // level: 'info'
28 |
29 | };
30 |
--------------------------------------------------------------------------------
/config/models.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Default model configuration
3 | * (sails.config.models)
4 | *
5 | * Unless you override them, the following properties will be included
6 | * in each of your models.
7 | *
8 | * For more info on Sails models, see:
9 | * http://sailsjs.org/#!/documentation/concepts/ORM
10 | */
11 |
12 | module.exports.models = {
13 |
14 | /***************************************************************************
15 | * *
16 | * Your app's default connection. i.e. the name of one of your app's *
17 | * connections (see `config/connections.js`) *
18 | * *
19 | ***************************************************************************/
20 | connection: 'sequelize_mysql',
21 |
22 | /***************************************************************************
23 | * *
24 | * How and whether Sails will attempt to automatically rebuild the *
25 | * tables/collections/etc. in your schema. *
26 | * *
27 | * See http://sailsjs.org/#!/documentation/concepts/ORM/model-settings.html *
28 | * *
29 | ***************************************************************************/
30 | migrate: 'alter'
31 |
32 | };
33 |
--------------------------------------------------------------------------------
/config/redis.js:
--------------------------------------------------------------------------------
1 |
2 | module.exports.redis = {
3 |
4 | logging:true,
5 |
6 | url: process.env.REDIS_URL,
7 |
8 | options: {
9 |
10 | }
11 |
12 | };
13 |
--------------------------------------------------------------------------------
/cron.yaml:
--------------------------------------------------------------------------------
1 | version: 1
2 | cron:
3 | - name: "last-day-splitted-stats" # required - unique across all entries in this file
4 | url: "/last-day-splitted-stats" # required - does not need to be unique
5 | schedule: "0 */12 * * *" # required - does not need to be unique
6 | - name: "update-percentile" # required - unique across all entries in this file
7 | url: "/update-percentile" # required - does not need to be unique
8 | schedule: "0 */12 * * *" # required - does not need to be unique
9 |
--------------------------------------------------------------------------------
/database.json:
--------------------------------------------------------------------------------
1 | {
2 | "defaultEnv": "development",
3 |
4 | "docker": {
5 | "driver": "mysql",
6 | "host": { "ENV": "DATABASE_HOST" },
7 | "user": { "ENV": "DATABASE_USERNAME" },
8 | "password": { "ENV": "DATABASE_PASSWORD" },
9 | "database": { "ENV": "DATABASE_NAME" },
10 | "port": { "ENV": "DATABASE_PORT" },
11 | "multipleStatements": true
12 | },
13 |
14 | "development": {
15 | "driver": "mysql",
16 | "host": { "ENV": "DATABASE_HOST" },
17 | "user": { "ENV": "DATABASE_USERNAME" },
18 | "password": { "ENV": "DATABASE_PASSWORD" },
19 | "database": { "ENV": "DATABASE_NAME" },
20 | "port": { "ENV": "DATABASE_PORT" },
21 | "multipleStatements": true
22 | },
23 |
24 | "staging": {
25 | "driver": "mysql",
26 | "host": { "ENV": "DATABASE_HOST" },
27 | "user": { "ENV": "DATABASE_USERNAME" },
28 | "password": { "ENV": "DATABASE_PASSWORD" },
29 | "database": { "ENV": "DATABASE_NAME" },
30 | "port": { "ENV": "DATABASE_PORT" },
31 | "multipleStatements": true
32 | },
33 |
34 | "worker": {
35 | "driver": "mysql",
36 | "host": { "ENV": "DATABASE_HOST" },
37 | "user": { "ENV": "DATABASE_USERNAME" },
38 | "password": { "ENV": "DATABASE_PASSWORD" },
39 | "database": { "ENV": "DATABASE_NAME" },
40 | "port": { "ENV": "DATABASE_PORT" },
41 | "multipleStatements": true
42 | },
43 |
44 | "production": {
45 | "driver": "mysql",
46 | "host": { "ENV": "DATABASE_HOST" },
47 | "user": { "ENV": "DATABASE_USERNAME" },
48 | "password": { "ENV": "DATABASE_PASSWORD" },
49 | "database": { "ENV": "DATABASE_NAME" },
50 | "port": { "ENV": "DATABASE_PORT" },
51 | "multipleStatements": true
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/deploy_worker.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | if [ -n "$(git status --porcelain)" ]; then
5 | echo "Your git directory is not clean, commit your changes before building";
6 | exit 1;
7 | fi
8 |
9 | BUILD_NUMBER=$(git rev-parse --short HEAD)
10 | #build new docker image
11 | docker build -t dockerhub.datacamp.com:443/rdocsv2:$BUILD_NUMBER .
12 | #push image to docker registery
13 | docker push dockerhub.datacamp.com:443/rdocsv2:$BUILD_NUMBER
14 |
15 | sed -e "s/\$version/$BUILD_NUMBER/" -e "s/\$memory/1500/" < Dockerrun.aws.json.in > Dockerrun.aws.json
16 |
17 | zip -r build/release.zip Dockerrun.aws.json proxy .ebextensions cron.yaml
18 |
19 | eb deploy rdocsv2-workers
20 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "2"
2 | services:
3 | db:
4 | image: mysql:latest
5 | ports:
6 | - "3306:3306"
7 | environment:
8 | MYSQL_ROOT_PASSWORD: password
9 | MYSQL_USER: rdoc
10 | MYSQL_PASSWORD: password
11 | MYSQL_DATABASE: rdocs
12 | redis:
13 | image: redis
14 | ports:
15 | - "6379:6379"
16 |
--------------------------------------------------------------------------------
/ecs.worker.json:
--------------------------------------------------------------------------------
1 | {
2 | "cluster": "${CLUSTER}",
3 | "servicePort": 1337,
4 | "serviceProtocol": "HTTP",
5 | "desiredCount": ${DESIRED_COUNT},
6 | "loadBalancer": "datacamp-services-internal",
7 | "containers": [
8 | {
9 | "containerName": "${SERVICE}-worker",
10 | "containerImage": "${CONTAINER_IMAGE}",
11 | "containerTag": "${CIRCLE_SHA1}",
12 | "containerPort": 1337,
13 | "memoryReservation": 4000,
14 | "cpu": 256,
15 | "essential": true
16 | },
17 | {
18 | "containerName": "${SERVICE}-sqsd",
19 | "containerImage": "sqsd",
20 | "containerTag": "latest",
21 | "memoryReservation": 128,
22 | "essential": true,
23 | "containerCommand": [
24 | "bash",
25 | "-c",
26 | "eval $(aws-env) && node run-cli.js"
27 | ]
28 | }
29 | ],
30 | "healthCheck": {
31 | "healthyThreshold": 3,
32 | "unhealthyThreshold": 5,
33 | "path": "/status",
34 | "interval": 60,
35 | "matcher": "200"
36 | },
37 | "ruleConditions": [
38 | {
39 | "hostname": "rdoc-worker",
40 | "listeners": [
41 | "https"
42 | ]
43 | }
44 | ]
45 | }
46 |
--------------------------------------------------------------------------------
/jake/sails-lifter.js:
--------------------------------------------------------------------------------
1 |
2 |
3 | module.exports = {
4 |
5 | lift: function(done) {
6 | var sails = require('sails');
7 | require('dotenv').config({silent: true});
8 | var liftSails = function (config, cb) {
9 | if (sails.config) {
10 | return cb();
11 | }
12 |
13 | config.hooks = {
14 | blueprints: false,
15 | controllers: false,
16 | cors: false,
17 | csrf: false,
18 | grunt: false,
19 | http: false,
20 | i18n: false,
21 | logger: false,
22 | orm:false,
23 | policies: false,
24 | pubsub: false,
25 | request: false,
26 | responses: false,
27 | //services: leave default hook,
28 | session: false,
29 | sockets: false,
30 | views: false
31 | };
32 | // Start server
33 | sails.load(config, cb);
34 | };
35 |
36 | liftSails({
37 | port: 1338,
38 | environment: process.env.NODE_ENV,
39 | tasks: true
40 | }, done);
41 | }
42 |
43 | };
44 |
--------------------------------------------------------------------------------
/migrations/20160603105133-initial.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var dbm;
4 | var type;
5 | var seed;
6 | var fs = require('fs');
7 | var path = require('path');
8 | var Promise;
9 |
10 | /**
11 | * We receive the dbmigrate dependency from dbmigrate initially.
12 | * This enables us to not have to rely on NODE_PATH.
13 | */
14 | exports.setup = function(options, seedLink) {
15 | dbm = options.dbmigrate;
16 | type = dbm.dataType;
17 | seed = seedLink;
18 | Promise = options.Promise;
19 | };
20 |
21 | exports.up = function(db) {
22 | var filePath = path.join(__dirname + '/sqls/20160603105133-migration-name-up.sql');
23 | return new Promise( function( resolve, reject ) {
24 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
25 | if (err) return reject(err);
26 | console.log('received data: ' + data);
27 |
28 | resolve(data);
29 | });
30 | })
31 | .then(function(data) {
32 | return db.runSql(data);
33 | });
34 | };
35 |
36 | exports.down = function(db) {
37 | var filePath = path.join(__dirname + '/sqls/20160603105133-migration-name-down.sql');
38 | return new Promise( function( resolve, reject ) {
39 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
40 | if (err) return reject(err);
41 | console.log('received data: ' + data);
42 |
43 | resolve(data);
44 | });
45 | })
46 | .then(function(data) {
47 | return db.runSql(data);
48 | });
49 | };
50 |
--------------------------------------------------------------------------------
/migrations/20160607121610-indexAliases.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var dbm;
4 | var type;
5 | var seed;
6 |
7 | /**
8 | * We receive the dbmigrate dependency from dbmigrate initially.
9 | * This enables us to not have to rely on NODE_PATH.
10 | */
11 | exports.setup = function(options, seedLink) {
12 | dbm = options.dbmigrate;
13 | type = dbm.dataType;
14 | seed = seedLink;
15 | };
16 |
17 | exports.up = function(db, callback) {
18 | db.addIndex('Aliases', 'name_index', 'name', callback);
19 | };
20 |
21 | exports.down = function(db) {
22 | return null;
23 | };
24 |
--------------------------------------------------------------------------------
/migrations/20160609193515-title-allow-null.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var dbm;
4 | var type;
5 | var seed;
6 | var fs = require('fs');
7 | var path = require('path');
8 | var Promise;
9 |
10 | /**
11 | * We receive the dbmigrate dependency from dbmigrate initially.
12 | * This enables us to not have to rely on NODE_PATH.
13 | */
14 | exports.setup = function(options, seedLink) {
15 | dbm = options.dbmigrate;
16 | type = dbm.dataType;
17 | seed = seedLink;
18 | Promise = options.Promise;
19 | };
20 |
21 | exports.up = function(db) {
22 | var filePath = path.join(__dirname + '/sqls/20160609193515-title-allow-null-up.sql');
23 | return new Promise( function( resolve, reject ) {
24 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
25 | if (err) return reject(err);
26 | console.log('received data: ' + data);
27 |
28 | resolve(data);
29 | });
30 | })
31 | .then(function(data) {
32 | return db.runSql(data);
33 | });
34 | };
35 |
36 | exports.down = function(db) {
37 | var filePath = path.join(__dirname + '/sqls/20160609193515-title-allow-null-down.sql');
38 | return new Promise( function( resolve, reject ) {
39 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
40 | if (err) return reject(err);
41 | console.log('received data: ' + data);
42 |
43 | resolve(data);
44 | });
45 | })
46 | .then(function(data) {
47 | return db.runSql(data);
48 | });
49 | };
50 |
--------------------------------------------------------------------------------
/migrations/20160610094821-argument-description.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var dbm;
4 | var type;
5 | var seed;
6 | var fs = require('fs');
7 | var path = require('path');
8 | var Promise;
9 |
10 | /**
11 | * We receive the dbmigrate dependency from dbmigrate initially.
12 | * This enables us to not have to rely on NODE_PATH.
13 | */
14 | exports.setup = function(options, seedLink) {
15 | dbm = options.dbmigrate;
16 | type = dbm.dataType;
17 | seed = seedLink;
18 | Promise = options.Promise;
19 | };
20 |
21 | exports.up = function(db) {
22 | var filePath = path.join(__dirname + '/sqls/20160610094821-argument-description-up.sql');
23 | return new Promise( function( resolve, reject ) {
24 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
25 | if (err) return reject(err);
26 | console.log('received data: ' + data);
27 |
28 | resolve(data);
29 | });
30 | })
31 | .then(function(data) {
32 | return db.runSql(data);
33 | });
34 | };
35 |
36 | exports.down = function(db) {
37 | var filePath = path.join(__dirname + '/sqls/20160610094821-argument-description-down.sql');
38 | return new Promise( function( resolve, reject ) {
39 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
40 | if (err) return reject(err);
41 | console.log('received data: ' + data);
42 |
43 | resolve(data);
44 | });
45 | })
46 | .then(function(data) {
47 | return db.runSql(data);
48 | });
49 | };
50 |
--------------------------------------------------------------------------------
/migrations/20160612100705-users.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var dbm;
4 | var type;
5 | var seed;
6 |
7 | /**
8 | * We receive the dbmigrate dependency from dbmigrate initially.
9 | * This enables us to not have to rely on NODE_PATH.
10 | */
11 | exports.setup = function(options, seedLink) {
12 | dbm = options.dbmigrate;
13 | type = dbm.dataType;
14 | seed = seedLink;
15 | };
16 |
17 | exports.up = function(db, cb) {
18 | db.createTable('Users', {
19 | id: { type: 'int', primaryKey: true, autoIncrement: true },
20 | username: { type: 'string', unique: true, notNull: true},
21 | password: { type: 'string', notNull: true },
22 | created_at: { type: 'datetime', notNull: true},
23 | updated_at: { type: 'datetime', notNull: true}
24 | }, cb);
25 | };
26 |
27 | exports.down = function(db, cb) {
28 | db.dropTable('Users', { ifExists: true }, cb);
29 | };
30 |
--------------------------------------------------------------------------------
/migrations/20160612150901-package-type.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var dbm;
4 | var type;
5 | var seed;
6 | var fs = require('fs');
7 | var path = require('path');
8 | var Promise;
9 |
10 | /**
11 | * We receive the dbmigrate dependency from dbmigrate initially.
12 | * This enables us to not have to rely on NODE_PATH.
13 | */
14 | exports.setup = function(options, seedLink) {
15 | dbm = options.dbmigrate;
16 | type = dbm.dataType;
17 | seed = seedLink;
18 | Promise = options.Promise;
19 | };
20 |
21 | exports.up = function(db) {
22 | var filePath = path.join(__dirname + '/sqls/20160612150901-package-type-up.sql');
23 | return new Promise( function( resolve, reject ) {
24 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
25 | if (err) return reject(err);
26 | console.log('received data: ' + data);
27 |
28 | resolve(data);
29 | });
30 | })
31 | .then(function(data) {
32 | return db.runSql(data);
33 | });
34 | };
35 |
36 | exports.down = function(db) {
37 | var filePath = path.join(__dirname + '/sqls/20160612150901-package-type-down.sql');
38 | return new Promise( function( resolve, reject ) {
39 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
40 | if (err) return reject(err);
41 | console.log('received data: ' + data);
42 |
43 | resolve(data);
44 | });
45 | })
46 | .then(function(data) {
47 | return db.runSql(data);
48 | });
49 | };
50 |
--------------------------------------------------------------------------------
/migrations/20160612161712-package-type-allow-null.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var dbm;
4 | var type;
5 | var seed;
6 | var fs = require('fs');
7 | var path = require('path');
8 | var Promise;
9 |
10 | /**
11 | * We receive the dbmigrate dependency from dbmigrate initially.
12 | * This enables us to not have to rely on NODE_PATH.
13 | */
14 | exports.setup = function(options, seedLink) {
15 | dbm = options.dbmigrate;
16 | type = dbm.dataType;
17 | seed = seedLink;
18 | Promise = options.Promise;
19 | };
20 |
21 | exports.up = function(db) {
22 | var filePath = path.join(__dirname + '/sqls/20160612161712-package-type-allow-null-up.sql');
23 | return new Promise( function( resolve, reject ) {
24 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
25 | if (err) return reject(err);
26 | console.log('received data: ' + data);
27 |
28 | resolve(data);
29 | });
30 | })
31 | .then(function(data) {
32 | return db.runSql(data);
33 | });
34 | };
35 |
36 | exports.down = function(db) {
37 | var filePath = path.join(__dirname + '/sqls/20160612161712-package-type-allow-null-down.sql');
38 | return new Promise( function( resolve, reject ) {
39 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
40 | if (err) return reject(err);
41 | console.log('received data: ' + data);
42 |
43 | resolve(data);
44 | });
45 | })
46 | .then(function(data) {
47 | return db.runSql(data);
48 | });
49 | };
50 |
--------------------------------------------------------------------------------
/migrations/20160612162625-topic-add-sourceJSON.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var dbm;
4 | var type;
5 | var seed;
6 | var fs = require('fs');
7 | var path = require('path');
8 | var Promise;
9 |
10 | /**
11 | * We receive the dbmigrate dependency from dbmigrate initially.
12 | * This enables us to not have to rely on NODE_PATH.
13 | */
14 | exports.setup = function(options, seedLink) {
15 | dbm = options.dbmigrate;
16 | type = dbm.dataType;
17 | seed = seedLink;
18 | Promise = options.Promise;
19 | };
20 |
21 | exports.up = function(db) {
22 | var filePath = path.join(__dirname + '/sqls/20160612162625-topic-add-sourceJSON-up.sql');
23 | return new Promise( function( resolve, reject ) {
24 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
25 | if (err) return reject(err);
26 | console.log('received data: ' + data);
27 |
28 | resolve(data);
29 | });
30 | })
31 | .then(function(data) {
32 | return db.runSql(data);
33 | });
34 | };
35 |
36 | exports.down = function(db) {
37 | var filePath = path.join(__dirname + '/sqls/20160612162625-topic-add-sourceJSON-down.sql');
38 | return new Promise( function( resolve, reject ) {
39 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
40 | if (err) return reject(err);
41 | console.log('received data: ' + data);
42 |
43 | resolve(data);
44 | });
45 | })
46 | .then(function(data) {
47 | return db.runSql(data);
48 | });
49 | };
50 |
--------------------------------------------------------------------------------
/migrations/20160613085210-comments.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var dbm;
4 | var type;
5 | var seed;
6 | var fs = require('fs');
7 | var path = require('path');
8 | var Promise;
9 |
10 | /**
11 | * We receive the dbmigrate dependency from dbmigrate initially.
12 | * This enables us to not have to rely on NODE_PATH.
13 | */
14 | exports.setup = function(options, seedLink) {
15 | dbm = options.dbmigrate;
16 | type = dbm.dataType;
17 | seed = seedLink;
18 | Promise = options.Promise;
19 | };
20 |
21 | exports.up = function(db) {
22 | var filePath = path.join(__dirname + '/sqls/20160613085210-comments-up.sql');
23 | return new Promise( function( resolve, reject ) {
24 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
25 | if (err) return reject(err);
26 | console.log('received data: ' + data);
27 |
28 | resolve(data);
29 | });
30 | })
31 | .then(function(data) {
32 | return db.runSql(data);
33 | });
34 | };
35 |
36 | exports.down = function(db) {
37 | var filePath = path.join(__dirname + '/sqls/20160613085210-comments-down.sql');
38 | return new Promise( function( resolve, reject ) {
39 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
40 | if (err) return reject(err);
41 | console.log('received data: ' + data);
42 |
43 | resolve(data);
44 | });
45 | })
46 | .then(function(data) {
47 | return db.runSql(data);
48 | });
49 | };
50 |
--------------------------------------------------------------------------------
/migrations/20160614083536-review-model.js:
--------------------------------------------------------------------------------
1 | var dbm = global.dbm || require('db-migrate');
2 | var type = dbm.dataType;
3 | var fs = require('fs');
4 | var path = require('path');
5 |
6 | exports.up = function(db, callback) {
7 | var filePath = path.join(__dirname + '/sqls/20160614083536-review-model-up.sql');
8 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
9 | if (err) return callback(err);
10 | console.log('received data: ' + data);
11 |
12 | db.runSql(data, function(err) {
13 | if (err) return callback(err);
14 | callback();
15 | });
16 | });
17 | };
18 |
19 | exports.down = function(db, callback) {
20 | var filePath = path.join(__dirname + '/sqls/20160614083536-review-model-down.sql');
21 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
22 | if (err) return callback(err);
23 | console.log('received data: ' + data);
24 |
25 | db.runSql(data, function(err) {
26 | if (err) return callback(err);
27 | callback();
28 | });
29 | });
30 | };
31 |
--------------------------------------------------------------------------------
/migrations/20160621104843-task-views.js:
--------------------------------------------------------------------------------
1 | var dbm = global.dbm || require('db-migrate');
2 | var type = dbm.dataType;
3 | var fs = require('fs');
4 | var path = require('path');
5 |
6 | exports.up = function(db, callback) {
7 | var filePath = path.join(__dirname + '/sqls/20160621104843-task-views-up.sql');
8 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
9 | if (err) return callback(err);
10 | console.log('received data: ' + data);
11 |
12 | db.runSql(data, function(err) {
13 | if (err) return callback(err);
14 | callback();
15 | });
16 | });
17 | };
18 |
19 | exports.down = function(db, callback) {
20 | var filePath = path.join(__dirname + '/sqls/20160621104843-task-views-down.sql');
21 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
22 | if (err) return callback(err);
23 | console.log('received data: ' + data);
24 |
25 | db.runSql(data, function(err) {
26 | if (err) return callback(err);
27 | callback();
28 | });
29 | });
30 | };
31 |
--------------------------------------------------------------------------------
/migrations/20160624081405-download-statistics.js:
--------------------------------------------------------------------------------
1 | var dbm = global.dbm || require('db-migrate');
2 | var type = dbm.dataType;
3 | var fs = require('fs');
4 | var path = require('path');
5 |
6 | exports.up = function(db, callback) {
7 | var filePath = path.join(__dirname + '/sqls/20160624081405-download-statistics-up.sql');
8 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
9 | if (err) return callback(err);
10 | console.log('received data: ' + data);
11 |
12 | db.runSql(data, function(err) {
13 | if (err) return callback(err);
14 | callback();
15 | });
16 | });
17 | };
18 |
19 | exports.down = function(db, callback) {
20 | var filePath = path.join(__dirname + '/sqls/20160624081405-download-statistics-down.sql');
21 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
22 | if (err) return callback(err);
23 | console.log('received data: ' + data);
24 |
25 | db.runSql(data, function(err) {
26 | if (err) return callback(err);
27 | callback();
28 | });
29 | });
30 | };
31 |
--------------------------------------------------------------------------------
/migrations/20160626120528-token-table.js:
--------------------------------------------------------------------------------
1 | var dbm = global.dbm || require('db-migrate');
2 | var type = dbm.dataType;
3 | var fs = require('fs');
4 | var path = require('path');
5 |
6 | exports.up = function(db, callback) {
7 | var filePath = path.join(__dirname + '/sqls/20160626120528-token-table-up.sql');
8 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
9 | if (err) return callback(err);
10 | console.log('received data: ' + data);
11 |
12 | db.runSql(data, function(err) {
13 | if (err) return callback(err);
14 | callback();
15 | });
16 | });
17 | };
18 |
19 | exports.down = function(db, callback) {
20 | var filePath = path.join(__dirname + '/sqls/20160626120528-token-table-down.sql');
21 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
22 | if (err) return callback(err);
23 | console.log('received data: ' + data);
24 |
25 | db.runSql(data, function(err) {
26 | if (err) return callback(err);
27 | callback();
28 | });
29 | });
30 | };
31 |
--------------------------------------------------------------------------------
/migrations/20160626154713-unique-review.js:
--------------------------------------------------------------------------------
1 | var dbm = global.dbm || require('db-migrate');
2 | var type = dbm.dataType;
3 |
4 | exports.up = function(db, callback) {
5 | db.addIndex('Reviews', 'review_user', ['reviewable', 'reviewable_id', 'user_id'], true, callback);
6 | };
7 |
8 | exports.down = function(db, callback) {
9 | callback();
10 | };
11 |
--------------------------------------------------------------------------------
/migrations/20160708081226-readme-in-versions.js:
--------------------------------------------------------------------------------
1 | var dbm = global.dbm || require('db-migrate');
2 | var type = dbm.dataType;
3 | var fs = require('fs');
4 | var path = require('path');
5 |
6 | exports.up = function(db, callback) {
7 | var filePath = path.join(__dirname + '/sqls/20160708081226-readme-in-versions-up.sql');
8 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
9 | if (err) return callback(err);
10 | console.log('received data: ' + data);
11 |
12 | db.runSql(data, function(err) {
13 | if (err) return callback(err);
14 | callback();
15 | });
16 | });
17 | };
18 |
19 | exports.down = function(db, callback) {
20 | var filePath = path.join(__dirname + '/sqls/20160708081226-readme-in-versions-down.sql');
21 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
22 | if (err) return callback(err);
23 | console.log('received data: ' + data);
24 |
25 | db.runSql(data, function(err) {
26 | if (err) return callback(err);
27 | callback();
28 | });
29 | });
30 | };
31 |
--------------------------------------------------------------------------------
/migrations/20160711142622-splitted-downloads.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var dbm;
4 | var type;
5 | var seed;
6 | var fs = require('fs');
7 | var path = require('path');
8 | var Promise;
9 |
10 | /**
11 | * We receive the dbmigrate dependency from dbmigrate initially.
12 | * This enables us to not have to rely on NODE_PATH.
13 | */
14 | exports.setup = function(options, seedLink) {
15 | dbm = options.dbmigrate;
16 | type = dbm.dataType;
17 | seed = seedLink;
18 | Promise = options.Promise;
19 | };
20 |
21 | exports.up = function(db) {
22 | var filePath = path.join(__dirname + '/sqls/20160711142622-splitted-downloads-up.sql');
23 | return new Promise( function( resolve, reject ) {
24 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
25 | if (err) return reject(err);
26 | console.log('received data: ' + data);
27 |
28 | resolve(data);
29 | });
30 | })
31 | .then(function(data) {
32 | return db.runSql(data);
33 | });
34 | };
35 |
36 | exports.down = function(db) {
37 | var filePath = path.join(__dirname + '/sqls/20160711142622-splitted-downloads-down.sql');
38 | return new Promise( function( resolve, reject ) {
39 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
40 | if (err) return reject(err);
41 | console.log('received data: ' + data);
42 |
43 | resolve(data);
44 | });
45 | })
46 | .then(function(data) {
47 | return db.runSql(data);
48 | });
49 | };
50 |
--------------------------------------------------------------------------------
/migrations/20160714072116-downloads-per-day.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var dbm;
4 | var type;
5 | var seed;
6 | var fs = require('fs');
7 | var path = require('path');
8 | var Promise;
9 |
10 | /**
11 | * We receive the dbmigrate dependency from dbmigrate initially.
12 | * This enables us to not have to rely on NODE_PATH.
13 | */
14 | exports.setup = function(options, seedLink) {
15 | dbm = options.dbmigrate;
16 | type = dbm.dataType;
17 | seed = seedLink;
18 | Promise = options.Promise;
19 | };
20 |
21 | exports.up = function(db) {
22 | var filePath = path.join(__dirname + '/sqls/20160714072116-downloads-per-day-up.sql');
23 | return new Promise( function( resolve, reject ) {
24 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
25 | if (err) return reject(err);
26 | console.log('received data: ' + data);
27 |
28 | resolve(data);
29 | });
30 | })
31 | .then(function(data) {
32 | return db.runSql(data);
33 | });
34 | };
35 |
36 | exports.down = function(db) {
37 | var filePath = path.join(__dirname + '/sqls/20160714072116-downloads-per-day-down.sql');
38 | return new Promise( function( resolve, reject ) {
39 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
40 | if (err) return reject(err);
41 | console.log('received data: ' + data);
42 |
43 | resolve(data);
44 | });
45 | })
46 | .then(function(data) {
47 | return db.runSql(data);
48 | });
49 | };
50 |
--------------------------------------------------------------------------------
/migrations/20160714100838-stringToText.js:
--------------------------------------------------------------------------------
1 | var dbm = global.dbm || require('db-migrate');
2 | var type = dbm.dataType;
3 | var fs = require('fs');
4 | var path = require('path');
5 |
6 | exports.up = function(db, callback) {
7 | var filePath = path.join(__dirname + '/sqls/20160714100838-stringToText-up.sql');
8 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
9 | if (err) return callback(err);
10 | console.log('received data: ' + data);
11 |
12 | db.runSql(data, function(err) {
13 | if (err) return callback(err);
14 | callback();
15 | });
16 | });
17 | };
18 |
19 | exports.down = function(db, callback) {
20 | var filePath = path.join(__dirname + '/sqls/20160714100838-stringToText-down.sql');
21 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
22 | if (err) return callback(err);
23 | console.log('received data: ' + data);
24 |
25 | db.runSql(data, function(err) {
26 | if (err) return callback(err);
27 | callback();
28 | });
29 | });
30 | };
31 |
--------------------------------------------------------------------------------
/migrations/20160714102013-add-dependency-enum.js:
--------------------------------------------------------------------------------
1 | var dbm = global.dbm || require('db-migrate');
2 | var type = dbm.dataType;
3 | var fs = require('fs');
4 | var path = require('path');
5 |
6 | exports.up = function(db, callback) {
7 | var filePath = path.join(__dirname + '/sqls/20160714102013-add-dependency-enum-up.sql');
8 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
9 | if (err) return callback(err);
10 | console.log('received data: ' + data);
11 |
12 | db.runSql(data, function(err) {
13 | if (err) return callback(err);
14 | callback();
15 | });
16 | });
17 | };
18 |
19 | exports.down = function(db, callback) {
20 | var filePath = path.join(__dirname + '/sqls/20160714102013-add-dependency-enum-down.sql');
21 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
22 | if (err) return callback(err);
23 | console.log('received data: ' + data);
24 |
25 | db.runSql(data, function(err) {
26 | if (err) return callback(err);
27 | callback();
28 | });
29 | });
30 | };
31 |
--------------------------------------------------------------------------------
/migrations/20160714113658-cascading-delete-of-sections.js:
--------------------------------------------------------------------------------
1 | var dbm = global.dbm || require('db-migrate');
2 | var type = dbm.dataType;
3 | var fs = require('fs');
4 | var path = require('path');
5 |
6 | exports.up = function(db, callback) {
7 | var filePath = path.join(__dirname + '/sqls/20160714113658-cascading-delete-of-sections-up.sql');
8 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
9 | if (err) return callback(err);
10 | console.log('received data: ' + data);
11 |
12 | db.runSql(data, function(err) {
13 | if (err) return callback(err);
14 | callback();
15 | });
16 | });
17 | };
18 |
19 | exports.down = function(db, callback) {
20 | var filePath = path.join(__dirname + '/sqls/20160714113658-cascading-delete-of-sections-down.sql');
21 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
22 | if (err) return callback(err);
23 | console.log('received data: ' + data);
24 |
25 | db.runSql(data, function(err) {
26 | if (err) return callback(err);
27 | callback();
28 | });
29 | });
30 | };
31 |
--------------------------------------------------------------------------------
/migrations/20160812141926-BiocDownloads.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var dbm;
4 | var type;
5 | var seed;
6 | var fs = require('fs');
7 | var path = require('path');
8 | var Promise;
9 |
10 | /**
11 | * We receive the dbmigrate dependency from dbmigrate initially.
12 | * This enables us to not have to rely on NODE_PATH.
13 | */
14 | exports.setup = function(options, seedLink) {
15 | dbm = options.dbmigrate;
16 | type = dbm.dataType;
17 | seed = seedLink;
18 | Promise = options.Promise;
19 | };
20 |
21 | exports.up = function(db) {
22 | var filePath = path.join(__dirname + '/sqls/20160812141926-BiocDownloads-up.sql');
23 | return new Promise( function( resolve, reject ) {
24 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
25 | if (err) return reject(err);
26 | console.log('received data: ' + data);
27 |
28 | resolve(data);
29 | });
30 | })
31 | .then(function(data) {
32 | return db.runSql(data);
33 | });
34 | };
35 |
36 | exports.down = function(db) {
37 | var filePath = path.join(__dirname + '/sqls/20160812141926-BiocDownloads-down.sql');
38 | return new Promise( function( resolve, reject ) {
39 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
40 | if (err) return reject(err);
41 | console.log('received data: ' + data);
42 |
43 | resolve(data);
44 | });
45 | })
46 | .then(function(data) {
47 | return db.runSql(data);
48 | });
49 | };
50 |
--------------------------------------------------------------------------------
/migrations/20160821202039-stars.js:
--------------------------------------------------------------------------------
1 | var dbm = global.dbm || require('db-migrate');
2 | var type = dbm.dataType;
3 | var fs = require('fs');
4 | var path = require('path');
5 |
6 | exports.up = function(db, callback) {
7 | var filePath = path.join(__dirname + '/sqls/20160821202039-stars-up.sql');
8 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
9 | if (err) return callback(err);
10 | console.log('received data: ' + data);
11 |
12 | db.runSql(data, function(err) {
13 | if (err) return callback(err);
14 | callback();
15 | });
16 | });
17 | };
18 |
19 | exports.down = function(db, callback) {
20 | var filePath = path.join(__dirname + '/sqls/20160821202039-stars-down.sql');
21 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
22 | if (err) return callback(err);
23 | console.log('received data: ' + data);
24 |
25 | db.runSql(data, function(err) {
26 | if (err) return callback(err);
27 | callback();
28 | });
29 | });
30 | };
31 |
--------------------------------------------------------------------------------
/migrations/20160822080118-examples.js:
--------------------------------------------------------------------------------
1 | var dbm = global.dbm || require('db-migrate');
2 | var type = dbm.dataType;
3 | var fs = require('fs');
4 | var path = require('path');
5 |
6 | exports.up = function(db, callback) {
7 | var filePath = path.join(__dirname + '/sqls/20160822080118-examples-up.sql');
8 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
9 | if (err) return callback(err);
10 | console.log('received data: ' + data);
11 |
12 | db.runSql(data, function(err) {
13 | if (err) return callback(err);
14 | callback();
15 | });
16 | });
17 | };
18 |
19 | exports.down = function(db, callback) {
20 | var filePath = path.join(__dirname + '/sqls/20160822080118-examples-down.sql');
21 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
22 | if (err) return callback(err);
23 | console.log('received data: ' + data);
24 |
25 | db.runSql(data, function(err) {
26 | if (err) return callback(err);
27 | callback();
28 | });
29 | });
30 | };
31 |
--------------------------------------------------------------------------------
/migrations/20160830084534-percentiles.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var dbm;
4 | var type;
5 | var seed;
6 | var fs = require('fs');
7 | var path = require('path');
8 | var Promise;
9 |
10 | /**
11 | * We receive the dbmigrate dependency from dbmigrate initially.
12 | * This enables us to not have to rely on NODE_PATH.
13 | */
14 | exports.setup = function(options, seedLink) {
15 | dbm = options.dbmigrate;
16 | type = dbm.dataType;
17 | seed = seedLink;
18 | Promise = options.Promise;
19 | };
20 |
21 | exports.up = function(db) {
22 | var filePath = path.join(__dirname + '/sqls/20160830084534-percentiles-up.sql');
23 | return new Promise( function( resolve, reject ) {
24 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
25 | if (err) return reject(err);
26 | console.log('received data: ' + data);
27 |
28 | resolve(data);
29 | });
30 | })
31 | .then(function(data) {
32 | return db.runSql(data);
33 | });
34 | };
35 |
36 | exports.down = function(db) {
37 | var filePath = path.join(__dirname + '/sqls/20160830084534-percentiles-down.sql');
38 | return new Promise( function( resolve, reject ) {
39 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
40 | if (err) return reject(err);
41 | console.log('received data: ' + data);
42 |
43 | resolve(data);
44 | });
45 | })
46 | .then(function(data) {
47 | return db.runSql(data);
48 | });
49 | };
50 |
--------------------------------------------------------------------------------
/migrations/20170809033252-parser-version.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var dbm;
4 | var type;
5 | var seed;
6 | var fs = require('fs');
7 | var path = require('path');
8 | var Promise;
9 |
10 | /**
11 | * We receive the dbmigrate dependency from dbmigrate initially.
12 | * This enables us to not have to rely on NODE_PATH.
13 | */
14 | exports.setup = function(options, seedLink) {
15 | dbm = options.dbmigrate;
16 | type = dbm.dataType;
17 | seed = seedLink;
18 | Promise = options.Promise;
19 | };
20 |
21 | exports.up = function(db) {
22 | var filePath = path.join(__dirname, 'sqls', '20170809033252-parser-version-up.sql');
23 | return new Promise( function( resolve, reject ) {
24 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
25 | if (err) return reject(err);
26 | console.log('received data: ' + data);
27 |
28 | resolve(data);
29 | });
30 | })
31 | .then(function(data) {
32 | return db.runSql(data);
33 | });
34 | };
35 |
36 | exports.down = function(db) {
37 | var filePath = path.join(__dirname, 'sqls', '20170809033252-parser-version-down.sql');
38 | return new Promise( function( resolve, reject ) {
39 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
40 | if (err) return reject(err);
41 | console.log('received data: ' + data);
42 |
43 | resolve(data);
44 | });
45 | })
46 | .then(function(data) {
47 | return db.runSql(data);
48 | });
49 | };
50 |
51 | exports._meta = {
52 | "version": 1
53 | };
54 |
--------------------------------------------------------------------------------
/migrations/20170809222533-parsing-jobs.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var dbm;
4 | var type;
5 | var seed;
6 | var fs = require('fs');
7 | var path = require('path');
8 | var Promise;
9 |
10 | /**
11 | * We receive the dbmigrate dependency from dbmigrate initially.
12 | * This enables us to not have to rely on NODE_PATH.
13 | */
14 | exports.setup = function(options, seedLink) {
15 | dbm = options.dbmigrate;
16 | type = dbm.dataType;
17 | seed = seedLink;
18 | Promise = options.Promise;
19 | };
20 |
21 | exports.up = function(db) {
22 | var filePath = path.join(__dirname, 'sqls', '20170809222533-parsing-jobs-up.sql');
23 | return new Promise( function( resolve, reject ) {
24 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
25 | if (err) return reject(err);
26 | console.log('received data: ' + data);
27 |
28 | resolve(data);
29 | });
30 | })
31 | .then(function(data) {
32 | return db.runSql(data);
33 | });
34 | };
35 |
36 | exports.down = function(db) {
37 | var filePath = path.join(__dirname, 'sqls', '20170809222533-parsing-jobs-down.sql');
38 | return new Promise( function( resolve, reject ) {
39 | fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
40 | if (err) return reject(err);
41 | console.log('received data: ' + data);
42 |
43 | resolve(data);
44 | });
45 | })
46 | .then(function(data) {
47 | return db.runSql(data);
48 | });
49 | };
50 |
51 | exports._meta = {
52 | "version": 1
53 | };
54 |
--------------------------------------------------------------------------------
/migrations/sqls/20160603105133-migration-name-down.sql:
--------------------------------------------------------------------------------
1 | # ************************************************************
2 | # Sequel Pro SQL dump
3 | # Version 4541
4 | #
5 | # http://www.sequelpro.com/
6 | # https://github.com/sequelpro/sequelpro
7 | #
8 | # Host: 192.168.99.100 (MySQL 5.7.12)
9 | # Database: rdoc
10 | # Generation Time: 2016-06-03 16:54:29 +0000
11 | # ************************************************************
12 |
13 |
14 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
15 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
16 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
17 | /*!40101 SET NAMES utf8 */;
18 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
19 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
20 | /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
21 |
22 |
23 | # Dump of table Aliases
24 | # ------------------------------------------------------------
25 |
26 | DROP TABLE IF EXISTS `Aliases`;
27 |
28 | DROP TABLE IF EXISTS `Arguments`;
29 |
30 | DROP TABLE IF EXISTS `Collaborations`;
31 |
32 | DROP TABLE IF EXISTS `Collaborators`;
33 |
34 | DROP TABLE IF EXISTS `Dependencies`;
35 |
36 | DROP TABLE IF EXISTS `Packages`;
37 |
38 | DROP TABLE IF EXISTS `PackageVersions`;
39 |
40 | DROP TABLE IF EXISTS `Sections`;
41 |
42 | DROP TABLE IF EXISTS `Tags`;
43 |
44 | DROP TABLE IF EXISTS `Topics`;
45 |
46 | DROP TABLE IF EXISTS `TopicTags`;
47 |
48 |
49 | /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
50 | /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
51 | /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
52 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
53 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
54 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
55 |
--------------------------------------------------------------------------------
/migrations/sqls/20160609193515-title-allow-null-down.sql:
--------------------------------------------------------------------------------
1 | /* Replace with your SQL commands */
--------------------------------------------------------------------------------
/migrations/sqls/20160609193515-title-allow-null-up.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE `PackageVersions` MODIFY `title` varchar(255) DEFAULT NULL;
2 |
--------------------------------------------------------------------------------
/migrations/sqls/20160610094821-argument-description-down.sql:
--------------------------------------------------------------------------------
1 | /* Replace with your SQL commands */
--------------------------------------------------------------------------------
/migrations/sqls/20160610094821-argument-description-up.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE `Arguments` MODIFY `description` TEXT DEFAULT NULL;
2 |
--------------------------------------------------------------------------------
/migrations/sqls/20160612150901-package-type-down.sql:
--------------------------------------------------------------------------------
1 | /* Replace with your SQL commands */
--------------------------------------------------------------------------------
/migrations/sqls/20160612150901-package-type-up.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE `Repositories` (
2 | `id` int(11) NOT NULL AUTO_INCREMENT,
3 | `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
4 | PRIMARY KEY (`id`)
5 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
6 |
7 | INSERT INTO Repositories (name) VALUES ('cran'),('bioconductor'),('github');
8 |
9 | ALTER TABLE `Packages` ADD COLUMN `type_id` int(11) NOT NULL;
10 |
11 | UPDATE `Packages` SET `type_id` = (SELECT id from `Repositories` Where `name` = 'cran');
12 |
13 | ALTER TABLE `Packages` ADD CONSTRAINT fk_type_id FOREIGN KEY (type_id) REFERENCES Repositories(id);
14 |
--------------------------------------------------------------------------------
/migrations/sqls/20160612161712-package-type-allow-null-down.sql:
--------------------------------------------------------------------------------
1 | /* Replace with your SQL commands */
--------------------------------------------------------------------------------
/migrations/sqls/20160612161712-package-type-allow-null-up.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE `PackageVersions` ADD COLUMN `sourceJSON` TEXT DEFAULT NULL;
2 |
3 | ALTER TABLE `Packages` MODIFY `type_id` int(11) DEFAULT NULL;
4 |
--------------------------------------------------------------------------------
/migrations/sqls/20160612162625-topic-add-sourceJSON-down.sql:
--------------------------------------------------------------------------------
1 | /* Replace with your SQL commands */
--------------------------------------------------------------------------------
/migrations/sqls/20160612162625-topic-add-sourceJSON-up.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE `Topics` ADD COLUMN `sourceJSON` TEXT DEFAULT NULL;
2 |
--------------------------------------------------------------------------------
/migrations/sqls/20160613085210-comments-down.sql:
--------------------------------------------------------------------------------
1 | /* Replace with your SQL commands */
--------------------------------------------------------------------------------
/migrations/sqls/20160613085210-comments-up.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE `Comments` (
2 | `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
3 | `description` TEXT COLLATE utf8_unicode_ci NOT NULL,
4 | `commentable` varchar(255) NOT NULL,
5 | `commentable_id` int(11) NOT NULL,
6 | `created_at` datetime NOT NULL,
7 | `updated_at` datetime NOT NULL,
8 | `user_id` int(11) NOT NULL REFERENCES Users(id) ON DELETE CASCADE ON UPDATE CASCADE
9 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
10 |
--------------------------------------------------------------------------------
/migrations/sqls/20160614083536-review-model-down.sql:
--------------------------------------------------------------------------------
1 | /* Replace with your SQL commands */
--------------------------------------------------------------------------------
/migrations/sqls/20160614083536-review-model-up.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE IF EXISTS `Comments`;
2 |
3 | CREATE TABLE `Reviews` (
4 | `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
5 | `rating` TINYINT NOT NULL,
6 | `title` varchar(255) DEFAULT NULL,
7 | `text` TEXT COLLATE utf8_unicode_ci DEFAULT NULL,
8 | `reviewable` varchar(255) NOT NULL,
9 | `reviewable_id` int(11) NOT NULL,
10 | `created_at` datetime NOT NULL,
11 | `updated_at` datetime NOT NULL,
12 | `user_id` int(11) NOT NULL REFERENCES Users(id) ON DELETE CASCADE ON UPDATE CASCADE
13 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
14 |
--------------------------------------------------------------------------------
/migrations/sqls/20160621104843-task-views-down.sql:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datacamp/rdocumentation-app/3642111a3bfcae6c934e8aca4889c005ca90167d/migrations/sqls/20160621104843-task-views-down.sql
--------------------------------------------------------------------------------
/migrations/sqls/20160621104843-task-views-up.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE `TaskViews` (
2 | `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
3 | `name` varchar(255) NOT NULL,
4 | `url` varchar(255) NOT NULL,
5 | `created_at` datetime NOT NULL,
6 | `updated_at` datetime NOT NULL,
7 | UNIQUE KEY `task_name_unique` (`name`)
8 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
9 |
10 | CREATE TABLE `TaskViewPackages` (
11 | `task_id` int(11) NOT NULL,
12 | `package_name` varchar(255) NOT NULL,
13 | PRIMARY KEY (`task_id`,`package_name`),
14 | CONSTRAINT `TaskViews_ibfk_1` FOREIGN KEY (`task_id`) REFERENCES `TaskViews` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
15 | CONSTRAINT `TaskViewPackages_ibfk_1` FOREIGN KEY (`package_name`) REFERENCES `Packages` (`name`) ON DELETE CASCADE ON UPDATE CASCADE
16 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
17 |
--------------------------------------------------------------------------------
/migrations/sqls/20160624081405-download-statistics-down.sql:
--------------------------------------------------------------------------------
1 | /* Replace with your SQL commands */
--------------------------------------------------------------------------------
/migrations/sqls/20160624081405-download-statistics-up.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE `DownloadStatistics` (
2 | `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
3 | `package_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
4 | `last_month_downloads` int(11) NOT NULL,
5 | `created_at` datetime NOT NULL,
6 | `updated_at` datetime NOT NULL,
7 | UNIQUE KEY `package` (`package_name`),
8 | FOREIGN KEY (`package_name`) REFERENCES `Packages` (`name`) ON DELETE CASCADE ON UPDATE CASCADE
9 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
10 |
--------------------------------------------------------------------------------
/migrations/sqls/20160626120528-token-table-down.sql:
--------------------------------------------------------------------------------
1 | /* Replace with your SQL commands */
--------------------------------------------------------------------------------
/migrations/sqls/20160626120528-token-table-up.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE `ApiTokens` (
2 | `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
3 | `token` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
4 | `can_create` BOOL NOT NULL DEFAULT 0,
5 | `can_update` BOOL NOT NULL DEFAULT 0,
6 | `can_delete` BOOL NOT NULL DEFAULT 0,
7 | `expire_at` datetime NOT NULL,
8 | UNIQUE KEY `token_unq` (`token`)
9 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
10 |
--------------------------------------------------------------------------------
/migrations/sqls/20160708081226-readme-in-versions-down.sql:
--------------------------------------------------------------------------------
1 | /* Replace with your SQL commands */
--------------------------------------------------------------------------------
/migrations/sqls/20160708081226-readme-in-versions-up.sql:
--------------------------------------------------------------------------------
1 | /* Replace with your SQL commands */
2 |
3 | ALTER TABLE PackageVersions ADD readmemd TEXT DEFAULT NULL AFTER copyright;
4 |
--------------------------------------------------------------------------------
/migrations/sqls/20160711142622-splitted-downloads-down.sql:
--------------------------------------------------------------------------------
1 | /* Replace with your SQL commands */
--------------------------------------------------------------------------------
/migrations/sqls/20160711142622-splitted-downloads-up.sql:
--------------------------------------------------------------------------------
1 | /* Replace with your SQL commands */
2 | ALTER TABLE DownloadStatistics
3 | ADD (`last_month_downloads_direct` int(11) NOT NULL,
4 | `last_month_downloads_indirect` int(11) NOT NULL);
5 |
--------------------------------------------------------------------------------
/migrations/sqls/20160714072116-downloads-per-day-down.sql:
--------------------------------------------------------------------------------
1 | /* Replace with your SQL commands */
--------------------------------------------------------------------------------
/migrations/sqls/20160714072116-downloads-per-day-up.sql:
--------------------------------------------------------------------------------
1 | /* Replace with your SQL commands */
2 | ALTER TABLE `DownloadStatistics`
3 | DROP `last_month_downloads_direct`,
4 | DROP `last_month_downloads_indirect`,
5 | DROP `last_month_downloads`;
6 |
7 | ALTER TABLE DownloadStatistics
8 | ADD (`direct_downloads` int(11) NOT NULL,
9 | `indirect_downloads` int(11) NOT NULL,
10 | `date` DATE NOT NULL);
11 |
12 | CREATE INDEX package_name_index ON DownloadStatistics(package_name);
13 | CREATE UNIQUE INDEX package_month ON DownloadStatistics(package_name,date);
14 | ALTER TABLE DownloadStatistics DROP INDEX package;
15 |
--------------------------------------------------------------------------------
/migrations/sqls/20160714100838-stringToText-down.sql:
--------------------------------------------------------------------------------
1 | /* Replace with your SQL commands */
--------------------------------------------------------------------------------
/migrations/sqls/20160714100838-stringToText-up.sql:
--------------------------------------------------------------------------------
1 | /* Replace with your SQL commands */
2 |
3 | ALTER TABLE `PackageVersions` MODIFY `license` TEXT DEFAULT NULL;
4 | ALTER TABLE `PackageVersions` MODIFY `title` TEXT DEFAULT NULL;
5 | ALTER TABLE `PackageVersions` MODIFY `copyright` TEXT DEFAULT NULL;
6 |
--------------------------------------------------------------------------------
/migrations/sqls/20160714102013-add-dependency-enum-down.sql:
--------------------------------------------------------------------------------
1 | /* Replace with your SQL commands */
--------------------------------------------------------------------------------
/migrations/sqls/20160714102013-add-dependency-enum-up.sql:
--------------------------------------------------------------------------------
1 | /* Replace with your SQL commands */
2 |
3 | ALTER TABLE Dependencies CHANGE type type ENUM('depends','imports','suggests','enhances', 'linkingto');
4 |
--------------------------------------------------------------------------------
/migrations/sqls/20160714113658-cascading-delete-of-sections-down.sql:
--------------------------------------------------------------------------------
1 | /* Replace with your SQL commands */
--------------------------------------------------------------------------------
/migrations/sqls/20160714113658-cascading-delete-of-sections-up.sql:
--------------------------------------------------------------------------------
1 | /* Replace with your SQL commands */
2 |
3 | ALTER TABLE Aliases DROP FOREIGN KEY `Aliases_ibfk_1`;
4 |
5 | ALTER TABLE Aliases ADD CONSTRAINT `Aliases_ibfk_1` FOREIGN KEY (`topic_id`)
6 | REFERENCES `Topics` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
7 |
8 | ALTER TABLE Arguments DROP FOREIGN KEY `Arguments_ibfk_1`;
9 |
10 | ALTER TABLE Arguments ADD CONSTRAINT `Arguments_ibfk_1` FOREIGN KEY (`topic_id`)
11 | REFERENCES `Topics` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
12 |
13 | ALTER TABLE Sections DROP FOREIGN KEY `Sections_ibfk_1`;
14 |
15 | ALTER TABLE Sections ADD CONSTRAINT `Sections_ibfk_1` FOREIGN KEY (`topic_id`)
16 | REFERENCES `Topics` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
17 |
18 | DELETE FROM Aliases WHERE topic_id IS NULL;
19 | DELETE FROM Arguments WHERE topic_id IS NULL;
20 | DELETE FROM Sections WHERE topic_id IS NULL;
21 |
--------------------------------------------------------------------------------
/migrations/sqls/20160812141926-BiocDownloads-down.sql:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datacamp/rdocumentation-app/3642111a3bfcae6c934e8aca4889c005ca90167d/migrations/sqls/20160812141926-BiocDownloads-down.sql
--------------------------------------------------------------------------------
/migrations/sqls/20160812141926-BiocDownloads-up.sql:
--------------------------------------------------------------------------------
1 | /* Replace with your SQL commands */
2 | --
3 | -- Table structure for table `BiocDownloadStatistics`
4 | --
5 |
6 | DROP TABLE IF EXISTS `BiocDownloadStatistics`;
7 | /*!40101 SET @saved_cs_client = @@character_set_client */;
8 | /*!40101 SET character_set_client = utf8 */;
9 | CREATE TABLE `BiocDownloadStatistics` (
10 | `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
11 | `package_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
12 | `distinct_ips` int(11) NOT NULL,
13 | `downloads` int(11) NOT NULL,
14 | `created_at` datetime NOT NULL,
15 | `updated_at` datetime NOT NULL,
16 | `date` DATE NOT NULL,
17 | FOREIGN KEY (`package_name`) REFERENCES `Packages` (`name`) ON DELETE CASCADE ON UPDATE CASCADE
18 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
19 |
20 | CREATE UNIQUE INDEX bioc_package_month ON BiocDownloadStatistics(package_name,date);
21 |
--------------------------------------------------------------------------------
/migrations/sqls/20160821202039-stars-down.sql:
--------------------------------------------------------------------------------
1 | /* Replace with your SQL commands */
--------------------------------------------------------------------------------
/migrations/sqls/20160821202039-stars-up.sql:
--------------------------------------------------------------------------------
1 | /* Replace with your SQL commands */
2 | --
3 | -- Table structure for table `BiocDownloadStatistics`
4 | --
5 |
6 | DROP TABLE IF EXISTS `Stars`;
7 | /*!40101 SET @saved_cs_client = @@character_set_client */;
8 | /*!40101 SET character_set_client = utf8 */;
9 | CREATE TABLE `Stars` (
10 | `user_id` int(11) NOT NULL,
11 | `package_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
12 | `created_at` datetime NOT NULL,
13 | `updated_at` datetime NOT NULL,
14 | FOREIGN KEY (`package_name`) REFERENCES `Packages` (`name`) ON DELETE CASCADE ON UPDATE CASCADE,
15 | FOREIGN KEY (`user_id`) REFERENCES `Users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
16 | PRIMARY KEY (`user_id`,`package_name`)
17 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
18 |
--------------------------------------------------------------------------------
/migrations/sqls/20160822080118-examples-down.sql:
--------------------------------------------------------------------------------
1 | /* Replace with your SQL commands */
--------------------------------------------------------------------------------
/migrations/sqls/20160822080118-examples-up.sql:
--------------------------------------------------------------------------------
1 | /* Replace with your SQL commands */
2 | --
3 | -- Table structure for table `BiocDownloadStatistics`
4 | --
5 |
6 | DROP TABLE IF EXISTS `Examples`;
7 | /*!40101 SET @saved_cs_client = @@character_set_client */;
8 | /*!40101 SET character_set_client = utf8 */;
9 | CREATE TABLE `Examples` (
10 | `id` int(11) NOT NULL AUTO_INCREMENT,
11 | `user_id` int(11) NOT NULL,
12 | `topic_id` int(11) NOT NULL,
13 | `example` text NOT NULL COLLATE utf8_unicode_ci,
14 | `created_at` datetime NOT NULL,
15 | `updated_at` datetime NOT NULL,
16 | FOREIGN KEY (`topic_id`) REFERENCES `Topics` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
17 | FOREIGN KEY (`user_id`) REFERENCES `Users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
18 | PRIMARY KEY (`id`)
19 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
20 |
--------------------------------------------------------------------------------
/migrations/sqls/20160830084534-percentiles-down.sql:
--------------------------------------------------------------------------------
1 | /* Replace with your SQL commands */
--------------------------------------------------------------------------------
/migrations/sqls/20160830084534-percentiles-up.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE IF EXISTS `Percentiles`;
2 |
3 | CREATE TABLE `Percentiles` (
4 | `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
5 | `percentile` double(5,2) NOT NULL,
6 | `value` int(11) NOT NULL,
7 | `created_at` datetime NOT NULL,
8 | `updated_at` datetime NOT NULL,
9 | UNIQUE (percentile)
10 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
--------------------------------------------------------------------------------
/migrations/sqls/20170809033252-parser-version-down.sql:
--------------------------------------------------------------------------------
1 | /* Replace with your SQL commands */
--------------------------------------------------------------------------------
/migrations/sqls/20170809033252-parser-version-up.sql:
--------------------------------------------------------------------------------
1 | /* Replace with your SQL commands */
2 | ALTER TABLE `PackageVersions` ADD COLUMN `parser_version` int(11) DEFAULT 0;
3 |
--------------------------------------------------------------------------------
/migrations/sqls/20170809222533-parsing-jobs-down.sql:
--------------------------------------------------------------------------------
1 | /* Replace with your SQL commands */
--------------------------------------------------------------------------------
/migrations/sqls/20170809222533-parsing-jobs-up.sql:
--------------------------------------------------------------------------------
1 | /* Replace with your SQL commands */
2 | ALTER TABLE `PackageVersions` DROP COLUMN `parser_version`;
3 |
4 | CREATE TABLE `ParsingJobs` (
5 | `package_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
6 | `package_version` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
7 | `parser_version` int(11) DEFAULT 0,
8 | `parsed_at` datetime NOT NULL,
9 | `parsing_status` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
10 | `error` text COLLATE utf8_unicode_ci DEFAULT NULL,
11 | PRIMARY KEY(`package_name`, `package_version`)
12 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
13 |
14 | INSERT INTO `ParsingJobs` (`package_name`, `package_version`, `parsed_at`, `parsing_status`)
15 | SELECT `package_name`, `version`, NOW(), "succes"
16 | FROM `PackageVersions`
17 |
--------------------------------------------------------------------------------
/newrelic.js:
--------------------------------------------------------------------------------
1 | exports.config = {
2 | app_name: [process.env.NEW_RELIC_APP],
3 | license_key: 'e6cd6d8afacfcc7191c34c933af26309dfa57cc6',
4 | logging: {
5 | level: 'warn', // can be error, warn, info, debug or trace
6 | rules: {
7 | ignore: ['^/socket.io/*/xhr-polling']
8 | }
9 | }
10 | };
11 |
--------------------------------------------------------------------------------
/tasks/config/apidoc.js:
--------------------------------------------------------------------------------
1 |
2 | module.exports = function(grunt) {
3 |
4 | grunt.config.set('apidoc',{
5 | doc: {
6 | src: "api/",
7 | dest: ".tmp/public/docs",
8 | options: {
9 | includeFilters: [ ".*\\.js$" ],
10 | }
11 | }
12 | });
13 |
14 | grunt.loadNpmTasks('grunt-apidoc');
15 |
16 | };
17 |
--------------------------------------------------------------------------------
/tasks/config/clean.js:
--------------------------------------------------------------------------------
1 | /**
2 | * `clean`
3 | *
4 | * ---------------------------------------------------------------
5 | *
6 | * Remove the files and folders in your Sails app's web root
7 | * (conventionally a hidden directory called `.tmp/public`).
8 | *
9 | * For usage docs see:
10 | * https://github.com/gruntjs/grunt-contrib-clean
11 | *
12 | */
13 | module.exports = function(grunt) {
14 |
15 | grunt.config.set('clean', {
16 | dev: ['.tmp/public/**'],
17 | build: ['www']
18 | });
19 |
20 | grunt.loadNpmTasks('grunt-contrib-clean');
21 | };
22 |
--------------------------------------------------------------------------------
/tasks/config/coffee.js:
--------------------------------------------------------------------------------
1 | /**
2 | * `coffee`
3 | *
4 | * ---------------------------------------------------------------
5 | *
6 | * Compile CoffeeScript files located in `assets/js` into Javascript
7 | * and generate new `.js` files in `.tmp/public/js`.
8 | *
9 | * For usage docs see:
10 | * https://github.com/gruntjs/grunt-contrib-coffee
11 | *
12 | */
13 | module.exports = function(grunt) {
14 |
15 | grunt.config.set('coffee', {
16 | dev: {
17 | options: {
18 | bare: true,
19 | sourceMap: true,
20 | sourceRoot: './'
21 | },
22 | files: [{
23 | expand: true,
24 | cwd: 'assets/js/',
25 | src: ['**/*.coffee'],
26 | dest: '.tmp/public/js/',
27 | ext: '.js'
28 | }]
29 | }
30 | });
31 |
32 | grunt.loadNpmTasks('grunt-contrib-coffee');
33 | };
34 |
--------------------------------------------------------------------------------
/tasks/config/concat.js:
--------------------------------------------------------------------------------
1 | /**
2 | * `concat`
3 | *
4 | * ---------------------------------------------------------------
5 | *
6 | * Concatenates the contents of multiple JavaScript and/or CSS files
7 | * into two new files, each located at `concat/production.js` and
8 | * `concat/production.css` respectively in `.tmp/public/concat`.
9 | *
10 | * This is used as an intermediate step to generate monolithic files
11 | * that can then be passed in to `uglify` and/or `cssmin` for minification.
12 | *
13 | * For usage docs see:
14 | * https://github.com/gruntjs/grunt-contrib-concat
15 | *
16 | */
17 | module.exports = function(grunt) {
18 |
19 | grunt.config.set('concat', {
20 | js: {
21 | src: require('../pipeline').jsFilesToInject,
22 | dest: '.tmp/public/concat/production.js'
23 | },
24 | css: {
25 | src: require('../pipeline').cssFilesToInject,
26 | dest: '.tmp/public/concat/production.css'
27 | }
28 | });
29 |
30 | grunt.loadNpmTasks('grunt-contrib-concat');
31 | };
32 |
--------------------------------------------------------------------------------
/tasks/config/copy.js:
--------------------------------------------------------------------------------
1 | /**
2 | * `copy`
3 | *
4 | * ---------------------------------------------------------------
5 | *
6 | * Copy files and/or folders from your `assets/` directory into
7 | * the web root (`.tmp/public`) so they can be served via HTTP,
8 | * and also for further pre-processing by other Grunt tasks.
9 | *
10 | * #### Normal usage (`sails lift`)
11 | * Copies all directories and files (except CoffeeScript and LESS)
12 | * from the `assets/` folder into the web root -- conventionally a
13 | * hidden directory located `.tmp/public`.
14 | *
15 | * #### Via the `build` tasklist (`sails www`)
16 | * Copies all directories and files from the .tmp/public directory into a www directory.
17 | *
18 | * For usage docs see:
19 | * https://github.com/gruntjs/grunt-contrib-copy
20 | *
21 | */
22 | module.exports = function(grunt) {
23 |
24 | grunt.config.set('copy', {
25 | dev: {
26 | files: [{
27 | expand: true,
28 | cwd: './assets',
29 | src: ['**/*.!(coffee|scss)'],
30 | dest: '.tmp/public'
31 | }
32 | ]
33 | },
34 | build: {
35 | files: [{
36 | expand: true,
37 | cwd: '.tmp/public',
38 | src: ['**/*'],
39 | dest: 'www'
40 | }]
41 | }
42 | });
43 |
44 | grunt.loadNpmTasks('grunt-contrib-copy');
45 | };
46 |
--------------------------------------------------------------------------------
/tasks/config/cssmin.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Compress CSS files.
3 | *
4 | * ---------------------------------------------------------------
5 | *
6 | * Minify the intermediate concatenated CSS stylesheet which was
7 | * prepared by the `concat` task at `.tmp/public/concat/production.css`.
8 | *
9 | * Together with the `concat` task, this is the final step that minifies
10 | * all CSS files from `assets/styles/` (and potentially your LESS importer
11 | * file from `assets/styles/importer.less`)
12 | *
13 | * For usage docs see:
14 | * https://github.com/gruntjs/grunt-contrib-cssmin
15 | *
16 | */
17 | module.exports = function(grunt) {
18 |
19 | grunt.config.set('cssmin', {
20 | dist: {
21 | src: ['.tmp/public/concat/production.css'],
22 | dest: '.tmp/public/min/production.min.css'
23 | }
24 | });
25 |
26 | grunt.loadNpmTasks('grunt-contrib-cssmin');
27 | };
28 |
--------------------------------------------------------------------------------
/tasks/config/jst.js:
--------------------------------------------------------------------------------
1 | /**
2 | * `jst`
3 | *
4 | * ---------------------------------------------------------------
5 | *
6 | * Precompile HTML templates using Underscore/Lodash notation into
7 | * functions, creating a `.jst` file. This can be brought into your HTML
8 | * via a
49 |
50 |
--------------------------------------------------------------------------------
/views/task_view/_sidebar.ejs:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/views/task_view/index.ejs:
--------------------------------------------------------------------------------
1 |
2 | <%- include ../task_view/_sidebar.ejs %>
3 |
4 |
5 |
--------------------------------------------------------------------------------
/views/task_view/show.ejs:
--------------------------------------------------------------------------------
1 | <% var view = data; %>
2 |
43 |
--------------------------------------------------------------------------------
/views/topic/_header.ejs:
--------------------------------------------------------------------------------
1 |
25 |
--------------------------------------------------------------------------------
/views/user/show.ejs:
--------------------------------------------------------------------------------
1 | <% var user = data; %>
2 | <% var user_examples = user.examples; %>
3 |
4 |
5 |
6 | <%- user.username %>
7 |
8 |
9 |
10 | My Examples
11 |
12 | <% if(user_examples.length === 0) { %>
13 |
Looks like there are no examples yet.
14 | <% } %>
15 | <% for(var i=0; i < user_examples.length; i++) { %>
16 | <% var exampleUser = null; %>
17 | <% var exampleTarget = (user_examples[i].topic); %>
18 | <%- include ../shared/_example.ejs %>
19 | <% } %>
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------