David Losert

David Losert

// Menu: Track Todo
// Description: Start the tracking timer of Toggl with a todo from today of Todoist.
// Author: David Losert
// Twitter: @david_losert
import "@johnlindquist/kit"
import { getTodosOfToday, getProjectById } from '../lib/Todoist';
import { startTimeTrackerFor } from '../lib/Toggl';
const todosToday = await getTodosOfToday();
const selectedTodo = await arg(
'Select Todo to start',
todosToday.map((todo) => ({
name: todo.content,
value: todo
})
));
let projectName;
if(selectedTodo.project_id) {
const project = await getProjectById(selectedTodo.project_id);
projectName = project.name;
}
const result = await startTimeTrackerFor({
description: selectedTodo.content,
projectName
});
await notify({
title: 'Tracking Started.',
message: `Started Tracking for ${result.description}.`
});
import "@johnlindquist/kit"
const axios = await npm('axios');
const todoistApiToken = await env('TODOIST_API_TOKEN');
// Types omit properties not relevant right now
type TodoistTask = {
id: number,
project_id: number,
content: string,
};
type TodoistProject = {
id: number,
name: string,
};
const getTodosOfToday = async (): Promise<TodoistTask[]> => {
const response = await axios({
method: 'GET',
url: 'https://api.todoist.com/rest/v1/tasks?filter=today',
headers: {
'Authorization': `Bearer ${todoistApiToken}`
}
});
return response.data;
};
const getProjectById = async (id: number): Promise<TodoistProject> => {
const response = await axios({
method: 'GET',
url: `https://api.todoist.com/rest/v1/projects/${id}`,
headers: {
'Authorization': `Bearer ${todoistApiToken}`
}
});
return response.data;
};
export {
getTodosOfToday,
getProjectById
};
import "@johnlindquist/kit"
const axios = await npm('axios');
const togglApiToken = await env('TOGGL_API_TOKEN');
const togglWorkspaceId = await env('TOGGL_WORKSPACE_ID');
const auth = {
username: togglApiToken,
// not a real password - the token is the actual secret. For whatever reason, toggl expects it this way around.
password: 'api_token'
};
// Types omit properties not relevant right now
type TimeEntry = {
id: number,
description: string,
};
type TogglProject = {
id: number,
name: string,
}
const getProjectByName = async(name: string): Promise<TogglProject | undefined> => {
const response = await axios({
method: 'GET',
url: `https://api.track.toggl.com/api/v8/workspaces/${togglWorkspaceId}/projects`,
auth
});
return response.data.find((project: TogglProject): boolean => project.name === name)
}
const startTimeTrackerFor = async (
{description, projectName}: { description: string, projectName?: string}
): Promise<TimeEntry> => {
let projectId;
if(projectName) {
const project = await getProjectByName(projectName);
projectId = project.id;
}
const response = await axios({
method: 'POST',
url: 'https://api.track.toggl.com/api/v8/time_entries/start',
data: {
time_entry: {
description,
pid: projectId,
created_with: 'script-kit'
}
},
auth
});
return response.data.data;
}
export {
startTimeTrackerFor
};
export {
startTimeTrackerFor
};

// Menu: Change Wallpaper
// Description: Change your background wallpaper by selecting from a configured folder.
// Author: David Losert
// Twitter: @david_losert
import "@johnlindquist/kit"
// Set to the folder where you keep all your wallpapers for easy selection
const wallpapersPath = await env('WALLPAPER_PATH');
const availableWallpapers = ls(wallpapersPath);
const selectedWallpaper = await arg('select', availableWallpapers.map(image => {
const imagePath = path.resolve(wallpapersPath, image);
return {
name: image,
preview: `<img src="${imagePath}">`,
value: imagePath
};
}));
await applescript(`tell application "Finder" to set desktop picture to POSIX file "${selectedWallpaper}"`);