Skip to content

Commit

Permalink
refactor: move away from deno and back to yarn
Browse files Browse the repository at this point in the history
  • Loading branch information
JustSamuel committed Oct 24, 2024
1 parent baf1085 commit ae6c00a
Show file tree
Hide file tree
Showing 13 changed files with 2,209 additions and 202 deletions.
31 changes: 1 addition & 30 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -1,35 +1,6 @@
const { process } = require("node:process");

module.exports = {
root: true,
env: {
node: true,
mocha: true,
},
plugins: [
"chai-friendly",
"import",
],
extends: [
"airbnb-typescript/base",
"plugin:chai-expect/recommended",
"@gewis/eslint-config",
],
rules: {
"no-console": process.env.NODE_ENV === "production" ? "error" : "off",
"no-debugger": process.env.NODE_ENV === "production" ? "error" : "off",
"linebreak-style": process.env.NODE_ENV === "production"
? ["error", "windows"]
: ["off", "windows"],
"@typescript-eslint/no-empty-function": ["error", {
allow: ["constructors"],
}],
"@typescript-eslint/no-unused-expressions": "off",
"chai-friendly/no-unused-expressions": "error",
"@typescript-eslint/no-floating-promises": "error",
"@typescript-eslint/await-thenable": "warn",
"class-methods-use-this": "off",
},
parserOptions: {
project: "./tsconfig.json",
},
};
53 changes: 2 additions & 51 deletions .github/workflows/lint-and-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,54 +6,5 @@ on:
- main

jobs:
lint:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v2

- name: Set up Deno
uses: denoland/setup-deno@v1
with:
deno-version: v2.0

- name: Install Yarn
run: npm install -g yarn

- name: Install Dependencies
run: yarn install

# TODO: Not sure how this should work, but we should not be removing the lock file.
- name: Remove deno.lock
run: rm -rf ./deno.lock

- name: Lint
run: deno lint ./src/*.ts

build:
runs-on: ubuntu-latest
needs: lint

steps:
- name: Checkout repository
uses: actions/checkout@v2

- name: Set up Deno
uses: denoland/setup-deno@v1
with:
deno-version: v2.0

- name: Install Yarn
run: npm install -g yarn

- name: Install Dependencies
run: yarn install

# TODO: Not sure how this should work, but we should not be removing the lock file.
- name: Remove deno.lock
run: rm -rf ./deno.lock

- name: Compile Deno Project
run: |
deno compile --output plankapi --unstable --no-check ./src/index.ts
build-and-lint:
uses: GEWIS/actions/.github/workflows/typescript-yarn-lint-and-build.yml@e16e0f26bd1d7b5efc72961dbe09267978a9fbf3
18 changes: 12 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
FROM denoland/deno:alpine
FROM node:alpine AS builder

WORKDIR /app

COPY . .
COPY package.json yarn.lock ./

# Install any dependencies (if applicable)
RUN deno cache --unstable --lock=lock.json main.ts
RUN yarn install --frozen-lockfile

# Copy the cron job definition
COPY ./cronjob /etc/crontabs/root

FROM node:alpine

WORKDIR /app

COPY --from=builder /app/node_modules ./node_modules
COPY package.json yarn.lock ./
COPY . .

COPY ./cronjob /etc/crontabs/root

CMD ["sh", "-c", "crond && tail -f /dev/null"]
55 changes: 30 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@

# Planka email integration
# Planka Email Integration

This project integrates email processing with [Planka](https://github.com/plankanban/planka?tab=readme-ov-file), a Kanban board management tool. The application retrieves emails, extracts relevant information to create cards on Planka, and manages the acceptance or rejection of these cards based on specific criteria.

Expand Down Expand Up @@ -28,19 +27,23 @@ This project integrates email processing with [Planka](https://github.com/planka
cd plankAPI
```

2. **Set Up Deno**
2. **Set Up Yarn**

Make sure you have Deno installed. You can follow the installation guide on the [Deno website](https://deno.land/#installation).
Make sure you have [Yarn](https://yarnpkg.com/getting-started/install) installed. You can follow the installation guide on the Yarn website.

3. **Install Dependencies**

Deno handles dependencies through imports, so you don’t need a separate installation step.
Run the following command to install the required dependencies:

```bash
yarn install
```

4. **Copy the .env-example File**

```bash
cp .env-example .env
```
```bash
cp .env-example .env
```

Make sure to replace the default values with actual credentials before running the application.

Expand All @@ -49,7 +52,7 @@ This project integrates email processing with [Planka](https://github.com/planka
To run the application, ensure you have the required environment variables set up (see below). Then, execute the script:

```bash
deno task exec:env
yarn start:env
```

## Environment Variables
Expand All @@ -76,30 +79,32 @@ Make sure to replace the default values with actual credentials before running t
The main workflow is defined in `index.ts`:

```typescript
import Mailer from "./mailer.ts";
import Planka from "./planka.ts";
import Mailer from "./mailer";
import Planka from "./planka";

// Main workflow
async function main() {
Planka.initialize();
const mailer: Mailer = new Mailer();
try {
const emails = await mailer.handleEmails();
const result = await Planka.processCards(emails);
await mailer.handleResults(result);
console.log("Process completed successfully.");
} catch (error) {
console.error("An error occurred during the process:", error);
}
Planka.initialize();
const mailer: Mailer = new Mailer();

try {
const emails = await mailer.handleEmails();
const result = await Planka.processCards(emails);
await mailer.handleResults(result);
console.log("Process completed successfully.");
} catch (error) {
console.error("An error occurred during the process:", error);
}
}

// Execute main if this is the main module
if (import.meta.main) {
void main();
if (require.main === module) {
void main();
}
```

The `Dockerfile` will simply execute the index.ts file based on a cron schedule.

### Mailer Class

The `Mailer` class is responsible for connecting to the IMAP server, handling emails, and moving accepted or rejected emails to appropriate mailboxes.
Expand All @@ -110,4 +115,4 @@ The `Planka` class initializes the Planka client, caches boards, and processes c

## License

This project is licensed under the GNU General Public License. See the [LICENSE](LICENSE) file for details.
This project is licensed under the GNU General Public License. See the [LICENSE](LICENSE) file for details.
28 changes: 0 additions & 28 deletions deno.json

This file was deleted.

14 changes: 0 additions & 14 deletions deno.lock

This file was deleted.

33 changes: 31 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,37 @@
{
"devDependencies": {
"name": "plankapi",
"version": "0.0.0",
"description": "Planka API service",
"main": "src/index.ts",
"scripts": {
"start": "ts-node src/index.ts",
"start:env": "ts-node -r dotenv/config src/index.ts",
"build": "tsc",
"lint": "eslint . --ext .vue,.js,.jsx,.mjs,.ts,.tsx,.cts,.mts,.json --ignore-path .gitignore",
"lint:fix": "eslint . --fix --ext .vue,.js,.jsx,.mjs,.ts,.tsx,.cts,.mts,.json --ignore-path .gitignore"
},
"dependencies": {
"@gewis/planka-client": "github:GEWIS/planka-client#3bb88c2a8d86a9ba8f4fccf0a70e534047c6f88c",
"@hey-api/client-fetch": "^0.4.2",
"imapflow": "^1.0.164"
},
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
"devDependencies": {
"@gewis/eslint-config": "https://github.com/GEWIS/eslint-config",
"@types/imapflow": "^1.0.19",
"@types/node": "^22.7.9",
"dotenv": "^16.0.0",
"ts-node": "^10.9.2",
"typescript": "^5.2.2"
},
"repository": {
"type": "git",
"url": "git+https://github.com/GEWIS/plankapi.git"
},
"author": "GEWIS GEFLITST",
"license": "ISC",
"bugs": {
"url": "https://github.com/GEWIS/plankapi/issues"
},
"homepage": "https://github.com/GEWIS/plankapi#readme",
"packageManager": "yarn@1.22.22"
}
6 changes: 3 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Mailer from "./mailer.ts";
import Planka from "./planka.ts";
import Mailer from "./mailer";
import Planka from "./planka";

// Main workflow
async function main() {
Expand All @@ -17,6 +17,6 @@ async function main() {
}

// Execute main if this is the main module
if (import.meta.main) {
if (require.main === module) {
void main();
}
17 changes: 8 additions & 9 deletions src/mailer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { ImapFlow } from "imapflow";
import type { Readable } from "node:stream";
import { ImapFlow, Readable } from "imapflow";

export interface CardEmail {
title: string;
Expand All @@ -12,7 +11,7 @@ export interface CardEmail {

/**
* Extracts the Planka board ID from email headers.
* @param {string} headers - The email headers as a string.
* @param {string} headers - The ema il headers as a string.
* @returns {string | null} The extracted board ID, or null if not found.
*/
function extractPlankaBoardId(headers: string): string | null {
Expand Down Expand Up @@ -42,6 +41,7 @@ function extractDate(subject: string): Date | null {
const match = subject.match(datePattern);

if (match) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [_, day, month, year, hour, minute] = match;
return new Date(`${year}-${month}-${day}T${hour}:${minute}:00`);
} else {
Expand Down Expand Up @@ -84,12 +84,12 @@ export default class Mailer {

constructor() {
this.client = new ImapFlow({
host: Deno.env.get("IMAP_HOST") || "localhost",
port: Number(Deno.env.get("IMAP_PORT") || "993"),
host: process.env["IMAP_HOST"] || "localhost",
port: Number(process.env["IMAP_PORT"] || "993"),
secure: true,
auth: {
user: Deno.env.get("IMAP_USERNAME") || "user",
pass: Deno.env.get("IMAP_PASSWORD"),
user: process.env["IMAP_USERNAME"] || "user",
pass: process.env["IMAP_PASSWORD"],
},
});
}
Expand All @@ -112,14 +112,13 @@ export default class Mailer {
flags: true,
})
) {
console.error("received message", message);
const headers = "" + message.headers;
const plankaBoardId = extractPlankaBoardId(headers);
const plankaListId = extractPlankaListId(headers);
const date = extractDate(message.envelope.subject);

if (!plankaBoardId) {
rejected.unshift(message.uid);
rejected.unshift(String(message.uid));
continue;
}

Expand Down
Loading

0 comments on commit ae6c00a

Please sign in to comment.