Made it Prettier(tm)

This commit is contained in:
Juha Ristolainen 2017-11-08 21:03:53 +01:00
parent 2392b782b7
commit 01cd77e519
5 changed files with 276 additions and 242 deletions

View File

@ -1,78 +1,81 @@
import { Pulse } from "./pulse"; import { Pulse } from "./pulse";
import { getISOTimestamp, getLanguageName } from "./utils"; import { getISOTimestamp, getLanguageName } from "./utils";
import * as axios from "axios"; import * as axios from "axios";
export class CodeStatsAPI { export class CodeStatsAPI {
private API_KEY = null; private API_KEY = null;
private UPDATE_URL = "https://codestats.net/api/my/pulses"; private UPDATE_URL = "https://codestats.net/api/my/pulses";
private axios = null; private axios = null;
constructor(apiKey: string, apiURL: string) {
this.API_KEY = apiKey;
this.UPDATE_URL = apiURL;
if (this.API_KEY === null || this.API_KEY === undefined || this.API_KEY === '') {
return;
}
this.axios = axios.default.create({
baseURL: this.UPDATE_URL,
timeout: 10000,
headers: {
"X-API-Token": this.API_KEY,
"Content-Type": "application/json"
}
});
constructor(apiKey: string, apiURL: string) {
this.API_KEY = apiKey;
this.UPDATE_URL = apiURL;
if (
this.API_KEY === null ||
this.API_KEY === undefined ||
this.API_KEY === ""
) {
return;
} }
public sendUpdate(pulse: Pulse): axios.AxiosPromise { this.axios = axios.default.create({
// If we did not have API key, don't try to update baseURL: this.UPDATE_URL,
if (this.axios === null) { timeout: 10000,
return null; headers: {
} "X-API-Token": this.API_KEY,
"Content-Type": "application/json"
}
});
}
// tslint:disable-next-line:typedef public sendUpdate(pulse: Pulse): axios.AxiosPromise {
const data = new ApiJSON(new Date()); // If we did not have API key, don't try to update
if (this.axios === null) {
for (let lang of pulse.xps.keys()) { return null;
let languageName: string = getLanguageName(lang);
let xp: number = pulse.getXP(lang);
data.xps.push(new ApiXP(languageName, xp));
}
let json: string = JSON.stringify(data);
console.log(`JSON: ${json}`);
return this.axios.post(this.UPDATE_URL, json)
.then( (response) => {
console.log(response);
})
.then ( () => {
pulse.reset();
})
.catch((error) => {
console.log(error);
});
} }
// tslint:disable-next-line:typedef
const data = new ApiJSON(new Date());
for (let lang of pulse.xps.keys()) {
let languageName: string = getLanguageName(lang);
let xp: number = pulse.getXP(lang);
data.xps.push(new ApiXP(languageName, xp));
}
let json: string = JSON.stringify(data);
console.log(`JSON: ${json}`);
return this.axios
.post(this.UPDATE_URL, json)
.then(response => {
console.log(response);
})
.then(() => {
pulse.reset();
})
.catch(error => {
console.log(error);
});
}
} }
class ApiJSON { class ApiJSON {
constructor(date: Date) { constructor(date: Date) {
this.coded_at = getISOTimestamp(new Date()); this.coded_at = getISOTimestamp(new Date());
this.xps = new Array<ApiXP>(); this.xps = new Array<ApiXP>();
} }
coded_at: string; coded_at: string;
xps: Array<ApiXP>; xps: Array<ApiXP>;
} }
class ApiXP { class ApiXP {
constructor(language: string, xp: number) { constructor(language: string, xp: number) {
this.language = language; this.language = language;
this.xp = xp; this.xp = xp;
} }
language: string; language: string;
xp: number; xp: number;
} }

View File

@ -3,10 +3,9 @@ import { ExtensionContext } from "vscode";
import { XpCounter } from "./xp-counter"; import { XpCounter } from "./xp-counter";
export function activate(context: ExtensionContext): void { export function activate(context: ExtensionContext): void {
let controller: XpCounter = new XpCounter(); let controller: XpCounter = new XpCounter();
context.subscriptions.push(controller); context.subscriptions.push(controller);
} }
// this method is called when your extension is deactivated // this method is called when your extension is deactivated
export function deactivate(): void { export function deactivate(): void {}
}

View File

@ -1,33 +1,33 @@
export class Pulse { export class Pulse {
xps: Map < string, number > ; xps: Map<string, number>;
constructor() { constructor() {
this.xps = new Map < string, number > (); this.xps = new Map<string, number>();
}
public getXP(language: string): number {
let xp: number = this.xps.get(language);
if (xp === null || xp === undefined) {
return 0;
} else {
return xp;
} }
}
public getXP(language: string): number { public addXP(language: string, amount: number): void {
let xp: number = this.xps.get(language); let xp: number = this.getXP(language);
if (xp === null || xp === undefined) { xp += amount;
return 0;
} else {
return xp;
}
}
public addXP(language: string, amount: number): void { this.xps.set(language, xp);
let xp: number = this.getXP(language); }
xp += amount; public get getXPs(): Map<string, number> {
return this.xps;
}
this.xps.set(language, xp); public reset(): void {
} this.xps = new Map<string, number>();
}
public get getXPs(): Map < string, number > {
return this.xps;
}
public reset(): void {
this.xps = new Map < string, number > ();
}
} }

View File

@ -1,87 +1,95 @@
// converted to ts from https://github.com/Nicd/code-stats-atom/blob/master/lib/utils.js // converted to ts from https://github.com/Nicd/code-stats-atom/blob/master/lib/utils.js
export function getISOTimestamp(date: Date): string { export function getISOTimestamp(date: Date): string {
const offset: number = -date.getTimezoneOffset(); const offset: number = -date.getTimezoneOffset();
const prefix: string = (offset >= 0) ? "+" : "-"; const prefix: string = offset >= 0 ? "+" : "-";
function pad(num: number): string { function pad(num: number): string {
const norm: number = Math.abs(Math.floor(num)); const norm: number = Math.abs(Math.floor(num));
return ((norm < 10) ? "0" : "") + norm; return (norm < 10 ? "0" : "") + norm;
} }
return date.getFullYear() + return (
"-" + pad(date.getMonth() + 1) + date.getFullYear() +
"-" + pad(date.getDate()) + "-" +
"T" + pad(date.getHours()) + pad(date.getMonth() + 1) +
":" + pad(date.getMinutes()) + "-" +
":" + pad(date.getSeconds()) + pad(date.getDate()) +
prefix + pad(offset / 60) + "T" +
pad(offset % 60); pad(date.getHours()) +
":" +
pad(date.getMinutes()) +
":" +
pad(date.getSeconds()) +
prefix +
pad(offset / 60) +
pad(offset % 60)
);
} }
export function getLanguageName(langId: string): string { export function getLanguageName(langId: string): string {
// currently supported language ids in vscode as of 2017-03-18 // currently supported language ids in vscode as of 2017-03-18
let languageNames: { [key:string]: string; } = { let languageNames: { [key: string]: string } = {
"plaintext": "Plain text", plaintext: "Plain text",
"Log": "Log", Log: "Log",
"bat": "Batch", bat: "Batch",
"clojure": "Clojure", clojure: "Clojure",
"coffeescript": "CoffeeScript", coffeescript: "CoffeeScript",
"c": "C", c: "C",
"cpp": "C++", cpp: "C++",
"csharp": "C#", csharp: "C#",
"css": "CSS", css: "CSS",
"diff": "Diff", diff: "Diff",
"dockerfile": "Docker", dockerfile: "Docker",
"elixir": "Elixir", elixir: "Elixir",
"elm": "Elm", elm: "Elm",
"fsharpcss": "F#", fsharpcss: "F#",
"git-commit": "Git", "git-commit": "Git",
"git-rebase": "Git", "git-rebase": "Git",
"go": "Go", go: "Go",
"groovy": "Groovy", groovy: "Groovy",
"handlebars": "Handlebars", handlebars: "Handlebars",
"hlsl": "HLSL", hlsl: "HLSL",
"html": "HTML", html: "HTML",
"ini": "Ini", ini: "Ini",
"properties": "Properties", properties: "Properties",
"java": "Java", java: "Java",
"javascriptreact": "JavaScript (React)", javascriptreact: "JavaScript (React)",
"javascript": "JavaScript", javascript: "JavaScript",
"jsx-tags": "JavaScript (JSX)", "jsx-tags": "JavaScript (JSX)",
"json": "JSON", json: "JSON",
"less": "LESS", less: "LESS",
"lua": "Lua", lua: "Lua",
"makefile": "Makefile", makefile: "Makefile",
"markdown": "Markdown", markdown: "Markdown",
"objective-c": "Objective-C", "objective-c": "Objective-C",
"perl": "Perl", perl: "Perl",
"perl6": "Perl 6", perl6: "Perl 6",
"php": "PHP", php: "PHP",
"powershell": "PowerShell", powershell: "PowerShell",
"jade": "Pug", jade: "Pug",
"python": "Python", python: "Python",
"r": "R", r: "R",
"razor": "Razor", razor: "Razor",
"ruby": "Ruby", ruby: "Ruby",
"rust": "Rust", rust: "Rust",
"scss": "SCSS", scss: "SCSS",
"shaderlab": "Shaderlab", shaderlab: "Shaderlab",
"shellscript": "Shell Script", shellscript: "Shell Script",
"sql": "SQL", sql: "SQL",
"swift": "Swift", swift: "Swift",
"typescript": "TypeScript", typescript: "TypeScript",
"typescriptreact": "TypeScript (React)", typescriptreact: "TypeScript (React)",
"vb": "Visual Basic", vb: "Visual Basic",
"xml": "XML", xml: "XML",
"xsl": "XSL", xsl: "XSL",
"yaml": "YAML" yaml: "YAML"
}; };
let languageName: string = languageNames[langId]; let languageName: string = languageNames[langId];
if (languageName === null || languageName === undefined) { if (languageName === null || languageName === undefined) {
return langId; return langId;
} }
return languageName; return languageName;
} }

View File

@ -1,24 +1,34 @@
// tslint:disable-next-line:max-line-length // tslint:disable-next-line:max-line-length
import { Disposable, workspace, window, StatusBarItem, TextDocument, StatusBarAlignment, TextDocumentChangeEvent, Range, WorkspaceConfiguration } from "vscode"; import {
Disposable,
workspace,
window,
StatusBarItem,
TextDocument,
StatusBarAlignment,
TextDocumentChangeEvent,
Range,
WorkspaceConfiguration
} from "vscode";
import { Pulse } from "./pulse"; import { Pulse } from "./pulse";
import { CodeStatsAPI } from "./code-stats-api"; import { CodeStatsAPI } from "./code-stats-api";
export class XpCounter { export class XpCounter {
private combinedDisposable: Disposable; private combinedDisposable: Disposable;
private statusBarItem: StatusBarItem; private statusBarItem: StatusBarItem;
private pulse: Pulse; private pulse: Pulse;
private api: CodeStatsAPI; private api: CodeStatsAPI;
private updateTimeout: any; private updateTimeout: any;
// private languages: Array<string> = ["typescript", "javascript"]; // private languages: Array<string> = ["typescript", "javascript"];
// wait 10s after each change in the document before sending an update // wait 10s after each change in the document before sending an update
private UPDATE_DELAY = 10000; private UPDATE_DELAY = 10000;
constructor() { constructor() {
this.pulse = new Pulse(); this.pulse = new Pulse();
/* // print out supported language names /* // print out supported language names
let allLanguages = languages.getLanguages().then( let allLanguages = languages.getLanguages().then(
(result => { (result => {
console.log(JSON.stringify(result)); console.log(JSON.stringify(result));
@ -26,77 +36,91 @@ export class XpCounter {
); );
*/ */
this.initAPI(); this.initAPI();
if (!this.statusBarItem) { if (!this.statusBarItem) {
this.statusBarItem = window.createStatusBarItem(StatusBarAlignment.Left); this.statusBarItem = window.createStatusBarItem(StatusBarAlignment.Left);
}
let subscriptions: Disposable[] = [];
workspace.onDidChangeTextDocument(this.onTextDocumentChanged, this, subscriptions);
workspace.onDidChangeConfiguration(this.initAPI, this, subscriptions);
this.combinedDisposable = Disposable.from(...subscriptions);
} }
dispose(): void { let subscriptions: Disposable[] = [];
this.combinedDisposable.dispose(); workspace.onDidChangeTextDocument(
this.statusBarItem.dispose(); this.onTextDocumentChanged,
this,
subscriptions
);
workspace.onDidChangeConfiguration(this.initAPI, this, subscriptions);
this.combinedDisposable = Disposable.from(...subscriptions);
}
dispose(): void {
this.combinedDisposable.dispose();
this.statusBarItem.dispose();
}
private onTextDocumentChanged(event: TextDocumentChangeEvent): void {
this.updateXpCount(event.document, 1);
}
public updateXpCount(document: TextDocument, changeCount: number): void {
let show: boolean;
if (this.isSupportedLanguage(document.languageId)) {
this.pulse.addXP(document.languageId, changeCount);
show = true;
} else {
show = false;
}
this.updateStatusBar(show, `${this.pulse.getXP(document.languageId)}`);
// each change resets the timeout so we only send updates when there is a 10s delay in updates to the document
if (this.updateTimeout !== null) {
clearTimeout(this.updateTimeout);
} }
private onTextDocumentChanged(event: TextDocumentChangeEvent): void { this.updateTimeout = setTimeout(() => {
this.updateXpCount(event.document, 1); const promise = this.api.sendUpdate(this.pulse);
if (promise !== null) {
promise.then(() => {
this.updateStatusBar(
show,
`${this.pulse.getXP(document.languageId)}`
);
});
}
}, this.UPDATE_DELAY);
}
private updateStatusBar(show: boolean, changeCount: string): void {
if (!show) {
this.statusBarItem.hide();
} else {
this.statusBarItem.text = `$(pencil) C::S ${changeCount}`;
this.statusBarItem.show();
}
}
private isSupportedLanguage(language: string): boolean {
// todo: check supported languages
// only update xp if one of supported languages
return true;
}
private initAPI() {
let config: WorkspaceConfiguration = workspace.getConfiguration(
"codestats"
);
if (!config) {
return;
} }
public updateXpCount(document: TextDocument, changeCount: number): void { const apiKey: string = config.get("apikey");
let show: boolean; const apiURL: string = config.get("apiurl");
if (this.isSupportedLanguage(document.languageId)) { console.log(
this.pulse.addXP(document.languageId, changeCount); "code-stats-vscode setting up with API URL",
show = true; apiURL,
} else { "and key",
show = false; apiKey
} );
this.updateStatusBar(show, `${this.pulse.getXP(document.languageId)}`); this.api = new CodeStatsAPI(apiKey, apiURL);
}
// each change resets the timeout so we only send updates when there is a 10s delay in updates to the document
if (this.updateTimeout !== null) {
clearTimeout(this.updateTimeout);
}
this.updateTimeout = setTimeout(() => {
const promise = this.api.sendUpdate(this.pulse);
if (promise !== null) {
promise.then(() => {
this.updateStatusBar(show, `${this.pulse.getXP(document.languageId)}`);
});
}
}, this.UPDATE_DELAY);
}
private updateStatusBar(show: boolean, changeCount: string): void {
if (!show) {
this.statusBarItem.hide();
} else {
this.statusBarItem.text = `$(pencil) C::S ${changeCount}`;
this.statusBarItem.show();
}
}
private isSupportedLanguage(language: string): boolean {
// todo: check supported languages
// only update xp if one of supported languages
return true;
}
private initAPI() {
let config: WorkspaceConfiguration = workspace.getConfiguration("codestats");
if (!config) {
return;
}
const apiKey: string = config.get("apikey");
const apiURL: string = config.get("apiurl");
console.log("code-stats-vscode setting up with API URL", apiURL, "and key", apiKey);
this.api = new CodeStatsAPI(apiKey, apiURL);
}
} }