mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 20:21:09 +02:00
✨ feat(zitare): add @zitare/content package for shared quotes
- Create new @zitare/content package with 50 German quotes - Include 10 categories: motivation, weisheit, liebe, leben, erfolg, glueck, freundschaft, mut, hoffnung, natur - Add utility functions: getRandomQuote, getDailyQuote, searchQuotes, getQuotesByCategory, formatQuote, etc. - Migrate matrix-zitare-bot to use the shared package - Remove hardcoded quotes from bot configuration
This commit is contained in:
parent
9924eb545a
commit
74c1cfed4f
13 changed files with 1069 additions and 660 deletions
|
|
@ -25,6 +25,7 @@
|
|||
"dependencies": {
|
||||
"@manacore/bot-services": "workspace:*",
|
||||
"@manacore/matrix-bot-common": "workspace:*",
|
||||
"@zitare/content": "workspace:*",
|
||||
"@nestjs/common": "^10.4.15",
|
||||
"@nestjs/config": "^3.3.0",
|
||||
"@nestjs/core": "^10.4.15",
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ import {
|
|||
import { QuotesService } from '../quotes/quotes.service';
|
||||
import { ZitareService } from '../quotes/zitare.service';
|
||||
import { SessionService, TranscriptionService, CreditService } from '@manacore/bot-services';
|
||||
import { HELP_MESSAGE, Category } from '../config/configuration';
|
||||
import { HELP_MESSAGE } from '../config/configuration';
|
||||
import type { Category } from '@zitare/content';
|
||||
|
||||
@Injectable()
|
||||
export class MatrixService extends BaseMatrixService {
|
||||
|
|
|
|||
|
|
@ -18,10 +18,10 @@ export default () => ({
|
|||
},
|
||||
});
|
||||
|
||||
export const HELP_MESSAGE = `**Zitare Bot - Tagliche Inspiration**
|
||||
export const HELP_MESSAGE = `**Zitare Bot - Taegliche Inspiration**
|
||||
|
||||
**Zitate:**
|
||||
- \`!zitat\` - Zufalliges Zitat
|
||||
- \`!zitat\` - Zufaelliges Zitat
|
||||
- \`!heute\` - Zitat des Tages
|
||||
- \`!suche [text]\` - Zitate suchen
|
||||
- \`!kategorie [name]\` - Zitate nach Kategorie
|
||||
|
|
@ -36,7 +36,7 @@ export const HELP_MESSAGE = `**Zitare Bot - Tagliche Inspiration**
|
|||
**Listen:** (Login erforderlich)
|
||||
- \`!listen\` - Alle Listen anzeigen
|
||||
- \`!liste [name]\` - Neue Liste erstellen
|
||||
- \`!addliste [nr] [zitat-nr]\` - Zitat zur Liste hinzufugen
|
||||
- \`!addliste [nr] [zitat-nr]\` - Zitat zur Liste hinzufuegen
|
||||
|
||||
**Sonstiges:**
|
||||
- \`!status\` - Bot-Status
|
||||
|
|
@ -45,250 +45,11 @@ export const HELP_MESSAGE = `**Zitare Bot - Tagliche Inspiration**
|
|||
**Sprachnotizen:**
|
||||
Sende eine Sprachnotiz mit Befehlen wie "Zitat", "Motivation" oder einem Suchbegriff.
|
||||
|
||||
**Naturliche Sprache:**
|
||||
- "zitat", "inspiration" -> Zufalliges Zitat
|
||||
**Natuerliche Sprache:**
|
||||
- "zitat", "inspiration" -> Zufaelliges Zitat
|
||||
- "motiviere mich" -> Motivation-Zitat
|
||||
- "guten morgen" -> Morgenzitat`;
|
||||
|
||||
// Quote categories
|
||||
export const CATEGORIES = [
|
||||
'motivation',
|
||||
'weisheit',
|
||||
'liebe',
|
||||
'leben',
|
||||
'erfolg',
|
||||
'glueck',
|
||||
'freundschaft',
|
||||
'mut',
|
||||
'hoffnung',
|
||||
'natur',
|
||||
] as const;
|
||||
|
||||
export type Category = (typeof CATEGORIES)[number];
|
||||
|
||||
// German inspirational quotes collection
|
||||
export interface Quote {
|
||||
id: string;
|
||||
text: string;
|
||||
author: string;
|
||||
category: Category;
|
||||
}
|
||||
|
||||
export const QUOTES: Quote[] = [
|
||||
// Motivation
|
||||
{
|
||||
id: 'mot-1',
|
||||
text: 'Der einzige Weg, grossartige Arbeit zu leisten, ist zu lieben, was man tut.',
|
||||
author: 'Steve Jobs',
|
||||
category: 'motivation',
|
||||
},
|
||||
{
|
||||
id: 'mot-2',
|
||||
text: 'Erfolg ist nicht endgultig, Misserfolg ist nicht fatal: Was zahlt, ist der Mut weiterzumachen.',
|
||||
author: 'Winston Churchill',
|
||||
category: 'motivation',
|
||||
},
|
||||
{
|
||||
id: 'mot-3',
|
||||
text: 'Die Zukunft gehort denen, die an die Schonheit ihrer Traume glauben.',
|
||||
author: 'Eleanor Roosevelt',
|
||||
category: 'motivation',
|
||||
},
|
||||
{
|
||||
id: 'mot-4',
|
||||
text: 'Es ist nie zu spat, das zu werden, was man hatte sein konnen.',
|
||||
author: 'George Eliot',
|
||||
category: 'motivation',
|
||||
},
|
||||
{
|
||||
id: 'mot-5',
|
||||
text: 'Gib jedem Tag die Chance, der schonste deines Lebens zu werden.',
|
||||
author: 'Mark Twain',
|
||||
category: 'motivation',
|
||||
},
|
||||
// Weisheit
|
||||
{
|
||||
id: 'weis-1',
|
||||
text: 'Der Weg ist das Ziel.',
|
||||
author: 'Konfuzius',
|
||||
category: 'weisheit',
|
||||
},
|
||||
{
|
||||
id: 'weis-2',
|
||||
text: 'Wer kampft, kann verlieren. Wer nicht kampft, hat schon verloren.',
|
||||
author: 'Bertolt Brecht',
|
||||
category: 'weisheit',
|
||||
},
|
||||
{
|
||||
id: 'weis-3',
|
||||
text: 'Man sieht nur mit dem Herzen gut. Das Wesentliche ist fur die Augen unsichtbar.',
|
||||
author: 'Antoine de Saint-Exupery',
|
||||
category: 'weisheit',
|
||||
},
|
||||
{
|
||||
id: 'weis-4',
|
||||
text: 'Nicht weil es schwer ist, wagen wir es nicht, sondern weil wir es nicht wagen, ist es schwer.',
|
||||
author: 'Seneca',
|
||||
category: 'weisheit',
|
||||
},
|
||||
{
|
||||
id: 'weis-5',
|
||||
text: 'Wissen ist Macht.',
|
||||
author: 'Francis Bacon',
|
||||
category: 'weisheit',
|
||||
},
|
||||
// Liebe
|
||||
{
|
||||
id: 'liebe-1',
|
||||
text: 'Wo Liebe ist, da ist auch Leben.',
|
||||
author: 'Mahatma Gandhi',
|
||||
category: 'liebe',
|
||||
},
|
||||
{
|
||||
id: 'liebe-2',
|
||||
text: 'Die Liebe allein versteht das Geheimnis, andere zu beschenken und dabei selbst reich zu werden.',
|
||||
author: 'Clemens Brentano',
|
||||
category: 'liebe',
|
||||
},
|
||||
{
|
||||
id: 'liebe-3',
|
||||
text: 'Es gibt nur ein Gluck in diesem Leben: zu lieben und geliebt zu werden.',
|
||||
author: 'George Sand',
|
||||
category: 'liebe',
|
||||
},
|
||||
// Leben
|
||||
{
|
||||
id: 'leben-1',
|
||||
text: 'Das Leben ist wie Fahrrad fahren. Um die Balance zu halten, musst du in Bewegung bleiben.',
|
||||
author: 'Albert Einstein',
|
||||
category: 'leben',
|
||||
},
|
||||
{
|
||||
id: 'leben-2',
|
||||
text: 'Leben ist das, was passiert, wahrend du damit beschaftigt bist, andere Plane zu machen.',
|
||||
author: 'John Lennon',
|
||||
category: 'leben',
|
||||
},
|
||||
{
|
||||
id: 'leben-3',
|
||||
text: 'Das Leben ist zu kurz fur spater.',
|
||||
author: 'Alexandra Reinwarth',
|
||||
category: 'leben',
|
||||
},
|
||||
{
|
||||
id: 'leben-4',
|
||||
text: 'Lebe jeden Tag, als ware es dein letzter.',
|
||||
author: 'Marcus Aurelius',
|
||||
category: 'leben',
|
||||
},
|
||||
// Erfolg
|
||||
{
|
||||
id: 'erfolg-1',
|
||||
text: 'Erfolg besteht darin, dass man genau die Fahigkeiten hat, die im Moment gefragt sind.',
|
||||
author: 'Henry Ford',
|
||||
category: 'erfolg',
|
||||
},
|
||||
{
|
||||
id: 'erfolg-2',
|
||||
text: 'Der Preis des Erfolges ist Hingabe, harte Arbeit und unablassiger Einsatz.',
|
||||
author: 'Frank Lloyd Wright',
|
||||
category: 'erfolg',
|
||||
},
|
||||
{
|
||||
id: 'erfolg-3',
|
||||
text: 'Ich habe nicht versagt. Ich habe nur 10.000 Wege gefunden, die nicht funktionieren.',
|
||||
author: 'Thomas Edison',
|
||||
category: 'erfolg',
|
||||
},
|
||||
// Glueck
|
||||
{
|
||||
id: 'glueck-1',
|
||||
text: 'Gluck ist das Einzige, das sich verdoppelt, wenn man es teilt.',
|
||||
author: 'Albert Schweitzer',
|
||||
category: 'glueck',
|
||||
},
|
||||
{
|
||||
id: 'glueck-2',
|
||||
text: 'Gluck ist kein Ziel, sondern ein Weg.',
|
||||
author: 'Buddha',
|
||||
category: 'glueck',
|
||||
},
|
||||
{
|
||||
id: 'glueck-3',
|
||||
text: 'Nicht die Glucklichen sind dankbar. Es sind die Dankbaren, die glucklich sind.',
|
||||
author: 'Francis Bacon',
|
||||
category: 'glueck',
|
||||
},
|
||||
// Freundschaft
|
||||
{
|
||||
id: 'freund-1',
|
||||
text: 'Ein wahrer Freund ist jemand, der die Melodie deines Herzens kennt und sie dir vorsingt, wenn du sie vergessen hast.',
|
||||
author: 'Albert Einstein',
|
||||
category: 'freundschaft',
|
||||
},
|
||||
{
|
||||
id: 'freund-2',
|
||||
text: 'Freundschaft ist eine Seele in zwei Korpern.',
|
||||
author: 'Aristoteles',
|
||||
category: 'freundschaft',
|
||||
},
|
||||
// Mut
|
||||
{
|
||||
id: 'mut-1',
|
||||
text: 'Mut steht am Anfang des Handelns, Gluck am Ende.',
|
||||
author: 'Demokrit',
|
||||
category: 'mut',
|
||||
},
|
||||
{
|
||||
id: 'mut-2',
|
||||
text: 'Wer wagt, gewinnt.',
|
||||
author: 'Deutsches Sprichwort',
|
||||
category: 'mut',
|
||||
},
|
||||
{
|
||||
id: 'mut-3',
|
||||
text: 'Der Mutige hat nicht weniger Angst, er handelt trotzdem.',
|
||||
author: 'Mark Twain',
|
||||
category: 'mut',
|
||||
},
|
||||
// Hoffnung
|
||||
{
|
||||
id: 'hoff-1',
|
||||
text: 'Hoffnung ist ein Vogel, der singt, wenn die Nacht noch dunkel ist.',
|
||||
author: 'Rabindranath Tagore',
|
||||
category: 'hoffnung',
|
||||
},
|
||||
{
|
||||
id: 'hoff-2',
|
||||
text: 'Nach jedem Sturm scheint auch wieder die Sonne.',
|
||||
author: 'Deutsches Sprichwort',
|
||||
category: 'hoffnung',
|
||||
},
|
||||
// Natur
|
||||
{
|
||||
id: 'natur-1',
|
||||
text: 'In der Natur ist nichts isoliert; alles hangt mit allem zusammen.',
|
||||
author: 'Johann Wolfgang von Goethe',
|
||||
category: 'natur',
|
||||
},
|
||||
{
|
||||
id: 'natur-2',
|
||||
text: 'Schau tief in die Natur, und dann wirst du alles besser verstehen.',
|
||||
author: 'Albert Einstein',
|
||||
category: 'natur',
|
||||
},
|
||||
];
|
||||
|
||||
// Category labels in German
|
||||
export const CATEGORY_LABELS: Record<Category, string> = {
|
||||
motivation: 'Motivation',
|
||||
weisheit: 'Weisheit',
|
||||
liebe: 'Liebe',
|
||||
leben: 'Leben',
|
||||
erfolg: 'Erfolg',
|
||||
glueck: 'Gluck',
|
||||
freundschaft: 'Freundschaft',
|
||||
mut: 'Mut',
|
||||
hoffnung: 'Hoffnung',
|
||||
natur: 'Natur',
|
||||
};
|
||||
// Re-export types and utilities from @zitare/content
|
||||
export type { Quote, Category } from '@zitare/content';
|
||||
export { CATEGORIES, CATEGORY_LABELS } from '@zitare/content';
|
||||
|
|
|
|||
|
|
@ -1,5 +1,23 @@
|
|||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { QUOTES, Quote, Category, CATEGORIES, CATEGORY_LABELS } from '../config/configuration';
|
||||
import {
|
||||
type Quote,
|
||||
type Category,
|
||||
QUOTES,
|
||||
CATEGORIES,
|
||||
CATEGORY_LABELS,
|
||||
getRandomQuote,
|
||||
getDailyQuote,
|
||||
getQuotesByCategory,
|
||||
getRandomQuoteByCategory,
|
||||
searchQuotes,
|
||||
getQuoteById,
|
||||
getQuoteByIndex,
|
||||
getAllCategories,
|
||||
getCategoryByName,
|
||||
formatQuote,
|
||||
formatQuoteWithNumber,
|
||||
getTotalCount,
|
||||
} from '@zitare/content';
|
||||
|
||||
@Injectable()
|
||||
export class QuotesService {
|
||||
|
|
@ -7,8 +25,7 @@ export class QuotesService {
|
|||
private dailyQuoteCache: { date: string; quote: Quote } | null = null;
|
||||
|
||||
getRandomQuote(): Quote {
|
||||
const index = Math.floor(Math.random() * QUOTES.length);
|
||||
return QUOTES[index];
|
||||
return getRandomQuote();
|
||||
}
|
||||
|
||||
getDailyQuote(): Quote {
|
||||
|
|
@ -19,95 +36,50 @@ export class QuotesService {
|
|||
return this.dailyQuoteCache.quote;
|
||||
}
|
||||
|
||||
// Generate deterministic quote based on date
|
||||
const dateHash = this.hashDate(today);
|
||||
const index = dateHash % QUOTES.length;
|
||||
const quote = QUOTES[index];
|
||||
|
||||
const quote = getDailyQuote();
|
||||
this.dailyQuoteCache = { date: today, quote };
|
||||
this.logger.log(`Daily quote for ${today}: "${quote.text.substring(0, 30)}..."`);
|
||||
|
||||
return quote;
|
||||
}
|
||||
|
||||
private hashDate(dateStr: string): number {
|
||||
let hash = 0;
|
||||
for (let i = 0; i < dateStr.length; i++) {
|
||||
const char = dateStr.charCodeAt(i);
|
||||
hash = (hash << 5) - hash + char;
|
||||
hash = hash & hash; // Convert to 32-bit integer
|
||||
}
|
||||
return Math.abs(hash);
|
||||
}
|
||||
|
||||
getQuotesByCategory(category: Category): Quote[] {
|
||||
return QUOTES.filter((q) => q.category === category);
|
||||
return getQuotesByCategory(category);
|
||||
}
|
||||
|
||||
getRandomQuoteByCategory(category: Category): Quote | null {
|
||||
const quotes = this.getQuotesByCategory(category);
|
||||
if (quotes.length === 0) return null;
|
||||
const index = Math.floor(Math.random() * quotes.length);
|
||||
return quotes[index];
|
||||
return getRandomQuoteByCategory(category);
|
||||
}
|
||||
|
||||
searchQuotes(searchText: string): Quote[] {
|
||||
const lowerSearch = searchText.toLowerCase();
|
||||
return QUOTES.filter(
|
||||
(q) =>
|
||||
q.text.toLowerCase().includes(lowerSearch) || q.author.toLowerCase().includes(lowerSearch)
|
||||
);
|
||||
return searchQuotes(searchText);
|
||||
}
|
||||
|
||||
getQuoteById(id: string): Quote | undefined {
|
||||
return QUOTES.find((q) => q.id === id);
|
||||
return getQuoteById(id);
|
||||
}
|
||||
|
||||
getQuoteByIndex(index: number): Quote | null {
|
||||
if (index < 1 || index > QUOTES.length) return null;
|
||||
return QUOTES[index - 1];
|
||||
return getQuoteByIndex(index);
|
||||
}
|
||||
|
||||
getAllCategories(): { category: Category; label: string; count: number }[] {
|
||||
return CATEGORIES.map((category) => ({
|
||||
category,
|
||||
label: CATEGORY_LABELS[category],
|
||||
count: QUOTES.filter((q) => q.category === category).length,
|
||||
}));
|
||||
return getAllCategories();
|
||||
}
|
||||
|
||||
getCategoryByName(name: string): Category | null {
|
||||
const lowerName = name.toLowerCase();
|
||||
|
||||
// Try exact match first
|
||||
if (CATEGORIES.includes(lowerName as Category)) {
|
||||
return lowerName as Category;
|
||||
}
|
||||
|
||||
// Try partial match
|
||||
for (const category of CATEGORIES) {
|
||||
if (
|
||||
category.startsWith(lowerName) ||
|
||||
CATEGORY_LABELS[category].toLowerCase().startsWith(lowerName)
|
||||
) {
|
||||
return category;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return getCategoryByName(name);
|
||||
}
|
||||
|
||||
getTotalCount(): number {
|
||||
return QUOTES.length;
|
||||
return getTotalCount();
|
||||
}
|
||||
|
||||
formatQuote(quote: Quote): string {
|
||||
const categoryLabel = CATEGORY_LABELS[quote.category];
|
||||
return `"${quote.text}"\n\n— *${quote.author}*\n\n[${categoryLabel}]`;
|
||||
return formatQuote(quote);
|
||||
}
|
||||
|
||||
formatQuoteWithNumber(quote: Quote, number: number): string {
|
||||
const categoryLabel = CATEGORY_LABELS[quote.category];
|
||||
return `**#${number}**\n"${quote.text}"\n\n— *${quote.author}* [${categoryLabel}]`;
|
||||
return formatQuoteWithNumber(quote, number);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue