diff --git a/package.json b/package.json index c98e5c1f..375076b8 100644 --- a/package.json +++ b/package.json @@ -156,6 +156,7 @@ "@types/fs-extra": "^5.0.5", "@types/mocha": "^5.2.6", "@types/node": "^11.13.0", + "@types/node-fetch": "^2.3.2", "chai": "^4.2.0", "clean-webpack-plugin": "^2.0.1", "mocha": "^6.0.2", @@ -174,6 +175,7 @@ "fs-extra": "^7.0.1", "https-proxy-agent": "^2.2.1", "lockfile": "^1.0.4", + "node-fetch": "^2.3.0", "temp": "^0.9.0", "vscode-chokidar": "^1.6.5" } diff --git a/src/service/giteeService.ts b/src/service/giteeService.ts new file mode 100644 index 00000000..91327767 --- /dev/null +++ b/src/service/giteeService.ts @@ -0,0 +1,152 @@ +"use strict"; + +import fetch from "node-fetch"; +import { File } from "./fileService"; + +export class GiteeService { + public userName: string = null; + public name: string = null; + private url: string = "https://gitee.com/api/v5"; + private auth: string = null; + private GIST_JSON_EMPTY: any = { + description: "Visual Studio Code Sync Settings Gist", + public: false, + files: { + "settings.json": { + content: "// Empty" + }, + "launch.json": { + content: "// Empty" + }, + "keybindings.json": { + content: "// Empty" + }, + "extensions.json": { + content: "// Empty" + }, + "locale.json": { + content: "// Empty" + }, + "keybindingsMac.json": { + content: "// Empty" + }, + cloudSettings: { + content: "// Empty" + } + } + }; + + constructor(userToken: string) { + if (userToken !== null && userToken !== "") { + this.auth = userToken; + } + if (userToken !== null && userToken !== "") { + fetch(`${this.url}/user${this.getAccessToken()}`, { + method: "GET" + }) + .then(ret => ret.json()) + .then(res => { + this.userName = res.login; + this.name = res.name; + console.log( + "Sync : Connected with user : " + "'" + this.userName + "'" + ); + }) + .catch(err => { + console.error(err); + }); + } + } + + public AddFile(list: File[], GIST_JSON_B: any) { + for (const file of list) { + if (file.content !== "") { + GIST_JSON_B.files[file.gistName] = {}; + GIST_JSON_B.files[file.gistName].content = file.content; + } + } + return GIST_JSON_B; + } + + public async CreateEmptyGIST( + publicGist: boolean, + gistDescription: string + ): Promise { + this.GIST_JSON_EMPTY.access_token = this.auth; + if (publicGist) { + this.GIST_JSON_EMPTY.public = true; + } else { + this.GIST_JSON_EMPTY.public = false; + } + if (gistDescription !== null && gistDescription !== "") { + this.GIST_JSON_EMPTY.description = gistDescription; + } + + try { + const res = await fetch(`${this.url}/gists`, { + headers: { "Content-Type": "application/json;charset=UTF-8" }, + method: "POST", + body: JSON.stringify(this.GIST_JSON_EMPTY) + }).then(ret => ret.json()); + + if (res && res.id) { + return res.id; + } else { + console.error("ID is null"); + console.log("Sync : " + "Response from Gitee is: "); + console.log(res); + } + } catch (err) { + console.error(err); + throw err; + } + } + + public async ReadGist(GIST: string): Promise { + return await fetch(`${this.url}/gists/${GIST}${this.getAccessToken()}`, { + method: "GET" + }) + .then(ret => ret.json()) + .then(data => { + return { + data, + public: data.public + }; + }); + } + + public UpdateGIST(gistObject: any, files: File[]): any { + const allFiles: string[] = Object.keys(gistObject.data.files); + for (const fileName of allFiles) { + let exists = false; + + for (const settingFile of files) { + if (settingFile.gistName === fileName) { + exists = true; + } + } + + if (!exists && !fileName.startsWith("keybindings")) { + gistObject.data.files[fileName] = null; + } + } + + gistObject.data = this.AddFile(files, gistObject.data); + return gistObject; + } + + public async SaveGIST(gistObject: any): Promise { + gistObject.access_token = this.auth; + + await fetch(`${this.url}/gists/${gistObject.id}`, { + headers: { "Content-Type": "application/json;charset=UTF-8" }, + method: "PATCH", + body: JSON.stringify(gistObject) + }); + return true; + } + + private getAccessToken(): string { + return `?access_token=${this.auth}`; + } +} diff --git a/src/setting.ts b/src/setting.ts index 0efa77e6..0a88ad18 100644 --- a/src/setting.ts +++ b/src/setting.ts @@ -57,4 +57,5 @@ export class CustomSettings { public askGistName: boolean = false; public customFiles: { [key: string]: string } = {}; public hostName: string = null; + public gitServer: "github" | "gitee" = "github"; } diff --git a/src/sync.ts b/src/sync.ts index cd498faa..c2048bbb 100644 --- a/src/sync.ts +++ b/src/sync.ts @@ -7,6 +7,7 @@ import { Environment } from "./environmentPath"; import localize from "./localize"; import * as lockfile from "./lockfile"; import { File, FileService } from "./service/fileService"; +import { GiteeService } from "./service/giteeService"; import { GitHubService } from "./service/githubService"; import { ExtensionInformation, PluginService } from "./service/pluginService"; import { @@ -79,7 +80,7 @@ export class Sync { // @ts-ignore const args = arguments; const env = new Environment(this.context); - let github: GitHubService = null; + let gitService = null; let localConfig: LocalConfig = new LocalConfig(); const allSettingFiles: File[] = []; let uploadedExtensions: ExtensionInformation[] = []; @@ -96,10 +97,7 @@ export class Sync { } } - github = new GitHubService( - localConfig.customConfig.token, - localConfig.customConfig.githubEnterpriseUrl - ); + gitService = this.getGitService(localConfig.customConfig); await startGitProcess(localConfig.extConfig, localConfig.customConfig); } catch (error) { Commons.LogException(error, globalCommonService.ERROR_MESSAGE, true); @@ -257,7 +255,7 @@ export class Sync { customSettings.gistDescription = await globalCommonService.AskGistName(); } newGIST = true; - const gistID = await github.CreateEmptyGIST( + const gistID = await gitService.CreateEmptyGIST( localConfig.publicGist, customSettings.gistDescription ); @@ -274,7 +272,7 @@ export class Sync { return; } } - let gistObj = await github.ReadGist(syncSetting.gist); + let gistObj = await gitService.ReadGist(syncSetting.gist); if (!gistObj) { vscode.window.showErrorMessage( localize("cmd.updateSettings.error.readGistFail", syncSetting.gist) @@ -284,8 +282,8 @@ export class Sync { if (gistObj.data.owner !== null) { const gistOwnerName: string = gistObj.data.owner.login.trim(); - if (github.userName != null) { - const userName: string = github.userName.trim(); + if (gitService.userName != null) { + const userName: string = gitService.userName.trim(); if (gistOwnerName !== userName) { Commons.LogException( null, @@ -312,8 +310,8 @@ export class Sync { localize("cmd.updateSettings.info.uploadingFile"), 3000 ); - gistObj = github.UpdateGIST(gistObj, allSettingFiles); - completed = await github.SaveGIST(gistObj.data); + gistObj = gitService.UpdateGIST(gistObj, allSettingFiles); + completed = await gitService.SaveGIST(gistObj.data); if (!completed) { vscode.window.showErrorMessage( localize("cmd.updateSettings.error.gistNotSave") @@ -386,7 +384,11 @@ export class Sync { try { localSettings = await globalCommonService.InitalizeSettings(true, true); - await StartDownload(localSettings.extConfig, localSettings.customConfig); + await StartDownload( + localSettings.extConfig, + localSettings.customConfig, + this.getGitService + ); } catch (err) { Commons.LogException(err, globalCommonService.ERROR_MESSAGE, true); return; @@ -394,19 +396,17 @@ export class Sync { async function StartDownload( syncSetting: ExtensionConfig, - customSettings: CustomSettings + customSettings: CustomSettings, + getGitService: (customConfig: CustomSettings) => any ) { - const github = new GitHubService( - customSettings.token, - customSettings.githubEnterpriseUrl - ); + const gitService = getGitService(customSettings); vscode.window.setStatusBarMessage("").dispose(); vscode.window.setStatusBarMessage( localize("cmd.downloadSettings.info.readdingOnline"), 2000 ); - const res = await github.ReadGist(syncSetting.gist); + const res = await gitService.ReadGist(syncSetting.gist); if (!res) { Commons.LogException(res, "Sync : Unable to Read Gist.", true); @@ -1030,11 +1030,8 @@ export class Sync { customSettings: CustomSettings, syncSetting: ExtensionConfig ): Promise { - const github = new GitHubService( - customSettings.token, - customSettings.githubEnterpriseUrl - ); - const res = await github.ReadGist(syncSetting.gist); + const gitService = this.getGitService(customSettings); + const res = await gitService.ReadGist(syncSetting.gist); if (!res) { Commons.LogException(res, "Sync : Unable to Read Gist.", true); return []; @@ -1062,4 +1059,15 @@ export class Sync { }); return customFiles; } + + private getGitService(customConfig: CustomSettings) { + if (customConfig.gitServer === "github") { + return new GitHubService( + customConfig.token, + customConfig.githubEnterpriseUrl + ); + } else if (customConfig.gitServer === "gitee") { + return new GiteeService(customConfig.token); + } + } }