Skip to content

Instantly share code, notes, and snippets.

@dnnsmnstrr
Created January 21, 2023 02:29
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dnnsmnstrr/54cc09809a306374a6d6b29278439b5f to your computer and use it in GitHub Desktop.
Save dnnsmnstrr/54cc09809a306374a6d6b29278439b5f to your computer and use it in GitHub Desktop.
A scriptable module to interface with the gitlab api
// Variables used by Scriptable.
// These must be at the very top of the file. Do not edit.
// icon-color: blue; icon-glyph: magic;
/**
* Keychain key for GitLab url and personal access token.
*/
const GITLAB_ACCESS_TOKEN_KEY = "gitlab.widget.accessToken";
const GITLAB_URL_KEY = "gitlab.widget.url";
/**
* Whether or not the widget is configured.
*/
const credentialsAlreadyExist =
Keychain.contains(GITLAB_ACCESS_TOKEN_KEY) && Keychain.contains(GITLAB_URL_KEY);
/**
* GitLab Configuration
Configure your gitlab credentials
If you don't know how to obtain a personal access token see:
https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html#creating-a-personal-access-token
*/
let USERNAME = 'dm';
const GITLAB_URL = safeKeychainGet(GITLAB_URL_KEY);
const ACCESS_TOKEN = safeKeychainGet(GITLAB_ACCESS_TOKEN_KEY);
/**
* Returns a Request object for a given GraphQL query.
*
* @param {string} query - GraphQL ("query {}")
* @returns {Request}
*/
function makeGraphQlRequest(query = "query {currentUser {name}}") {
const accessToken = Keychain.get(GITLAB_ACCESS_TOKEN_KEY);
const gitlabUrl = Keychain.get(GITLAB_URL_KEY);
// In GitLab API
const request = new Request(
`${GITLAB_URL}/api/graphql`
);
request.method = 'POST'
request.headers = {
Authorization: `Bearer ${ACCESS_TOKEN}`,
"Content-Type": "application/json"
};
request.body = JSON.stringify({
query
})
return request;
}
const apiUrl = GITLAB_URL + '/api/v4';
const headers = {
Authorization: `Bearer ${ACCESS_TOKEN}`
};
async function getUserInfo() {
const request = new Request(`${apiUrl}/user`);
request.headers = headers;
request.method = 'GET'
const response = await request.loadJSON();
console.log(response.username);
USERNAME = response.username
return response
}
function getTimeSpentToday({ edges: timelogs }) {
const now = new Date();
// const oneDay = 60 * 60 * 24 * 1000
const spentSeconds = timelogs.reduce((spentTime, { node }) => {
const spentDate = new Date(node.spentAt)
const spentToday = now.toDateString() === spentDate.toDateString()
if (spentToday) {
spentTime += node.timeSpent
}
return spentTime
}, 0)
return spentSeconds
}
async function getFile(projectId, filePath, branch = "master") {
const url = `${apiUrl}/projects/${projectId}/repository/files/${encodeURIComponent(filePath)}/raw?ref=${branch}`
console.log(url)
const request = new Request(url);
request.headers = headers;
request.method = 'GET'
const response = await request.loadJSON();
console.log(response);
return response
}
getUserInfo()
module.exports = {
getUserInfo,
makeGraphQlRequest,
credentialsAlreadyExist,
getFile,
showCredentialsDialog,
USERNAME,
GITLAB_URL,
ACCESS_TOKEN
}
/**
* Displays a dialog and asks user to enter credentials.
*/
async function showCredentialsDialog() {
const alert = new Alert();
let gitlabUrl = safeKeychainGet(GITLAB_URL_KEY);
let accessToken = safeKeychainGet(GITLAB_ACCESS_TOKEN_KEY);
alert.title = "GitLab Credentials";
alert.message =
"Please enter fields below to use GitLab Contribution Graph widget. Your credentials will be stored in Keychain.";
alert.addTextField("GitLab URL", gitlabUrl);
alert.addSecureTextField("Personal Access Token", accessToken);
alert.addAction("Submit");
alert.addAction("Help");
alert.addCancelAction("Cancel");
const index = await alert.present();
if (index === 0) {
gitlabUrl = alert.textFieldValue(0);
accessToken = alert.textFieldValue(1);
} else if (index === 1) {
WebView.loadHTML(`
<h1>GitLab Contribution Graph</h1>
<h2>Credentials</h2>
<ul>
<li>
GitLab URL: The GitLab server you want to connect to. For instance: "https://gitlab.example.com".
</li>
<li>
Personal Access Token: It is used to authenticate with the GitLab API.
For more information, please visit
<a href="https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html#creating-a-personal-access-token">this link</a>.
</li>
</ul>
`);
return;
} else {
throw new Error(errors.missingCredentials);
}
const isUrlValid = !!gitlabUrl;
const isAccessTokenValid = !!accessToken;
const isValid = isUrlValid && isAccessTokenValid;
if (isUrlValid) {
Keychain.set(GITLAB_URL_KEY, gitlabUrl);
}
if (isAccessTokenValid) {
Keychain.set(GITLAB_ACCESS_TOKEN_KEY, accessToken);
}
if (isValid) {
await showMainMenu();
} else {
await showCredentialsDialog();
}
}
/**
* Displays confirmation dialog for removing credentials from Keychain.
*/
async function showCredentialsRemovalAlert() {
const alert = new Alert();
alert.title = "Remove Credentials";
alert.message = "Are you sure you want to remove credentials from Keychain?";
alert.addDestructiveAction("Remove");
alert.addCancelAction("Cancel");
const index = await alert.presentAlert();
if (index === 0) {
removeCredentials();
}
}
/**
* Reads a value from Keychain.
*
* @param {string} key - Key of credential stored in Keychain.
* @returns {void}
*/
function safeKeychainGet(key) {
if (Keychain.contains(key)) {
return Keychain.get(key);
}
}
/**
* Removes an item from Keychain.
*
* @param {string} key - Key of credential stored in Keychain.
* @returns {void}
*/
function safeKeychainRemove(key) {
if (Keychain.contains(key)) {
Keychain.remove(key);
}
}
/**
* Removes stored credentials from Keychain.
*/
function removeCredentials() {
safeKeychainRemove(GITLAB_URL_KEY);
safeKeychainRemove(GITLAB_ACCESS_TOKEN_KEY);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment