carnet api

This commit is contained in:
alma 2025-04-20 11:51:23 +02:00
parent 490cabde2d
commit 3bbb365f53
4 changed files with 193 additions and 0 deletions

View File

@ -0,0 +1,45 @@
import { NextResponse } from 'next/server';
import { getServerSession } from 'next-auth';
import { getNextCloudService } from '@/lib/nextcloud-utils';
export async function GET(
request: Request,
{ params }: { params: { date: string } }
) {
try {
const session = await getServerSession();
if (!session?.user?.email) {
return NextResponse.json(
{ error: 'Not authenticated' },
{ status: 401 }
);
}
const service = await getNextCloudService();
const date = new Date(params.date);
if (isNaN(date.getTime())) {
return NextResponse.json(
{ error: 'Invalid date format' },
{ status: 400 }
);
}
const content = await service.getNote(session.user.email, date);
if (!content) {
return NextResponse.json(
{ error: 'Note not found' },
{ status: 404 }
);
}
return NextResponse.json({ content });
} catch (error) {
console.error('Failed to get note:', error);
return NextResponse.json(
{ error: 'Failed to get note' },
{ status: 500 }
);
}
}

55
app/api/carnet/route.ts Normal file
View File

@ -0,0 +1,55 @@
import { NextResponse } from 'next/server';
import { getServerSession } from 'next-auth';
import { getNextCloudService } from '@/lib/nextcloud-utils';
export async function GET(request: Request) {
try {
const session = await getServerSession();
if (!session?.user?.email) {
return NextResponse.json(
{ error: 'Not authenticated' },
{ status: 401 }
);
}
const service = await getNextCloudService();
const notes = await service.listNotes(session.user.email);
return NextResponse.json({ notes });
} catch (error) {
console.error('Failed to list notes:', error);
return NextResponse.json(
{ error: 'Failed to list notes' },
{ status: 500 }
);
}
}
export async function POST(request: Request) {
try {
const session = await getServerSession();
if (!session?.user?.email) {
return NextResponse.json(
{ error: 'Not authenticated' },
{ status: 401 }
);
}
const service = await getNextCloudService();
const { content, date } = await request.json();
const fileName = await service.saveNote(
session.user.email,
content,
date ? new Date(date) : undefined
);
return NextResponse.json({ fileName });
} catch (error) {
console.error('Failed to save note:', error);
return NextResponse.json(
{ error: 'Failed to save note' },
{ status: 500 }
);
}
}

17
lib/nextcloud-utils.ts Normal file
View File

@ -0,0 +1,17 @@
import { getServerSession } from 'next-auth';
import { NextCloudService } from './nextcloud';
export async function getNextCloudService() {
const session = await getServerSession();
if (!session?.user?.email) {
throw new Error('Not authenticated');
}
// Get the NextCloud token from the session
const token = session.accessToken;
if (!token) {
throw new Error('No NextCloud token available');
}
return new NextCloudService(token);
}

76
lib/nextcloud.ts Normal file
View File

@ -0,0 +1,76 @@
import { WebDAV } from 'webdav';
import { getSession } from 'next-auth/react';
export class NextCloudService {
private webdav: WebDAV;
private basePath: string = '/Personal/Carnet';
constructor(token: string) {
this.webdav = new WebDAV(
process.env.NEXTCLOUD_URL + '/remote.php/dav/files',
{
headers: {
Authorization: `Bearer ${token}`,
},
}
);
}
async ensureCarnetFolder(username: string) {
const userPath = `${username}${this.basePath}`;
try {
await this.webdav.exists(userPath);
} catch {
await this.webdav.createDirectory(userPath, { recursive: true });
}
}
async saveNote(username: string, content: string, date: Date = new Date()) {
const fileName = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}.md`;
const filePath = `${username}${this.basePath}/${fileName}`;
await this.ensureCarnetFolder(username);
await this.webdav.putFileContents(filePath, content, { overwrite: true });
return fileName;
}
async getNote(username: string, date: Date) {
const fileName = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}.md`;
const filePath = `${username}${this.basePath}/${fileName}`;
try {
const content = await this.webdav.getFileContents(filePath, { format: 'text' });
return content;
} catch (error) {
if (error.response?.status === 404) {
return null;
}
throw error;
}
}
async listNotes(username: string) {
const userPath = `${username}${this.basePath}`;
try {
const files = await this.webdav.getDirectoryContents(userPath);
return files
.filter(file => file.basename.endsWith('.md'))
.map(file => ({
date: this.fileNameToDate(file.basename),
name: file.basename,
path: file.filename
}));
} catch (error) {
if (error.response?.status === 404) {
return [];
}
throw error;
}
}
private fileNameToDate(fileName: string): Date {
const [year, month, day] = fileName.split('.')[0].split('-').map(Number);
return new Date(year, month - 1, day);
}
}