From d2d4a1e05c9dda8ce3fffb37d8b8016574bb2a70 Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Wed, 3 Jan 2018 19:18:12 -0500 Subject: [PATCH 1/8] Improve "Sharing" docs --- docs/business/sharing.rst | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/docs/business/sharing.rst b/docs/business/sharing.rst index 2700f703a4f..8c37a8133fe 100644 --- a/docs/business/sharing.rst +++ b/docs/business/sharing.rst @@ -4,26 +4,39 @@ Sharing .. note:: This feature only exists on our Business offering at `readthedocs.com `_. You can share your project with users outside of your company. -This works by sending them a link, -which will allow them to view a specific project inside your company. +There are two way to do this: + +* by sending them a *secret link*, +* by giving them a *password*. + +These methods will allow them to view a specific project inside your company. Enabling ~~~~~~~~ -* Go into your *Project Admin* page and to the *Sharing* link. -* Under the *Add Token* heading, add a *Description* so you remember who you're sharing it with. -* Click *Share* to create. -* Copy the link that is generated, and give that to the person who you want to give access. +* Go into your *Project Admin* page and to the *Sharing* menu. +* Under the *Share with someone new* heading, select the way you prefer (secret link or password), add an expiration date and a *Description* so you remember who you're sharing it with. +* Click *Share!* to create. +* Get the info needed to share your documentation with other users: + * If you have selected secret link, copy the link that is generated + * In case of password, copy the link and password +* Give that information to the person who you want to give access. .. note:: You can always revoke access in the same panel. Effects ~~~~~~~ +Secret Link +*********** + Once the person you send the link to clicks the link, they will have access to view your project. -It will only work for the specific browser that they click the link from. -.. warning:: They will be able to share this token with other people, - so only share with people you trust. - We only let sharing links be activated **five** times to prevent abuse. +Password +******** + +Once the person you send the link to clicks on the link, they will see +a *Authorization required* page asking them for the password you +generated. When the user enters the password, they will have access to +view your project. From a9239fd5dc8ad891fff768f2a8b59debc95eac18 Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Fri, 23 Feb 2018 12:32:46 -0500 Subject: [PATCH 2/8] Upgrade django-pagination to a "maintained" fork Closes #3664 The package `django-pagination` got unmaintained, so a fork by Linaro was created at https://github.com/zyga/django-pagination and got unmaintained again (https://github.com/zyga/django-pagination/issues/42). Now, there is another fork at https://github.com/pydanny/dj-pagination) that contains more compatibility releases. So, I'm upgrading to this one. --- readthedocs/settings/base.py | 4 ++-- requirements/pip.txt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/readthedocs/settings/base.py b/readthedocs/settings/base.py index 1131bed6531..51f779b6ef9 100644 --- a/readthedocs/settings/base.py +++ b/readthedocs/settings/base.py @@ -71,7 +71,7 @@ def INSTALLED_APPS(self): # noqa 'django.contrib.humanize', # third party apps - 'linaro_django_pagination', + 'dj_pagination', 'taggit', 'guardian', 'django_gravatar', @@ -131,7 +131,7 @@ def USE_PROMOS(self): # noqa 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', - 'linaro_django_pagination.middleware.PaginationMiddleware', + 'dj_pagination.middleware.PaginationMiddleware', 'readthedocs.core.middleware.SubdomainMiddleware', 'readthedocs.core.middleware.SingleVersionMiddleware', 'corsheaders.middleware.CorsMiddleware', diff --git a/requirements/pip.txt b/requirements/pip.txt index e94471cf34b..a5e02452936 100644 --- a/requirements/pip.txt +++ b/requirements/pip.txt @@ -56,6 +56,7 @@ django-textclassifier==1.0 django-annoying==0.10.1 django-messages-extends==0.5 djangorestframework-jsonp==1.0.2 +dj-pagination==2.3.2 # Docs sphinxcontrib-httpdomain==1.4.0 @@ -70,5 +71,4 @@ django-cors-middleware==1.3.1 nilsimsa==0.3.7 # Pegged git requirements -git+https://github.com/zyga/django-pagination.git@86caf15#egg=django_pagination-dev git+https://github.com/alex/django-taggit.git#egg=django_taggit-dev From 8a2a95ef3f238e6320061a211f9d59c6c7e5b8bd Mon Sep 17 00:00:00 2001 From: Durwasa Date: Mon, 12 Mar 2018 18:49:41 -0400 Subject: [PATCH 3/8] Fixed a grammatical error --- docs/gsoc.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/gsoc.rst b/docs/gsoc.rst index 5d4b70177d4..45c79f57d44 100644 --- a/docs/gsoc.rst +++ b/docs/gsoc.rst @@ -44,7 +44,7 @@ It will walk you through getting a basic environment for Read the Docs setup. Then you can look through our :doc:`contribute` doc for information on how to get started contributing to RTD. -People who has a history of submitting pull requests will be prioritized in our Summer of Code selection process. +People who have a history of submitting pull requests will be prioritized in our Summer of Code selection process. Want to get involved? --------------------- From f1dc3df1a1d66b5845e4675109ea4b84520dde3d Mon Sep 17 00:00:00 2001 From: Nitish Bansal Date: Mon, 12 Mar 2018 03:12:11 +0530 Subject: [PATCH 4/8] added lint rules --- .eslintrc | 8 ++++---- .../builds/static-src/builds/js/detail.js | 10 +++++----- .../core/static-src/core/js/autocomplete.js | 4 ++-- .../static-src/core/js/doc-embed/constants.js | 4 ++-- .../static-src/core/js/doc-embed/footer.js | 2 +- .../static-src/core/js/doc-embed/search.js | 6 +++--- .../static-src/core/js/doc-embed/sphinx.js | 6 +++--- .../core/js/doc-embed/sponsorship.js | 8 ++++---- readthedocs/core/static-src/core/js/site.js | 2 +- readthedocs/core/static-src/core/js/tasks.js | 6 +++--- readthedocs/gold/static-src/gold/js/gold.js | 4 ++-- .../projects/static-src/projects/js/import.js | 14 ++++++------- .../projects/static-src/projects/js/tools.js | 20 +++++++++---------- 13 files changed, 47 insertions(+), 47 deletions(-) diff --git a/.eslintrc b/.eslintrc index c817bc5b881..4b149d1fd22 100644 --- a/.eslintrc +++ b/.eslintrc @@ -26,16 +26,16 @@ "no-shadow": "off", "no-undef": "warn", "no-underscore-dangle": "off", - "no-unused-vars": "off", + "no-unused-vars": "warn", "no-use-before-define": "error", "object-curly-spacing": "off", "one-var": "error", "padded-blocks": "off", "quote-props": "off", "quotes": "off", - "semi": "off", - "space-before-function-paren": "off", - "space-unary-ops": "off", + "semi": "error", + "space-before-function-paren": "error", + "space-unary-ops": "error", "spaced-comment": "off", "vars-on-top": "off", } diff --git a/readthedocs/builds/static-src/builds/js/detail.js b/readthedocs/builds/static-src/builds/js/detail.js index 88a5a1c8598..5eed82db46e 100644 --- a/readthedocs/builds/static-src/builds/js/detail.js +++ b/readthedocs/builds/static-src/builds/js/detail.js @@ -4,7 +4,7 @@ var ko = require('knockout'); var $ = require('jquery'); -function BuildCommand (data) { +function BuildCommand(data) { var self = this; self.id = ko.observable(data.id); self.command = ko.observable(data.command); @@ -25,7 +25,7 @@ function BuildCommand (data) { }); } -function BuildDetailView (instance) { +function BuildDetailView(instance) { var self = this; var instance = instance || {}; @@ -46,7 +46,7 @@ function BuildDetailView (instance) { var n; for (n in commands_raw) { var command = new BuildCommand(commands_raw[n]); - commands_display.push(command) + commands_display.push(command); } return commands_display; }); @@ -58,7 +58,7 @@ function BuildDetailView (instance) { self.legacy_output(true); }; - function poll_api () { + function poll_api() { if (self.finished()) { return; } @@ -75,7 +75,7 @@ function BuildDetailView (instance) { var command = data.commands[n]; var match = ko.utils.arrayFirst( self.commands(), - function(command_cmp) { + function (command_cmp) { return (command_cmp.id === command.id); } ); diff --git a/readthedocs/core/static-src/core/js/autocomplete.js b/readthedocs/core/static-src/core/js/autocomplete.js index 9f4e71ab71f..4193a8b0972 100644 --- a/readthedocs/core/static-src/core/js/autocomplete.js +++ b/readthedocs/core/static-src/core/js/autocomplete.js @@ -5,9 +5,9 @@ module.exports = function (selector, url) { $(selector).autocomplete({ source: url, minLength: 2, - open: function(event, ui) { + open: function (event, ui) { var ac_top = $('.ui-autocomplete').css('top'); $('.ui-autocomplete').css({'width': '233px', 'top': ac_top + 10 }); } }); -} +}; diff --git a/readthedocs/core/static-src/core/js/doc-embed/constants.js b/readthedocs/core/static-src/core/js/doc-embed/constants.js index 5474def9285..cbd2cc72dda 100644 --- a/readthedocs/core/static-src/core/js/doc-embed/constants.js +++ b/readthedocs/core/static-src/core/js/doc-embed/constants.js @@ -3,13 +3,13 @@ var exports = { THEME_RTD: 'sphinx_rtd_theme', THEME_ALABASTER: 'alabaster', - THEME_CELERY: 'sphinx_celery', + THEME_CELERY: 'sphinx_celery' }; exports.PROMO_SUPPORTED_THEMES = [ exports.THEME_RTD, exports.THEME_ALABASTER, - exports.THEME_CELERY, + exports.THEME_CELERY ]; exports.PROMO_TYPES = { diff --git a/readthedocs/core/static-src/core/js/doc-embed/footer.js b/readthedocs/core/static-src/core/js/doc-embed/footer.js index 3cca7456697..fd0c11bba98 100644 --- a/readthedocs/core/static-src/core/js/doc-embed/footer.js +++ b/readthedocs/core/static-src/core/js/doc-embed/footer.js @@ -28,7 +28,7 @@ function setupBookmarkCSRFToken() { } $.ajaxSetup({ - beforeSend: function(xhr, settings) { + beforeSend: function (xhr, settings) { if (!csrfSafeMethod(settings.type)) { xhr.setRequestHeader("X-CSRFToken", $('a.bookmark[token]').attr('token')); } diff --git a/readthedocs/core/static-src/core/js/doc-embed/search.js b/readthedocs/core/static-src/core/js/doc-embed/search.js index b661e1bdde2..d611fb448b1 100644 --- a/readthedocs/core/static-src/core/js/doc-embed/search.js +++ b/readthedocs/core/static-src/core/js/doc-embed/search.js @@ -94,9 +94,9 @@ function attach_elastic_search_query(data) { xhrFields: { withCredentials: true, }, - complete: function(resp, status_code) { - if (typeof(resp.responseJSON) === 'undefined' || - typeof(resp.responseJSON.results) === 'undefined') { + complete: function (resp, status_code) { + if (typeof (resp.responseJSON) === 'undefined' || + typeof (resp.responseJSON.results) === 'undefined') { return search_def.reject(); } return search_def.resolve(resp.responseJSON.results); diff --git a/readthedocs/core/static-src/core/js/doc-embed/sphinx.js b/readthedocs/core/static-src/core/js/doc-embed/sphinx.js index 5ff137a6220..838b3ffdb18 100644 --- a/readthedocs/core/static-src/core/js/doc-embed/sphinx.js +++ b/readthedocs/core/static-src/core/js/doc-embed/sphinx.js @@ -11,7 +11,7 @@ function init() { var rtd = rtddata.get(); /// Click tracking on flyout - $(document).on('click', "[data-toggle='rst-current-version']", function() { + $(document).on('click', "[data-toggle='rst-current-version']", function () { var flyout_state = $("[data-toggle='rst-versions']").hasClass('shift-up') ? 'was_open' : 'was_closed'; // This needs to handle both old style legacy analytics for previously built docs @@ -34,7 +34,7 @@ function init() { // already enabled. See: // https://github.com/snide/sphinx_rtd_theme/issues/250 $(document).ready(function () { - setTimeout(function() { + setTimeout(function () { if (!theme.navBar) { theme.enable(); } @@ -46,7 +46,7 @@ function init() { // scroll element, gracefully handle failover by adding it // dynamically. var navBar = jquery('div.wy-side-scroll:first'); - if (! navBar.length) { + if (!navBar.length) { var navInner = jquery('nav.wy-nav-side:first'); var navScroll = $('
') .addClass('wy-side-scroll'); diff --git a/readthedocs/core/static-src/core/js/doc-embed/sponsorship.js b/readthedocs/core/static-src/core/js/doc-embed/sponsorship.js index e1257c1dc28..8164f5d968f 100644 --- a/readthedocs/core/static-src/core/js/doc-embed/sponsorship.js +++ b/readthedocs/core/static-src/core/js/doc-embed/sponsorship.js @@ -8,7 +8,7 @@ var rtd; /* * Creates a sidebar div where an ad could go */ -function create_sidebar_placement () { +function create_sidebar_placement() { var element_id = 'rtd-' + (Math.random() + 1).toString(36).substring(4); var display_type = constants.PROMO_TYPES.LEFTNAV; var selector = null; @@ -36,7 +36,7 @@ function create_sidebar_placement () { * Creates a sidebar div where an ad could go * Returns the ID of the div or none if no footer ad is possible */ -function create_footer_placement () { +function create_footer_placement() { var element_id = 'rtd-' + (Math.random() + 1).toString(36).substring(4); var display_type = constants.PROMO_TYPES.FOOTER; var selector = null; @@ -63,7 +63,7 @@ function create_footer_placement () { /* * Returns an array of possible places where a promo could go */ -function get_placements () { +function get_placements() { var placements = []; var placement_funcs = [create_footer_placement, create_sidebar_placement]; var placement; @@ -78,7 +78,7 @@ function get_placements () { return placements; } -function Promo (data) { +function Promo(data) { this.id = data.id; // analytics id this.div_id = data.div_id || ''; this.html = data.html || ''; diff --git a/readthedocs/core/static-src/core/js/site.js b/readthedocs/core/static-src/core/js/site.js index e0c8eea9ea7..072764000fd 100644 --- a/readthedocs/core/static-src/core/js/site.js +++ b/readthedocs/core/static-src/core/js/site.js @@ -17,4 +17,4 @@ module.exports.handle_notification_dismiss = function () { } }); }); -} +}; diff --git a/readthedocs/core/static-src/core/js/tasks.js b/readthedocs/core/static-src/core/js/tasks.js index a8ff2aaf9af..26fa668b1ab 100644 --- a/readthedocs/core/static-src/core/js/tasks.js +++ b/readthedocs/core/static-src/core/js/tasks.js @@ -2,11 +2,11 @@ var jquery = require('jquery'); -function poll_task (data) { +function poll_task(data) { var defer = jquery.Deferred(); var tries = 5; - function poll_task_loop () { + function poll_task_loop() { jquery .getJSON(data.url) .success(function (task) { @@ -40,7 +40,7 @@ function poll_task (data) { return defer; } -function trigger_task (config) { +function trigger_task(config) { var defer = jquery.Deferred(); var url = config.url; var token = config.token; diff --git a/readthedocs/gold/static-src/gold/js/gold.js b/readthedocs/gold/static-src/gold/js/gold.js index 84ddc7a9ef2..07b42608ee1 100644 --- a/readthedocs/gold/static-src/gold/js/gold.js +++ b/readthedocs/gold/static-src/gold/js/gold.js @@ -4,7 +4,7 @@ var jquery = require('jquery'); var payment = require('readthedocs/payments/static-src/payments/js/base'); var ko = require('knockout'); -function GoldView (config) { +function GoldView(config) { var self = this; var config = config || {}; @@ -20,7 +20,7 @@ GoldView.init = function (config, obj) { var obj = obj || $('#payment-form')[0]; ko.applyBindings(view, obj); return view; -} +}; GoldView.prototype.submit_form = function (card_digits, token) { this.form.find('#id_last_4_digits').val(card_digits); diff --git a/readthedocs/projects/static-src/projects/js/import.js b/readthedocs/projects/static-src/projects/js/import.js index f996e1a7002..bd59dd31adc 100644 --- a/readthedocs/projects/static-src/projects/js/import.js +++ b/readthedocs/projects/static-src/projects/js/import.js @@ -3,7 +3,7 @@ var $ = require('jquery'); var tasks = require('readthedocs/core/static-src/core/js/tasks'); -$(function() { +$(function () { var input = $('#id_repo'); var repo = $('#id_repo_type'); @@ -37,7 +37,7 @@ $(function() { }); }); -function append_url_params (url, params) { +function append_url_params(url, params) { var link = $('').attr('href', url).get(0); Object.keys(params).map(function (key) { @@ -49,7 +49,7 @@ function append_url_params (url, params) { return link.href; } -function Organization (instance, view) { +function Organization(instance, view) { var self = this; self.id = ko.observable(instance.id); self.name = ko.observable(instance.name); @@ -74,7 +74,7 @@ function Organization (instance, view) { }); } -function Account (instance, view) { +function Account(instance, view) { var self = this; self.id = ko.observable(instance.id); self.username = ko.observable(instance.username); @@ -99,7 +99,7 @@ function Account (instance, view) { }); } -function Project (instance, view) { +function Project(instance, view) { var self = this; self.id = ko.observable(instance.id); self.name = ko.observable(instance.name); @@ -167,7 +167,7 @@ function Project (instance, view) { }; } -function ProjectImportView (instance, config) { +function ProjectImportView(instance, config) { var self = this; var instance = instance || {}; @@ -288,7 +288,7 @@ function ProjectImportView (instance, config) { }) .always(function () { self.is_syncing(false); - }) + }); }; self.has_projects = ko.computed(function () { diff --git a/readthedocs/projects/static-src/projects/js/tools.js b/readthedocs/projects/static-src/projects/js/tools.js index d882951576d..d9dbcdae100 100644 --- a/readthedocs/projects/static-src/projects/js/tools.js +++ b/readthedocs/projects/static-src/projects/js/tools.js @@ -6,7 +6,7 @@ var $ = jquery; // Modal display -function _show_modal (section) { +function _show_modal(section) { var embed_container = $('#embed-container'); if (!embed_container.length) { embed_container = $('