├── api ├── models │ ├── .gitkeep │ ├── Star.js │ ├── Repository.js │ ├── Argument.js │ ├── Section.js │ ├── Tag.js │ ├── Percentile.js │ ├── ApiToken.js │ ├── TaskView.js │ ├── ParsingJob.js │ ├── Example.js │ ├── Review.js │ └── BiocDownloadStatistics.js ├── services │ ├── .gitkeep │ ├── FlashService.js │ ├── CronService.js │ ├── PackageVersionService.js │ └── RedisService.js ├── controllers │ ├── .gitkeep │ ├── HomeController.js │ ├── CampusController.js │ └── AuthController.js ├── _apidoc.js ├── hooks │ ├── aws │ │ └── index.js │ ├── elasticsearch │ │ └── index.js │ ├── worker │ │ └── index.js │ └── redis │ │ └── index.js ├── policies │ ├── flash.js │ ├── sessionAuth.js │ └── api_auth.js └── responses │ ├── rstudio_redirect.js │ ├── ok.js │ └── created.js ├── assets ├── images │ ├── .gitkeep │ ├── logo.png │ ├── logo-dark.png │ ├── placeholder.png │ └── GitHub-Mark-32px.png ├── templates │ └── .gitkeep ├── favicon.ico ├── 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 │ ├── pages │ │ ├── _package-readme.scss │ │ ├── _task-views.scss │ │ ├── _error-page.scss │ │ ├── _authentication.scss │ │ ├── _user.scss │ │ ├── _topic-header.scss │ │ ├── _task-view-sidebar.scss │ │ ├── _package-vignettes.scss │ │ ├── _trends.scss │ │ ├── _topic.scss │ │ ├── _package.scss │ │ ├── _package-source.scss │ │ ├── _shared.scss │ │ └── _examples.scss │ ├── widgets │ │ ├── _modal.scss │ │ ├── _big-number.scss │ │ ├── _loader.scss │ │ └── mono-blue.css │ ├── styleguide │ │ └── partials │ │ │ ├── _labels.scss │ │ │ ├── _rstudio.scss │ │ │ ├── _lists.scss │ │ │ └── _tables.scss │ └── jquery-ui │ │ ├── tabs.scss │ │ └── core.scss ├── robots.txt ├── js │ ├── helpers │ │ ├── toggle.js │ │ ├── boot.js │ │ └── list-table-filtering.js │ ├── libs │ │ ├── jquery.cookie-1.4.1.min.js │ │ └── experiment.js │ └── pages │ │ ├── collaborator.js │ │ └── user.js └── css │ └── bootstrap-treeview.css ├── migrations ├── sqls │ ├── 20160621104843-task-views-down.sql │ ├── 20160812141926-BiocDownloads-down.sql │ ├── 20160821202039-stars-down.sql │ ├── 20160612150901-package-type-down.sql │ ├── 20160613085210-comments-down.sql │ ├── 20160614083536-review-model-down.sql │ ├── 20160626120528-token-table-down.sql │ ├── 20160714100838-stringToText-down.sql │ ├── 20160822080118-examples-down.sql │ ├── 20160830084534-percentiles-down.sql │ ├── 20170809222533-parsing-jobs-down.sql │ ├── 20160609193515-title-allow-null-down.sql │ ├── 20160714072116-downloads-per-day-down.sql │ ├── 20170809033252-parser-version-down.sql │ ├── 20160610094821-argument-description-down.sql │ ├── 20160612162625-topic-add-sourceJSON-down.sql │ ├── 20160624081405-download-statistics-down.sql │ ├── 20160708081226-readme-in-versions-down.sql │ ├── 20160711142622-splitted-downloads-down.sql │ ├── 20160714102013-add-dependency-enum-down.sql │ ├── 20160612161712-package-type-allow-null-down.sql │ ├── 20160714113658-cascading-delete-of-sections-down.sql │ ├── 20160610094821-argument-description-up.sql │ ├── 20160612162625-topic-add-sourceJSON-up.sql │ ├── 20160609193515-title-allow-null-up.sql │ ├── 20170809033252-parser-version-up.sql │ ├── 20160708081226-readme-in-versions-up.sql │ ├── 20160612161712-package-type-allow-null-up.sql │ ├── 20160714102013-add-dependency-enum-up.sql │ ├── 20160711142622-splitted-downloads-up.sql │ ├── 20160714100838-stringToText-up.sql │ ├── 20160830084534-percentiles-up.sql │ ├── 20160626120528-token-table-up.sql │ ├── 20160613085210-comments-up.sql │ ├── 20160624081405-download-statistics-up.sql │ ├── 20160614083536-review-model-up.sql │ ├── 20160714072116-downloads-per-day-up.sql │ ├── 20160612150901-package-type-up.sql │ ├── 20160821202039-stars-up.sql │ ├── 20170809222533-parsing-jobs-up.sql │ ├── 20160822080118-examples-up.sql │ ├── 20160621104843-task-views-up.sql │ ├── 20160812141926-BiocDownloads-up.sql │ ├── 20160714113658-cascading-delete-of-sections-up.sql │ └── 20160603105133-migration-name-down.sql ├── 20160626154713-unique-review.js ├── 20160607121610-indexAliases.js ├── 20160612100705-users.js ├── 20160821202039-stars.js ├── 20160822080118-examples.js ├── 20160621104843-task-views.js ├── 20160626120528-token-table.js ├── 20160614083536-review-model.js ├── 20160714100838-stringToText.js ├── 20160708081226-readme-in-versions.js ├── 20160624081405-download-statistics.js ├── 20160714102013-add-dependency-enum.js ├── 20160714113658-cascading-delete-of-sections.js ├── 20160613085210-comments.js ├── 20160830084534-percentiles.js ├── 20160603105133-initial.js ├── 20160612150901-package-type.js ├── 20160812141926-BiocDownloads.js ├── 20160609193515-title-allow-null.js ├── 20160711142622-splitted-downloads.js ├── 20160714072116-downloads-per-day.js ├── 20160610094821-argument-description.js ├── 20160612162625-topic-add-sourceJSON.js ├── 20160612161712-package-type-allow-null.js ├── 20170809222533-parsing-jobs.js └── 20170809033252-parser-version.js ├── views ├── rstudio_layout.ejs ├── task_view │ ├── index.ejs │ ├── _sidebar.ejs │ └── show.ejs ├── shared │ ├── _loader.ejs │ ├── _dc_footer.ejs │ ├── _percentile.ejs │ ├── _navigation.ejs │ ├── _post_example.ejs │ ├── _flash.ejs │ ├── _footer.ejs │ ├── _example.ejs │ └── _snowplow.ejs ├── rStudio │ ├── view.ejs │ ├── update.ejs │ ├── make_default.ejs │ ├── list_options.ejs │ ├── package_not_found.ejs │ └── topic_not_found.ejs ├── campus │ └── help.ejs ├── 404.ejs ├── 403.ejs ├── inner_layout.ejs ├── 500.ejs ├── package_version │ ├── readme.ejs │ ├── vignette.ejs │ └── source.ejs ├── package │ └── show.ejs ├── auth │ ├── modalLogin.ejs │ ├── login.ejs │ └── register.ejs ├── user │ └── show.ejs ├── topic │ └── _header.ejs ├── badges │ ├── version_badge.ejs │ └── downloads_badge.ejs └── search │ ├── result.ejs │ ├── function_results.ejs │ ├── package_results.ejs │ └── keyword_result.ejs ├── config ├── locales │ ├── de.json │ ├── en.json │ ├── es.json │ ├── fr.json │ └── _README.md ├── redis.js ├── elasticsearch.js ├── bootstrap.js ├── env │ ├── worker.js │ ├── production.js │ ├── staging.js │ ├── docker.js │ └── development.js ├── log.js └── models.js ├── .dockerignore ├── apidoc.json ├── .sailsrc ├── .editorconfig ├── newrelic.js ├── .env.sample ├── tasks ├── config │ ├── apidoc.js │ ├── versioning.js │ ├── clean.js │ ├── uglify.js │ ├── sails-tasks.js │ ├── coffee.js │ ├── watch.js │ ├── cssmin.js │ ├── sync.js │ ├── concat.js │ ├── sass.js │ ├── copy.js │ └── jst.js └── register │ ├── syncAssets.js │ ├── compileAssets.js │ ├── linkAssetsBuild.js │ ├── linkAssetsBuildProd.js │ ├── linkAssets.js │ ├── prod.js │ ├── default.js │ ├── buildProd.js │ └── build.js ├── docker-compose.yml ├── Procfile ├── catalog-info.yaml ├── cron.yaml ├── .ebextensions └── 10docker.config ├── test └── test-version-ordering.js ├── deploy_worker.sh ├── .eslintrc ├── Dockerfile ├── jake └── sails-lifter.js ├── LICENSE.md ├── ecs.worker.json ├── Dockerrun.aws.json.in ├── database.json ├── app.js └── ecs.json /api/models/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /api/services/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/images/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /api/controllers/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/templates/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /migrations/sqls/20160621104843-task-views-down.sql: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /migrations/sqls/20160812141926-BiocDownloads-down.sql: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /views/rstudio_layout.ejs: -------------------------------------------------------------------------------- 1 | <%- partial ('inner_layout.ejs') %> 2 | -------------------------------------------------------------------------------- /migrations/sqls/20160821202039-stars-down.sql: -------------------------------------------------------------------------------- 1 | /* Replace with your SQL commands */ -------------------------------------------------------------------------------- /migrations/sqls/20160612150901-package-type-down.sql: -------------------------------------------------------------------------------- 1 | /* Replace with your SQL commands */ -------------------------------------------------------------------------------- /migrations/sqls/20160613085210-comments-down.sql: -------------------------------------------------------------------------------- 1 | /* Replace with your SQL commands */ -------------------------------------------------------------------------------- /migrations/sqls/20160614083536-review-model-down.sql: -------------------------------------------------------------------------------- 1 | /* Replace with your SQL commands */ -------------------------------------------------------------------------------- /migrations/sqls/20160626120528-token-table-down.sql: -------------------------------------------------------------------------------- 1 | /* Replace with your SQL commands */ -------------------------------------------------------------------------------- /migrations/sqls/20160714100838-stringToText-down.sql: -------------------------------------------------------------------------------- 1 | /* Replace with your SQL commands */ -------------------------------------------------------------------------------- /migrations/sqls/20160822080118-examples-down.sql: -------------------------------------------------------------------------------- 1 | /* Replace with your SQL commands */ -------------------------------------------------------------------------------- /migrations/sqls/20160830084534-percentiles-down.sql: -------------------------------------------------------------------------------- 1 | /* Replace with your SQL commands */ -------------------------------------------------------------------------------- /migrations/sqls/20170809222533-parsing-jobs-down.sql: -------------------------------------------------------------------------------- 1 | /* Replace with your SQL commands */ -------------------------------------------------------------------------------- /migrations/sqls/20160609193515-title-allow-null-down.sql: -------------------------------------------------------------------------------- 1 | /* Replace with your SQL commands */ -------------------------------------------------------------------------------- /migrations/sqls/20160714072116-downloads-per-day-down.sql: -------------------------------------------------------------------------------- 1 | /* Replace with your SQL commands */ -------------------------------------------------------------------------------- /migrations/sqls/20170809033252-parser-version-down.sql: -------------------------------------------------------------------------------- 1 | /* Replace with your SQL commands */ -------------------------------------------------------------------------------- /migrations/sqls/20160610094821-argument-description-down.sql: -------------------------------------------------------------------------------- 1 | /* Replace with your SQL commands */ -------------------------------------------------------------------------------- /migrations/sqls/20160612162625-topic-add-sourceJSON-down.sql: -------------------------------------------------------------------------------- 1 | /* Replace with your SQL commands */ -------------------------------------------------------------------------------- /migrations/sqls/20160624081405-download-statistics-down.sql: -------------------------------------------------------------------------------- 1 | /* Replace with your SQL commands */ -------------------------------------------------------------------------------- /migrations/sqls/20160708081226-readme-in-versions-down.sql: -------------------------------------------------------------------------------- 1 | /* Replace with your SQL commands */ -------------------------------------------------------------------------------- /migrations/sqls/20160711142622-splitted-downloads-down.sql: -------------------------------------------------------------------------------- 1 | /* Replace with your SQL commands */ -------------------------------------------------------------------------------- /migrations/sqls/20160714102013-add-dependency-enum-down.sql: -------------------------------------------------------------------------------- 1 | /* Replace with your SQL commands */ -------------------------------------------------------------------------------- /assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datacamp/rdocumentation-app/HEAD/assets/favicon.ico -------------------------------------------------------------------------------- /migrations/sqls/20160612161712-package-type-allow-null-down.sql: -------------------------------------------------------------------------------- 1 | /* Replace with your SQL commands */ -------------------------------------------------------------------------------- /assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datacamp/rdocumentation-app/HEAD/assets/images/logo.png -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /migrations/sqls/20160714113658-cascading-delete-of-sections-down.sql: -------------------------------------------------------------------------------- 1 | /* Replace with your SQL commands */ -------------------------------------------------------------------------------- /assets/images/logo-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datacamp/rdocumentation-app/HEAD/assets/images/logo-dark.png -------------------------------------------------------------------------------- /config/locales/es.json: -------------------------------------------------------------------------------- 1 | { 2 | "Welcome": "Bienvenido", 3 | "A brand new app.": "Una nueva aplicación." 4 | } 5 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .tmp/ 2 | node_modules/ 3 | .env 4 | .newrelic_agent.log 5 | Procfile 6 | docker-compose.yml 7 | err.log 8 | -------------------------------------------------------------------------------- /assets/images/placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datacamp/rdocumentation-app/HEAD/assets/images/placeholder.png -------------------------------------------------------------------------------- /config/locales/fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "Welcome": "Bienvenue", 3 | "A brand new app.": "Une toute nouvelle application." 4 | } 5 | -------------------------------------------------------------------------------- /assets/sitemap/sitemap-1.xml.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datacamp/rdocumentation-app/HEAD/assets/sitemap/sitemap-1.xml.gz -------------------------------------------------------------------------------- /assets/sitemap/sitemap-2.xml.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datacamp/rdocumentation-app/HEAD/assets/sitemap/sitemap-2.xml.gz -------------------------------------------------------------------------------- /assets/sitemap/sitemap-3.xml.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datacamp/rdocumentation-app/HEAD/assets/sitemap/sitemap-3.xml.gz -------------------------------------------------------------------------------- /assets/sitemap/sitemap-4.xml.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datacamp/rdocumentation-app/HEAD/assets/sitemap/sitemap-4.xml.gz -------------------------------------------------------------------------------- /assets/sitemap/sitemap-5.xml.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datacamp/rdocumentation-app/HEAD/assets/sitemap/sitemap-5.xml.gz -------------------------------------------------------------------------------- /migrations/sqls/20160610094821-argument-description-up.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE `Arguments` MODIFY `description` TEXT DEFAULT NULL; 2 | -------------------------------------------------------------------------------- /migrations/sqls/20160612162625-topic-add-sourceJSON-up.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE `Topics` ADD COLUMN `sourceJSON` TEXT DEFAULT NULL; 2 | -------------------------------------------------------------------------------- /assets/images/GitHub-Mark-32px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datacamp/rdocumentation-app/HEAD/assets/images/GitHub-Mark-32px.png -------------------------------------------------------------------------------- /assets/sitemap/sitemapindex.xml.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datacamp/rdocumentation-app/HEAD/assets/sitemap/sitemapindex.xml.gz -------------------------------------------------------------------------------- /migrations/sqls/20160609193515-title-allow-null-up.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE `PackageVersions` MODIFY `title` varchar(255) DEFAULT NULL; 2 | -------------------------------------------------------------------------------- /views/task_view/index.ejs: -------------------------------------------------------------------------------- 1 |
2 | <%- include ../task_view/_sidebar.ejs %> 3 |
4 |
5 | -------------------------------------------------------------------------------- /views/shared/_loader.ejs: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 |
6 |
7 |
8 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /views/rStudio/view.ejs: -------------------------------------------------------------------------------- 1 |
3 | <%if(data[k]!= null){%> 4 | data-<%=k%> = "<%=data[k]%>" 5 | <%}%> 6 | <%}%>>
-------------------------------------------------------------------------------- /views/campus/help.ejs: -------------------------------------------------------------------------------- 1 |
3 | <%if(data[k]!= null){%> 4 | data-<%=k%> = "<%=data[k]%>" 5 | <%}%> 6 | <%}%>>
7 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/_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 | } -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /views/404.ejs: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

404

5 |

Page not found

6 |
7 |
8 | The page you were trying to reach doesn't exist. 9 |
10 |
11 |
-------------------------------------------------------------------------------- /views/403.ejs: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

403

5 |

Forbidden

6 |
7 |
8 | You don't have permission to see the page you're trying to reach. 9 |
10 |
11 |
-------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /views/inner_layout.ejs: -------------------------------------------------------------------------------- 1 | <% if (path === '/') { %> 2 | <%- partial ('shared/_flash.ejs') %> 3 | <%- body %> 4 | <% } else { %> 5 | 6 | <%- partial ('shared/_navbar.ejs') %> 7 |
8 | 9 | <%- partial ('shared/_flash.ejs') %> 10 | <%- body %> 11 |
12 | 13 | <%- partial ('shared/_footer.ejs') %> 14 | <% } %> 15 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/_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/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/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 | } -------------------------------------------------------------------------------- /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; -------------------------------------------------------------------------------- /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 | } -------------------------------------------------------------------------------- /views/task_view/_sidebar.ejs: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Task View

4 |
5 |
6 | <% for(var i = 0; i 7 | <%- data[i].name %> 8 | <% } %> 9 |
10 | 11 |
12 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /tasks/config/versioning.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | 3 | grunt.config.set('versioning', { 4 | options: { 5 | keepOriginal: false 6 | }, 7 | js: { 8 | src: [ 9 | '.tmp/public/min/production.min.js', 10 | ] 11 | }, 12 | css: { 13 | src: [ 14 | '.tmp/public/min/production.min.css' 15 | ] 16 | }, 17 | }); 18 | grunt.loadNpmTasks('grunt-version-assets'); 19 | }; 20 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /views/shared/_dc_footer.ejs: -------------------------------------------------------------------------------- 1 | <% if (dcBanner) { %> 2 | 9 | <% }%> 10 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /views/500.ejs: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

500

5 |

Internal Server Error

6 |

Something isn't right here.

7 |
8 |
9 | We have been notified of the issue. 10 | If the problem persists, please create an issue on our github page. 11 |
12 |
13 |
14 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /views/shared/_percentile.ejs: -------------------------------------------------------------------------------- 1 | <% if (percentilePath) { %> 2 |
3 | 4 | 0th 5 | 6 |

Percentile

7 |
8 | <% } else { %> 9 |
10 | 11 | <%= percentile %>th 12 | 13 |

Percentile

14 |
15 | <% } %> 16 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /tasks/config/uglify.js: -------------------------------------------------------------------------------- 1 | /** 2 | * `uglify` 3 | * 4 | * --------------------------------------------------------------- 5 | * 6 | * Minify client-side JavaScript files using UglifyJS. 7 | * 8 | * For usage docs see: 9 | * https://github.com/gruntjs/grunt-contrib-uglify 10 | * 11 | */ 12 | module.exports = function(grunt) { 13 | 14 | grunt.config.set('uglify', { 15 | dist: { 16 | src: ['.tmp/public/concat/production.js'], 17 | dest: '.tmp/public/min/production.min.js' 18 | } 19 | }); 20 | 21 | grunt.loadNpmTasks('grunt-contrib-uglify'); 22 | }; 23 | -------------------------------------------------------------------------------- /views/rStudio/update.ejs: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |
Please update your RDocumentation package
6 |
7 |

8 | You are using an outdated version of the RDocumentation package, to continue to use RDocumentation inside RStudio, please update your package. 9 |

10 |
11 | 12 |
13 |
14 |
15 |
16 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /tasks/register/syncAssets.js: -------------------------------------------------------------------------------- 1 | /** 2 | * `syncAssets` 3 | * 4 | * --------------------------------------------------------------- 5 | * 6 | * This Grunt tasklist is not designed to be used directly-- rather 7 | * it is a helper called by the `watch` task (`tasks/config/watch.js`). 8 | * 9 | * For more information see: 10 | * http://sailsjs.org/documentation/anatomy/my-app/tasks/register/sync-assets-js 11 | * 12 | */ 13 | module.exports = function(grunt) { 14 | grunt.registerTask('syncAssets', [ 15 | 'jst:dev', 16 | 'sass:dev', 17 | 'sync:dev', 18 | 'coffee:dev' 19 | ]); 20 | }; 21 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /views/package_version/readme.ejs: -------------------------------------------------------------------------------- 1 | <% var pkgVersion = data; %> 2 |
3 | <%- include ../package_version/_header.ejs %> 4 | 5 |
6 | <% if(pkgVersion.readmemd) { %> 7 |
8 |

Readme

9 | <% if(pkgVersion.url) { %> 10 | <%- md(pkgVersion.readmemd,pkgVersion.url.autoLink({ target: "_blank", id: "1" })) %> 11 | <%} %> 12 | <% if(!pkgVersion.url) {%> 13 | <%-md(pkgVersion.readmemd,"") %> 14 | <% }%> 15 | 16 |
17 | <% } %> 18 |
19 | 20 |
21 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /test/test-version-ordering.js: -------------------------------------------------------------------------------- 1 | const lifter = require('../jake/sails-lifter'); 2 | const _ = require('lodash'); 3 | const should = require('chai').should() 4 | 5 | describe('Version ordering', function() { 6 | this.timeout(30000); 7 | before(function(done) { 8 | lifter.lift(function(err, sails) { 9 | this.sails = sails; 10 | done() 11 | }); 12 | }) 13 | 14 | it('should order versions properly', (done) => { 15 | var versions = ['0.43-8', '1.4.1.1', '1.10', '1.2a.1', '1.1-0']; 16 | var expected = [ '1.10', '1.4.1.1', '1.2a.1', '1.1-0', '0.43-8' ]; 17 | versions.should.deep.equal(expected); 18 | done() 19 | }) 20 | }) 21 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /views/package/show.ejs: -------------------------------------------------------------------------------- 1 | <% var package = data; %> 2 |
3 |
4 |
5 |

<%- package.name %>

6 |
7 | 8 |

No versions for package <%- package.name %>

9 | 10 |
11 |

Reverse Dependencies

12 | 17 |
18 |
19 |
20 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /tasks/register/compileAssets.js: -------------------------------------------------------------------------------- 1 | /** 2 | * `compileAssets` 3 | * 4 | * --------------------------------------------------------------- 5 | * 6 | * This Grunt tasklist is not designed to be used directly-- rather 7 | * it is a helper called by the `default`, `prod`, `build`, and 8 | * `buildProd` tasklists. 9 | * 10 | * For more information see: 11 | * http://sailsjs.org/documentation/anatomy/my-app/tasks/register/compile-assets-js 12 | * 13 | */ 14 | module.exports = function(grunt) { 15 | grunt.registerTask('compileAssets', [ 16 | 'clean:dev', 17 | 'jst:dev', 18 | 'sass:dev', 19 | 'copy:dev', 20 | 'coffee:dev', 21 | 'apidoc:doc' 22 | ]); 23 | 24 | 25 | }; 26 | -------------------------------------------------------------------------------- /views/package_version/vignette.ejs: -------------------------------------------------------------------------------- 1 | <% var vignette = data; %> 2 |
3 |
4 |
5 |
6 |
7 |
8 |

<%- vignette.title %> 9 |

10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | <%- vignette.file %> 18 |
19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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 | } -------------------------------------------------------------------------------- /tasks/register/linkAssetsBuild.js: -------------------------------------------------------------------------------- 1 | /** 2 | * `linkAssetsBuild` 3 | * 4 | * --------------------------------------------------------------- 5 | * 6 | * This Grunt tasklist is not designed to be used directly-- rather 7 | * it is a helper called by the `build` tasklist. 8 | * 9 | * For more information see: 10 | * http://sailsjs.org/documentation/anatomy/my-app/tasks/register/link-assets-build-js 11 | * 12 | */ 13 | module.exports = function(grunt) { 14 | grunt.registerTask('linkAssetsBuild', [ 15 | 'sails-linker:devJsRelative', 16 | 'sails-linker:devStylesRelative', 17 | 'sails-linker:devTpl', 18 | 'sails-linker:devJsRelativeJade', 19 | 'sails-linker:devStylesRelativeJade', 20 | 'sails-linker:devTplJade' 21 | ]); 22 | }; 23 | -------------------------------------------------------------------------------- /views/auth/modalLogin.ejs: -------------------------------------------------------------------------------- 1 |
2 |

Sign in

3 |
4 |
5 | 6 | 7 |
8 |
9 | 10 | 11 |
12 |
13 | 14 |
15 |
16 |
17 |
18 |
19 |

Or create an account

20 |
21 |
22 | -------------------------------------------------------------------------------- /tasks/register/linkAssetsBuildProd.js: -------------------------------------------------------------------------------- 1 | /** 2 | * `linkAssetsBuildProd` 3 | * 4 | * --------------------------------------------------------------- 5 | * 6 | * This Grunt tasklist is not designed to be used directly-- rather 7 | * it is a helper called by the `buildProd` tasklist. 8 | * 9 | * For more information see: 10 | * http://sailsjs.org/documentation/anatomy/my-app/tasks/register/link-assets-build-prod-js 11 | * 12 | */ 13 | module.exports = function(grunt) { 14 | grunt.registerTask('linkAssetsBuildProd', [ 15 | 'sails-linker:prodJsRelative', 16 | 'sails-linker:prodStylesRelative', 17 | 'sails-linker:devTpl', 18 | 'sails-linker:prodJsRelativeJade', 19 | 'sails-linker:prodStylesRelativeJade', 20 | 'sails-linker:devTplJade' 21 | ]); 22 | }; 23 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /tasks/register/linkAssets.js: -------------------------------------------------------------------------------- 1 | /** 2 | * `linkAssets` 3 | * 4 | * --------------------------------------------------------------- 5 | * 6 | * This Grunt tasklist is not designed to be used directly-- rather 7 | * it is a helper called by the `default` tasklist and the `watch` task 8 | * (but only if the `grunt-sails-linker` package is in use). 9 | * 10 | * For more information see: 11 | * http://sailsjs.org/documentation/anatomy/my-app/tasks/register/link-assets-js 12 | * 13 | */ 14 | module.exports = function(grunt) { 15 | grunt.registerTask('linkAssets', [ 16 | 'sails-linker:devJs', 17 | 'sails-linker:devStyles', 18 | 'sails-linker:devTpl', 19 | 'sails-linker:devJsJade', 20 | 'sails-linker:devStylesJade', 21 | 'sails-linker:devTplJade' 22 | ]); 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 | -------------------------------------------------------------------------------- /tasks/config/sails-tasks.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = function(grunt) { 3 | 4 | grunt.config.set('sails_tasks', { 5 | authorCleaning: { 6 | functions: [ 7 | function (callback) { 8 | AuthorService.aggregateAuthors().then(function(result) { 9 | console.log("Finished cleaning authors"); 10 | callback(); 11 | }); 12 | } 13 | ] 14 | }, 15 | 16 | maintainerRecover: { 17 | functions: [ 18 | function (callback) { 19 | AuthorService.recoverMaintainer().then(function(result) { 20 | console.log("Finished recover maitainers"); 21 | callback(); 22 | }); 23 | } 24 | ] 25 | }, 26 | }); 27 | 28 | 29 | grunt.loadNpmTasks('grunt-sails-tasks'); 30 | }; 31 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /views/shared/_navigation.ejs: -------------------------------------------------------------------------------- 1 | 15 | -------------------------------------------------------------------------------- /views/shared/_post_example.ejs: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 | 6 | 7 |
8 |
9 | <% if(user){ %> 10 | 11 | <% }else{ %> 12 | 13 | <% } %> 14 |
15 |
16 |
17 |
18 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /tasks/register/prod.js: -------------------------------------------------------------------------------- 1 | /** 2 | * `prod` 3 | * 4 | * --------------------------------------------------------------- 5 | * 6 | * This Grunt tasklist will be executed instead of `default` when 7 | * your Sails app is lifted in a production environment (e.g. using 8 | * `NODE_ENV=production node app`). 9 | * 10 | * For more information see: 11 | * http://sailsjs.org/documentation/anatomy/my-app/tasks/register/prod-js 12 | * 13 | */ 14 | module.exports = function(grunt) { 15 | grunt.registerTask('prod', [ 16 | 'compileAssets', 17 | 'concat', 18 | 'uglify', 19 | 'cssmin', 20 | 'versioning', 21 | 'sails-linker:prodJs', 22 | 'sails-linker:prodStyles', 23 | 'sails-linker:devTpl', 24 | 'sails-linker:prodJsJade', 25 | 'sails-linker:prodStylesJade', 26 | 'sails-linker:devTplJade' 27 | ]); 28 | }; 29 | -------------------------------------------------------------------------------- /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/register/default.js: -------------------------------------------------------------------------------- 1 | /** 2 | * `default` 3 | * 4 | * --------------------------------------------------------------- 5 | * 6 | * This is the default Grunt tasklist that will be executed if you 7 | * run `grunt` in the top level directory of your app. It is also 8 | * called automatically when you start Sails in development mode using 9 | * `sails lift` or `node app`. 10 | * 11 | * Note that when lifting your app in a production environment (with the 12 | * `NODE_ENV` environment variable set to 'production') the `prod` task 13 | * will be run instead of this one. 14 | * 15 | * For more information see: 16 | * http://sailsjs.org/documentation/anatomy/my-app/tasks/register/default-js 17 | * 18 | */ 19 | module.exports = function (grunt) { 20 | grunt.registerTask('default', ['compileAssets', 'linkAssets', 'watch']); 21 | }; 22 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /tasks/config/watch.js: -------------------------------------------------------------------------------- 1 | /** 2 | * `watch` 3 | * 4 | * --------------------------------------------------------------- 5 | * 6 | * Run predefined tasks whenever watched file patterns are added, changed or deleted. 7 | * 8 | * Watch for changes on: 9 | * - files in the `assets` folder 10 | * - the `tasks/pipeline.js` file 11 | * and re-run the appropriate tasks. 12 | * 13 | * For usage docs see: 14 | * https://github.com/gruntjs/grunt-contrib-watch 15 | * 16 | */ 17 | module.exports = function(grunt) { 18 | 19 | grunt.config.set('watch', { 20 | assets: { 21 | 22 | // Assets to watch: 23 | files: ['assets/**/*', 'tasks/pipeline.js', '!**/node_modules/**'], 24 | 25 | // When assets are changed: 26 | tasks: ['syncAssets' , 'linkAssets' ] 27 | } 28 | }); 29 | 30 | grunt.loadNpmTasks('grunt-contrib-watch'); 31 | }; 32 | -------------------------------------------------------------------------------- /views/shared/_flash.ejs: -------------------------------------------------------------------------------- 1 | <% if(typeof messages !== 'undefined') { %> 2 | <% if (messages && messages['error'].length > 0) { %> 3 | <% messages['error'].forEach(function(message) { %> 4 |
5 | <%= message %>
6 |
7 | <% }); %> 8 | <% } %> 9 | <% if (messages && messages['warning'].length > 0) { %> 10 | <% messages['warning'].forEach(function(message) { %> 11 |
12 | <%= message %>
13 |
14 | <% }); %> 15 | <% } %> 16 | <% if (messages && messages['success'].length > 0) { %> 17 | <% messages['success'].forEach(function(message) { %> 18 |
19 | <%= message %>
20 |
21 | <% }); %> 22 | <% } %> 23 | <% } %> -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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/register/buildProd.js: -------------------------------------------------------------------------------- 1 | /** 2 | * `buildProd` 3 | * 4 | * --------------------------------------------------------------- 5 | * 6 | * This Grunt tasklist will be executed instead of `build` if you 7 | * run `sails www` in a production environment, e.g.: 8 | * `NODE_ENV=production sails www` 9 | * 10 | * This generates a folder containing your compiled (and usually minified) 11 | * assets. The most common use case for this is bundling up files to 12 | * deploy to a CDN. 13 | * 14 | * For more information see: 15 | * http://sailsjs.org/documentation/anatomy/my-app/tasks/register/build-prod-js 16 | * 17 | */ 18 | module.exports = function(grunt) { 19 | grunt.registerTask('buildProd', [ 20 | 'compileAssets', 21 | 'concat', 22 | 'uglify', 23 | 'cssmin', 24 | 'linkAssetsBuildProd', 25 | 'clean:build', 26 | 'copy:build' 27 | ]); 28 | }; 29 | 30 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /views/package_version/source.ejs: -------------------------------------------------------------------------------- 1 | <% var pkgVersion = data; %> 2 |
3 |
4 | 8 |
9 | 10 |
11 |
12 |
13 | 14 |
15 |
16 |

No Source Code Found.

17 |
18 | 19 |
20 | -------------------------------------------------------------------------------- /tasks/config/sync.js: -------------------------------------------------------------------------------- 1 | /** 2 | * `sync` 3 | * 4 | * --------------------------------------------------------------- 5 | * 6 | * Synchronize files from the `assets` folder to `.tmp/public`, 7 | * smashing anything that's already there. 8 | * 9 | * This task synchronizes one directory with another (like rsync). 10 | * In the default Sails asset pipeline, it plays very similar role 11 | * to `grunt-contrib-copy`, but copies only those files that have 12 | * actually changed since the last time the task was run. 13 | * 14 | * For usage docs see: 15 | * https://github.com/tomusdrw/grunt-sync 16 | * 17 | */ 18 | module.exports = function(grunt) { 19 | 20 | grunt.config.set('sync', { 21 | dev: { 22 | files: [{ 23 | cwd: './assets', 24 | src: ['**/*.!(coffee|less)'], 25 | dest: '.tmp/public' 26 | }] 27 | } 28 | }); 29 | 30 | grunt.loadNpmTasks('grunt-sync'); 31 | }; 32 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /views/shared/_footer.ejs: -------------------------------------------------------------------------------- 1 | 24 | -------------------------------------------------------------------------------- /tasks/register/build.js: -------------------------------------------------------------------------------- 1 | /** 2 | * `build` 3 | * 4 | * --------------------------------------------------------------- 5 | * 6 | * This Grunt tasklist will be executed if you run `sails www` or 7 | * `grunt build` in a development environment. It generates a 8 | * folder containing your compiled assets, e.g. for troubleshooting 9 | * issues with other Grunt plugins, bundling assets for an Electron 10 | * or PhoneGap app, or deploying your app's flat files to a CDN. 11 | * 12 | * Note that when running `sails www` in a production environment (with the 13 | * `NODE_ENV` environment variable set to 'production') the `buildProd` task 14 | * will be run instead of this one. 15 | * 16 | * For more information see: 17 | * http://sailsjs.org/documentation/anatomy/my-app/tasks/register/build-js 18 | * 19 | */ 20 | module.exports = function(grunt) { 21 | grunt.registerTask('build', [ 22 | 'compileAssets', 23 | 'linkAssetsBuild', 24 | 'clean:build', 25 | 'copy:build' 26 | ]); 27 | }; 28 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /views/rStudio/make_default.ejs: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |
Do you want to make RDocumentation your default help package?
6 |
7 |

8 | The RDocumentation package enhances the normal R help function by searching in the online database instead of your local database, providing an easy way to install packages and execute the examples on function-pages and more. Making this package your default package will provide the help pages on RDocumentation when you are online, and will automatically fall back on the normal help function if you are offline. 9 |

10 |
11 | 12 |
13 |
14 | 15 |
16 |
17 |
18 | -------------------------------------------------------------------------------- /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/sass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * `less` 3 | * 4 | * --------------------------------------------------------------- 5 | * 6 | * Compile your LESS files into a CSS stylesheet. 7 | * 8 | * By default, only the `assets/styles/importer.less` is compiled. 9 | * This allows you to control the ordering yourself, i.e. import your 10 | * dependencies, mixins, variables, resets, etc. before other stylesheets) 11 | * 12 | * For usage docs see: 13 | * https://github.com/gruntjs/grunt-contrib-less 14 | * 15 | */ 16 | 17 | var nodeSassGlobbing = require('node-sass-globbing'); 18 | 19 | module.exports = function(grunt) { 20 | 21 | grunt.config.set('sass', { 22 | dev: { 23 | files: [{ 24 | expand: true, 25 | cwd: 'assets/styles/', 26 | src: ['application.scss'], 27 | dest: '.tmp/public/styles/', 28 | ext: '.css' 29 | }], 30 | options: { 31 | importer: nodeSassGlobbing 32 | } 33 | } 34 | }); 35 | 36 | grunt.loadNpmTasks('grunt-sass'); 37 | }; 38 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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/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/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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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/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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /views/auth/login.ejs: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |

Sign in

6 |
7 |
8 | 9 | 10 |
11 |
12 | 13 | 14 |
15 |
16 | 17 |
18 |
19 |
20 |
21 |
22 |
23 |

Or create an account

24 |
25 |
26 |
27 |
28 | 29 | -------------------------------------------------------------------------------- /views/rStudio/list_options.ejs: -------------------------------------------------------------------------------- 1 | <% var topics = data; %> 2 |
3 |
4 |
5 |

Multiple matching functions

6 |
7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | <% for(var i = 0; i < topics.length; i++) { %> 19 | <% var topic = topics[i]; %> 20 | 21 | 22 | 23 | 24 | 25 | <% } %> 26 | 27 | 28 |
NamePackageDescription
<%= topic.function_name %> (alias:<%=topic.function_alias%>)<%- topic.package_name %><%- topic.function_description%>
No Results!
29 |
30 |
31 |
32 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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. -------------------------------------------------------------------------------- /views/topic/_header.ejs: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 |

<%- topic.name %>

7 |
8 |
9 |
10 |
11 | From <%- topic.package_version.package_name %> v<%- topic.package_version.version %> 12 | <% if(topic.package_version.maintainer) { %> 13 | by <%- topic.package_version.maintainer.name %> 14 | <% } %> 15 |
16 |
17 | <% var percentilePath = "/api/packages/"+topic.package_version.package_name+"/percentile" %> 18 | <%- include ../shared/_percentile.ejs %> 19 |
20 |
21 |
22 |
23 |
24 |
25 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /views/rStudio/package_not_found.ejs: -------------------------------------------------------------------------------- 1 | <% var packages = data; %> 2 |
3 |
4 |
5 |

There where no packages found matching your search term

6 | <%if(packages.length>0){ %> 7 | Perhaps you meant one of these: 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | <% for(var i = 0; i < packages.length; ++i) { %> 19 | <%var package = package[i];%> 20 | 21 | 22 | 23 | 24 | <% } %> 25 | 26 | 27 |
PackageDescription
<%= package.name %><%-package.description%>
No Results!
28 |
29 | <%}%> 30 |
31 |
32 |
33 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /views/badges/version_badge.ejs: -------------------------------------------------------------------------------- 1 | <% var versionInfo = data; %> 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 17 | 18 | rdocumentation 19 | 20 | 21 | rdocumentation 22 | 23 | 24 | <%=versionInfo.version%> 25 | 26 | 27 | <%=versionInfo.version%> 28 | 29 | 30 | -------------------------------------------------------------------------------- /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 | } -------------------------------------------------------------------------------- /views/auth/register.ejs: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 |
6 |

Create an account and provide feedback to package authors

7 |
8 |
9 | 10 | 11 |
12 |
13 | 14 | 15 |
16 |
17 | 18 | 19 |
20 |
21 |
22 |
23 |
24 | 25 |
26 |
27 |
28 |
29 |
30 |
31 | -------------------------------------------------------------------------------- /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))}}); -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /views/badges/downloads_badge.ejs: -------------------------------------------------------------------------------- 1 | <% var downloadstats = data; %> 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 16 | 17 | <%=downloadstats.statsName%> 18 | 19 | 20 | <%=downloadstats.statsName%> 21 | 22 | 23 | <%=downloadstats.downloads%>/<%=downloadstats.period%> 24 | 25 | 26 | <%=downloadstats.downloads%>/<%=downloadstats.period%> 27 | 28 | 29 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /views/rStudio/topic_not_found.ejs: -------------------------------------------------------------------------------- 1 | <% var topics = data; %> 2 |
3 |
4 |
5 |

There where no functions found matching your search term

6 | <%if(topics.length>0){ %> 7 | Perhaps you meant one of these: 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | <% for(var i = 0; i < topics.length; ++i) { %> 20 | <%var topic = topics[i];%> 21 | 22 | 23 | 24 | 25 | 26 | <% } %> 27 | 28 | 29 |
NamePackageDescription
<%= topic.function_name %> (alias:<%=topic.function_alias%>)<%- topic.package_name %><%- topic.function_description%>
No Results!
30 |
31 | <%}%> 32 |
33 |
34 |
35 | -------------------------------------------------------------------------------- /views/search/result.ejs: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

Search Results for <%- data.query %>

5 | Why do I see these results? 6 |
7 |
8 |
9 | 10 |
11 |
12 | 13 |
14 |
15 | 16 |
17 |
18 | 19 |
20 |
21 |
22 |
23 |
24 |
25 | 26 |
27 | 31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | 41 |
42 |
43 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /views/search/function_results.ejs: -------------------------------------------------------------------------------- 1 |

Functions

2 | <%= data.hits %> results 3 |
4 | <% for (var i = 0; i < data.functions.length; i++) { %> 5 | <% var hit = data.functions[i]; %> 6 | <% var versionURI = '/packages/' + encodeURIComponent(hit.fields.package_name) + '/versions/' + encodeURIComponent(hit.fields.version); %> 7 |
8 |
9 | 10 | <%= hit.fields.name %> 11 | 12 |
13 | in <%=hit.fields.package_name%> v<%=hit.fields.version %> by <%= hit.fields.maintainer %> 14 |

<%- hit.title %>

15 |

<%- hit.description %>

16 |
17 | <% } %> 18 |
19 |
20 | Previous Results 21 | Next Results 22 |
23 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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/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/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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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/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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /views/search/package_results.ejs: -------------------------------------------------------------------------------- 1 |

Packages

2 | <%= data.hits %> results 3 |
4 | <% for (var i = 0; i < data.packages.length; i++) { %> 5 | <% var hit = data.packages[i]; %> 6 |
7 |
8 |
9 | 10 | <%= hit.fields.package_name + ' v' + hit.fields.version %> 11 | 12 |
13 | by <%= hit.fields.maintainer %> 14 |
15 | <% var percentilePath = "/api/packages/" + hit.fields.package_name + "/percentile" %> 16 |
<%- include ../shared/_percentile.ejs %>
17 |

<%- hit.description %>

18 |
19 | <% } %> 20 |
21 |
22 | Previous Results 23 | Next Results 24 |
25 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /views/shared/_example.ejs: -------------------------------------------------------------------------------- 1 |
2 | <% if(exampleTarget!==null){ %> 3 |

<%- exampleTarget.package_version.package_name+": "+exampleTarget.name %>

4 | <% } %> 5 |
> 7 |
8 | 9 | <% if(exampleUser !== null) { %> 10 | <%= exampleUser.username %> 11 | at 12 | <% } %> 13 | <%= dateformat(user_examples[i].created_at, "mediumDate") %> 14 | 15 | <% if(user && user_examples[i].user_id===user.id) { %> 16 |
17 | Edit 18 | Remove 19 |
20 | <% } %> 21 | <% if(user_examples[i].topic){ %> 22 | 23 | <%= user_examples[i].topic.package_version.package_name %> 24 | 25 | v<%= user_examples[i].topic.package_version.version %> 26 | 27 | 28 | <% } %> 29 |
30 |
31 |

33 | data-package-name = '<%=user_examples[i].topic.package_version.package_name%>' 34 | <%}%> 35 | > 36 | <%= user_examples[i].example %> 37 |

38 |
39 |
40 |
41 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /views/shared/_snowplow.ejs: -------------------------------------------------------------------------------- 1 | 2 | 49 | 50 | -------------------------------------------------------------------------------- /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