Skip to content

Commit

Permalink
Send telemetry when gather survey link is clicked. (microsoft#10683)
Browse files Browse the repository at this point in the history
* Sending gather quality report (works - not pretty)

* Actually open the gather survey
And whitelist the command that
does so. We don't necessarily want to open the door of being able to
execute arbitrary commands to
notebooks. Yet.

* Fixup for PR submit

* Tweak to work correctly with surveymonkey
  • Loading branch information
greazer committed Mar 22, 2020
1 parent 790cd6d commit 68d7acb
Show file tree
Hide file tree
Showing 8 changed files with 35 additions and 6 deletions.
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,11 @@
"title": "%DataScience.selectKernel%",
"category": "Python",
"enablement": "python.datascience.isnativeactive"
},
{
"command": "python.datascience.gatherquality",
"title": "%DataScience.gatherGood%",
"category": "Python"
}
],
"menus": {
Expand Down
2 changes: 1 addition & 1 deletion package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@
"DataScience.findJupyterCommandProgressCheckInterpreter": "Checking {0}.",
"DataScience.findJupyterCommandProgressSearchCurrentPath": "Searching current path.",
"DataScience.gatheredScriptDescription":"# This file was generated by an experimental feature called 'Gather'.\n#\n# The intent is that it contains only the code required to produce\n# the same results as the cell originally selected for gathering.\n# Please note that the Python analysis is quite conservative, so if\n# it is unsure whether a line of code is necessary for execution, it\n# will err on the side of including it.\n#\n# Please let us know if you are satisfied with what was gathered here:\n# https://aka.ms/gathersurvey\n\n",
"DataScience.gatheredNotebookDescriptionInMarkdown": "## Gathered Notebook\nGathered from ```{0}```\n\n| | |\n|---|---|\n|  &nbsp|This notebook was generated by an experimental feature called \"Gather\". The intent is that it contains only the code and cells required to produce the same results as the cell originally selected for gathering. Please note that the Python analysis is quite conservative, so if it is unsure whether a line of code is necessary for execution, it will err on the side of including it.|\n\n**Are you satisfied with the code that was gathered?**\n\n[Yes](https://aka.ms/gathersurvey?succeed_value=1) [No](https://aka.ms/gathersurvey?succeed_value=0)",
"DataScience.gatheredNotebookDescriptionInMarkdown": "## Gathered Notebook\nGathered from ```{0}```\n\n| | |\n|---|---|\n|  &nbsp|This notebook was generated by an experimental feature called \"Gather\". The intent is that it contains only the code and cells required to produce the same results as the cell originally selected for gathering. Please note that the Python analysis is quite conservative, so if it is unsure whether a line of code is necessary for execution, it will err on the side of including it.|\n\n**Are you satisfied with the code that was gathered?**\n\n[Yes](https://command:python.datascience.gatherquality?yes) [No](https://command:python.datascience.gatherquality?no)",
"DataScience.savePngTitle": "Save Image",
"DataScience.jupyterSelectURIQuickPickTitle": "Pick how to connect to Jupyter",
"DataScience.jupyterSelectURIQuickPickPlaceholder": "Choose an option",
Expand Down
1 change: 1 addition & 0 deletions src/client/common/application/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,4 +161,5 @@ export interface ICommandNameArgumentTypeMapping extends ICommandNameWithoutArgu
[DSCommands.SaveNotebookNonCustomEditor]: [Uri];
[DSCommands.SaveAsNotebookNonCustomEditor]: [Uri, Uri];
[DSCommands.OpenNotebookNonCustomEditor]: [Uri];
[DSCommands.GatherQuality]: [string];
}
2 changes: 1 addition & 1 deletion src/client/common/utils/localize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -726,7 +726,7 @@ export namespace DataScience {
);
export const gatheredNotebookDescriptionInMarkdown = localize(
'DataScience.gatheredNotebookDescriptionInMarkdown',
'# Gathered Notebook\nGathered from ```{0}```\n\n| | |\n|---|---|\n|  &nbsp|This notebook was generated by an experimental feature called "Gather". The intent is that it contains only the code and cells required to produce the same results as the cell originally selected for gathering. Please note that the Python analysis is quite conservative, so if it is unsure whether a line of code is necessary for execution, it will err on the side of including it.|\n\n**Are you satisfied with the code that was gathered?**\n\n[Yes](https://aka.ms/gathersurvey?succeed_value=1) [No](https://aka.ms/gathersurvey?succeed_value=0)'
'# Gathered Notebook\nGathered from ```{0}```\n\n| | |\n|---|---|\n|  &nbsp|This notebook was generated by an experimental feature called "Gather". The intent is that it contains only the code and cells required to produce the same results as the cell originally selected for gathering. Please note that the Python analysis is quite conservative, so if it is unsure whether a line of code is necessary for execution, it will err on the side of including it.|\n\n**Are you satisfied with the code that was gathered?**\n\n[Yes](https://command:python.datascience.gatherquality?yes) [No](https://command:python.datascience.gatherquality?no)'
);
export const savePngTitle = localize('DataScience.savePngTitle', 'Save Image');
export const fallbackToUseActiveInterpeterAsKernel = localize(
Expand Down
10 changes: 8 additions & 2 deletions src/client/datascience/commands/commandRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
'use strict';

import { inject, injectable, multiInject, named, optional } from 'inversify';
import { CodeLens, Range } from 'vscode';
import { CodeLens, env, Range, Uri } from 'vscode';
import { ICommandNameArgumentTypeMapping } from '../../common/application/commands';
import { ICommandManager, IDebugService, IDocumentManager } from '../../common/application/types';
import { IDisposable, IOutputChannel } from '../../common/types';
import { DataScience } from '../../common/utils/localize';
import { captureTelemetry } from '../../telemetry';
import { captureTelemetry, sendTelemetryEvent } from '../../telemetry';
import { Commands, JUPYTER_OUTPUT_CHANNEL, Telemetry } from '../constants';
import {
ICodeWatcher,
Expand Down Expand Up @@ -68,6 +68,7 @@ export class CommandRegistry implements IDisposable {
this.registerCommand(Commands.DebugCurrentCellPalette, this.debugCurrentCellFromCursor);
this.registerCommand(Commands.CreateNewNotebook, this.createNewNotebook);
this.registerCommand(Commands.ViewJupyterOutput, this.viewJupyterOutput);
this.registerCommand(Commands.GatherQuality, this.reportGatherQuality);
if (this.commandListeners) {
this.commandListeners.forEach((listener: IDataScienceCommandListener) => {
listener.register(this.commandManager);
Expand Down Expand Up @@ -344,4 +345,9 @@ export class CommandRegistry implements IDisposable {
// Ask our code lens provider to find the matching code watcher for the current document
return this.dataScienceCodeLensProvider.getCodeWatcher(activeEditor.document);
}

private reportGatherQuality(val: string) {
sendTelemetryEvent(Telemetry.GatherQualityReport, undefined, { result: val === 'no' ? 'no' : 'yes' });
env.openExternal(Uri.parse(`https://aka.ms/gathersurvey?succeed=${val}`));
}
}
2 changes: 2 additions & 0 deletions src/client/datascience/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ export namespace Commands {
export const SaveNotebookNonCustomEditor = 'python.datascience.notebookeditor.save';
export const SaveAsNotebookNonCustomEditor = 'python.datascience.notebookeditor.saveAs';
export const OpenNotebookNonCustomEditor = 'python.datascience.notebookeditor.open';
export const GatherQuality = 'python.datascience.gatherquality';
}

export namespace CodeLensCommands {
Expand Down Expand Up @@ -285,6 +286,7 @@ export enum Telemetry {
KernelInvalid = 'DS_INTERNAL.INVALID_KERNEL_USED',
GatherCompleted = 'DATASCIENCE.GATHER_COMPLETED',
GatheredNotebookSaved = 'DATASCIENCE.GATHERED_NOTEBOOK_SAVED',
GatherQualityReport = 'DS_INTERNAL.GATHER_QUALITY_REPORT',
ZMQNotSupported = 'DATASCIENCE.ZMQ_NATIVE_BINARIES_NOT_LOADING'
}

Expand Down
15 changes: 13 additions & 2 deletions src/client/datascience/interactive-common/linkProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import '../../common/extensions';

import { inject, injectable } from 'inversify';
import { Event, EventEmitter, Position, Range, Selection, TextEditorRevealType, Uri } from 'vscode';
import { commands, Event, EventEmitter, Position, Range, Selection, TextEditorRevealType, Uri } from 'vscode';

import { IApplicationShell, ICommandManager, IDocumentManager } from '../../common/application/types';
import { IFileSystem } from '../../common/platform/types';
Expand All @@ -15,6 +15,10 @@ import { InteractiveWindowMessages } from './interactiveWindowTypes';

const LineQueryRegex = /line=(\d+)/;

// The following list of commands represent those that can be executed
// in a markdown cell using the syntax: https://command:[my.vscode.command].
const linkCommandWhitelist = ['python.datascience.gatherquality'];

// tslint:disable: no-any
@injectable()
export class LinkProvider implements IInteractiveWindowListener {
Expand All @@ -40,9 +44,16 @@ export class LinkProvider implements IInteractiveWindowListener {
case InteractiveWindowMessages.OpenLink:
if (payload) {
// Special case file URIs
const href = payload.toString();
const href: string = payload.toString();
if (href.startsWith('file')) {
this.openFile(href);
} else if (href.startsWith('https://command:')) {
const temp: string = href.split(':')[2];
const command = temp.split('/?')[0];
const params: string[] = temp.split('/?')[1].split(',');
if (linkCommandWhitelist.includes(command)) {
commands.executeCommand(command, params);
}
} else {
this.applicationShell.openUrl(href);
}
Expand Down
4 changes: 4 additions & 0 deletions src/client/telemetry/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1900,6 +1900,10 @@ export interface IEventNamePropertyMapping {
* Telemetry event sent when a gathered notebook has been saved by the user.
*/
[Telemetry.GatheredNotebookSaved]: undefined | never;
/**
* Telemetry event sent when the user reports whether Gathered notebook was good or not
*/
[Telemetry.GatherQualityReport]: { result: 'yes' | 'no' };
/**
* Telemetry event sent when the ZMQ native binaries do not work.
*/
Expand Down

0 comments on commit 68d7acb

Please sign in to comment.