Skip to content

Commit 26413b6

Browse files
authored
New Components - wakatime (#16648)
* new actions * new sources * pnpm-lock.yaml * updates
1 parent 02b76b8 commit 26413b6

File tree

15 files changed

+731
-20
lines changed

15 files changed

+731
-20
lines changed

components/wakatime/.gitignore

Lines changed: 0 additions & 3 deletions
This file was deleted.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import wakatime from "../../wakatime.app.mjs";
2+
3+
export default {
4+
key: "wakatime-fetch-daily-heartbeats",
5+
name: "Fetch Daily Heartbeats",
6+
description: "Fetch your daily coding activity from WakaTime. [See the documentation](https://wakatime.com/developers#heartbeats)",
7+
version: "0.0.1",
8+
type: "action",
9+
props: {
10+
wakatime,
11+
date: {
12+
type: "string",
13+
label: "Date",
14+
description: "The date to fetch heartbeats for (YYYY-MM-DD)",
15+
},
16+
},
17+
async run({ $ }) {
18+
const response = await this.wakatime.listHeartbeats({
19+
$,
20+
params: {
21+
date: this.date,
22+
},
23+
});
24+
25+
$.export("$summary", `Retrieved ${response.data.length} heartbeat${response.data.length === 1
26+
? ""
27+
: "s"} for ${this.date}`);
28+
return response;
29+
},
30+
};
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import wakatime from "../../wakatime.app.mjs";
2+
3+
export default {
4+
key: "wakatime-list-projects",
5+
name: "List Projects",
6+
description: "List all your WakaTime projects. [See the documentation](https://wakatime.com/developers#projects)",
7+
version: "0.0.1",
8+
type: "action",
9+
props: {
10+
wakatime,
11+
q: {
12+
type: "string",
13+
label: "Query",
14+
description: "Filter project names by a search term",
15+
optional: true,
16+
},
17+
},
18+
async run({ $ }) {
19+
const results = this.wakatime.paginate({
20+
fn: this.wakatime.listProjects,
21+
args: {
22+
$,
23+
params: {
24+
q: this.q,
25+
},
26+
},
27+
});
28+
29+
const projects = [];
30+
for await (const project of results) {
31+
projects.push(project);
32+
}
33+
34+
$.export("$summary", `Successfully retrieved ${projects.length} project${projects.length === 1
35+
? ""
36+
: "s"}`);
37+
return projects;
38+
},
39+
};
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
import wakatime from "../../wakatime.app.mjs";
2+
3+
export default {
4+
key: "wakatime-log-coding-activity",
5+
name: "Log Coding Activity",
6+
description: "Log coding activity to WakaTime. [See the documentation](https://wakatime.com/developers#heartbeats)",
7+
version: "0.0.1",
8+
type: "action",
9+
props: {
10+
wakatime,
11+
entity: {
12+
type: "string",
13+
label: "Entity",
14+
description: "The entity heartbeat is logging time against, such as an absolute file path or domain",
15+
},
16+
type: {
17+
type: "string",
18+
label: "Type",
19+
description: "Type of entity (file, app or domain)",
20+
default: "file",
21+
options: [
22+
"file",
23+
"app",
24+
"domain",
25+
],
26+
},
27+
time: {
28+
type: "string",
29+
label: "Time",
30+
description: "UNIX epoch timestamp; numbers after decimal point are fractions of a second",
31+
},
32+
category: {
33+
type: "string",
34+
label: "Category",
35+
description: "The category for this activity",
36+
optional: true,
37+
options: [
38+
"coding",
39+
"building",
40+
"indexing",
41+
"debugging",
42+
"browsing",
43+
"running tests",
44+
"writing tests",
45+
"manual testing",
46+
"writing docs",
47+
"communicating",
48+
"code reviewing",
49+
"researching",
50+
"learning",
51+
"designing",
52+
],
53+
},
54+
project: {
55+
propDefinition: [
56+
wakatime,
57+
"project",
58+
],
59+
optional: true,
60+
},
61+
projectRootCount: {
62+
type: "integer",
63+
label: "Project Root Count",
64+
description: "Count of the number of folders in the project root path (optional); for ex: if the project folder is /Users/user/projects/wakatime and the entity path is /Users/user/projects/wakatime/models/user.py then the project_root_count is 5 and the relative entity path after removing 5 prefix folders is models/user.py",
65+
optional: true,
66+
},
67+
branch: {
68+
type: "string",
69+
label: "Branch",
70+
description: "Branch name",
71+
optional: true,
72+
},
73+
language: {
74+
propDefinition: [
75+
wakatime,
76+
"language",
77+
],
78+
},
79+
dependencies: {
80+
type: "string",
81+
label: "Dependencies",
82+
description: "Comma separated list of dependencies",
83+
optional: true,
84+
},
85+
lines: {
86+
type: "integer",
87+
label: "Lines",
88+
description: "Total number of lines in the entity (when entity type is file)",
89+
optional: true,
90+
},
91+
lineAdditions: {
92+
type: "integer",
93+
label: "Line Additions",
94+
description: "Number of lines added since last heartbeat in the current file",
95+
optional: true,
96+
},
97+
lineDeletions: {
98+
type: "integer",
99+
label: "Line Deletions",
100+
description: "Number of lines removed since last heartbeat in the current file",
101+
optional: true,
102+
},
103+
lineNo: {
104+
type: "integer",
105+
label: "Line Number",
106+
description: "Current line row number of cursor with the first line starting at 1",
107+
optional: true,
108+
},
109+
cursorPos: {
110+
type: "integer",
111+
label: "Cursor Position",
112+
description: "Current cursor column position starting from 1",
113+
optional: true,
114+
},
115+
isWrite: {
116+
type: "boolean",
117+
label: "Is Write",
118+
description: "Whether this heartbeat was triggered from writing to a file",
119+
optional: true,
120+
},
121+
},
122+
async run({ $ }) {
123+
const { data } = await this.wakatime.createHeartbeat({
124+
$,
125+
data: {
126+
entity: this.entity,
127+
type: this.type,
128+
category: this.category,
129+
time: this.time,
130+
project: this.project,
131+
project_root_count: this.projectRootCount,
132+
branch: this.branch,
133+
language: this.language,
134+
dependencies: this.dependencies,
135+
lines: this.lines,
136+
line_additions: this.lineAdditions,
137+
line_deletions: this.lineDeletions,
138+
line_no: this.lineNo,
139+
cursor_pos: this.cursorPos,
140+
is_write: this.isWrite,
141+
},
142+
});
143+
144+
$.export("$summary", `Successfully logged coding activity for ${this.entity}`);
145+
return data;
146+
},
147+
};

components/wakatime/app/wakatime.app.ts

Lines changed: 0 additions & 13 deletions
This file was deleted.

components/wakatime/package.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
{
22
"name": "@pipedream/wakatime",
3-
"version": "0.0.3",
3+
"version": "0.1.0",
44
"description": "Pipedream WakaTime Components",
5-
"main": "dist/app/wakatime.app.mjs",
5+
"main": "wakatime.app.mjs",
66
"keywords": [
77
"pipedream",
88
"wakatime"
99
],
10-
"files": ["dist"],
1110
"homepage": "https://pipedream.com/apps/wakatime",
1211
"author": "Pipedream <[email protected]> (https://pipedream.com/)",
1312
"publishConfig": {
1413
"access": "public"
14+
},
15+
"dependencies": {
16+
"@pipedream/platform": "^3.0.3"
1517
}
1618
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import wakatime from "../../wakatime.app.mjs";
2+
import { DEFAULT_POLLING_SOURCE_TIMER_INTERVAL } from "@pipedream/platform";
3+
4+
export default {
5+
props: {
6+
wakatime,
7+
db: "$.service.db",
8+
timer: {
9+
type: "$.interface.timer",
10+
default: {
11+
intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL,
12+
},
13+
},
14+
},
15+
methods: {
16+
_getLastTs() {
17+
return this.db.get("lastTs") || 0;
18+
},
19+
_setLastTs(lastTs) {
20+
this.db.set("lastTs", lastTs);
21+
},
22+
getArgs() {
23+
return {};
24+
},
25+
getResourceKey() {
26+
return "data";
27+
},
28+
getTsField() {
29+
return "created_at";
30+
},
31+
generateMeta(item) {
32+
return {
33+
id: item.id,
34+
summary: this.getSummary(item),
35+
ts: Date.parse(item[this.getTsField()]),
36+
};
37+
},
38+
async processEvent(max) {
39+
const lastTs = this._getLastTs();
40+
let maxTs = lastTs;
41+
42+
const resourceFn = this.getResourceFn();
43+
const args = this.getArgs();
44+
const resourceKey = this.getResourceKey();
45+
const tsField = this.getTsField();
46+
47+
const results = this.wakatime.paginate({
48+
fn: resourceFn,
49+
args,
50+
resourceKey,
51+
});
52+
53+
let items = [];
54+
for await (const item of results) {
55+
const ts = Date.parse(item[tsField]);
56+
if (ts > lastTs) {
57+
items.push(item);
58+
maxTs = Math.max(maxTs, ts);
59+
}
60+
}
61+
62+
if (!items.length) {
63+
return;
64+
}
65+
66+
if (max && items.length >= max) {
67+
items = items.slice(0, max);
68+
}
69+
70+
this._setLastTs(maxTs);
71+
72+
for (const item of items.reverse()) {
73+
const meta = this.generateMeta(item);
74+
this.$emit(item, meta);
75+
}
76+
},
77+
getResourceFn() {
78+
throw new Error("getResourceFn is not implemented");
79+
},
80+
getSummary() {
81+
throw new Error("getSummary is not implemented");
82+
},
83+
},
84+
hooks: {
85+
async deploy() {
86+
await this.processEvent(25);
87+
},
88+
},
89+
async run() {
90+
await this.processEvent();
91+
},
92+
};
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import common from "../common/base.mjs";
2+
import sampleEmit from "./test-event.mjs";
3+
4+
export default {
5+
...common,
6+
key: "wakatime-new-commit-created",
7+
name: "New Commit Created",
8+
description: "Emit new event when a new commit is created in WakaTime. [See the documentation](https://wakatime.com/developers#commits)",
9+
version: "0.0.1",
10+
type: "source",
11+
dedupe: "unique",
12+
props: {
13+
...common.props,
14+
project: {
15+
propDefinition: [
16+
common.props.wakatime,
17+
"project",
18+
],
19+
},
20+
},
21+
methods: {
22+
...common.methods,
23+
getResourceFn() {
24+
return this.wakatime.listCommits;
25+
},
26+
getArgs() {
27+
return {
28+
project: this.project,
29+
};
30+
},
31+
getResourceKey() {
32+
return "commits";
33+
},
34+
getSummary(item) {
35+
return `New Commit Created: ${item.message}`;
36+
},
37+
},
38+
sampleEmit,
39+
};

0 commit comments

Comments
 (0)