Compare commits
25 Commits
349cb03844
...
main
Author | SHA1 | Date | |
---|---|---|---|
a355447dc6 | |||
a7e87335b1 | |||
5cf17d64f9 | |||
575979c497 | |||
9bf46c857c | |||
2f1089976c | |||
75fbd17761 | |||
fceef8197b | |||
74024e696a | |||
cb5ad765a1 | |||
62c7107233 | |||
6b0f99d5ad | |||
493c3ef47d | |||
dd5d35d043 | |||
7b59355a3c | |||
a9eeef17d7 | |||
d9f23b544a | |||
154148220e | |||
684057a2c5 | |||
de2400cdf2 | |||
059de4981c | |||
ed73e9db37 | |||
e398c3c6cb | |||
bdc7caf1b3 | |||
9f83b5baea |
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,2 +1,4 @@
|
|||||||
obj/*
|
obj/*
|
||||||
PyMenu
|
PyMenu
|
||||||
|
src/config.h
|
||||||
|
core
|
14
Dockerfile
14
Dockerfile
@ -1,18 +1,22 @@
|
|||||||
FROM debian
|
FROM debian
|
||||||
|
|
||||||
RUN apt update
|
RUN apt update
|
||||||
RUN apt upgrade
|
RUN yes y | apt upgrade
|
||||||
|
|
||||||
RUN apt install make
|
RUN apt install make
|
||||||
RUN apt install cmake
|
RUN yes y | apt install git
|
||||||
RUN apt install git
|
RUN yes | apt install wget
|
||||||
RUN apt install wget
|
RUN yes y | apt install g++
|
||||||
|
|
||||||
# install the dpp lib
|
# install the dpp lib
|
||||||
RUN apt install wget
|
RUN yes y | apt install cmake
|
||||||
|
RUN yes y | apt install libsodium23
|
||||||
|
RUN yes y | apt install libopus0
|
||||||
RUN wget -O dpp.deb https://dl.dpp.dev/
|
RUN wget -O dpp.deb https://dl.dpp.dev/
|
||||||
RUN dpkg -i dpp.deb
|
RUN dpkg -i dpp.deb
|
||||||
|
|
||||||
|
RUN mkdir /app
|
||||||
|
|
||||||
RUN git clone https://git.chauvet.pro/starnakin/PyMenuBOT /app
|
RUN git clone https://git.chauvet.pro/starnakin/PyMenuBOT /app
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
67
README.md
Normal file
67
README.md
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
# PyMenu
|
||||||
|
PyMenu is a discord bot to create grocery list
|
||||||
|
|
||||||
|
## Feature
|
||||||
|
- Add items to your list by sending a message to a channel within the `GROCERY_LIST` category.
|
||||||
|
- Support for multiple lists, one for each channel.
|
||||||
|
- Easily remove items from your list by clicking on the check mark reaction.
|
||||||
|
- Set prices for items.
|
||||||
|
- Specify quantities for items.
|
||||||
|
|
||||||
|
## Screenshots
|
||||||
|

|
||||||
|
|
||||||
|
## Planned feature
|
||||||
|
- Customize the category name.
|
||||||
|
- Add images.
|
||||||
|
- Implement statistics for nerd
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- make
|
||||||
|
- g++
|
||||||
|
- [DPP](https://dpp.dev)
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
- install `make`
|
||||||
|
- install `g++`
|
||||||
|
- [install dpp and its dependencies](https://dpp.dev/installing.html)
|
||||||
|
- Clone the project:
|
||||||
|
``` bash
|
||||||
|
git clone https://git.chauvet.pro/starnakin/PyMenuBOT/
|
||||||
|
cd PyMenuBOT
|
||||||
|
```
|
||||||
|
- Compile the project:
|
||||||
|
``` bash
|
||||||
|
make
|
||||||
|
```
|
||||||
|
- Launch the executable:
|
||||||
|
``` bash
|
||||||
|
./PyMenu
|
||||||
|
```
|
||||||
|
|
||||||
|
## Installation - Docker
|
||||||
|
- Clone the project:
|
||||||
|
``` bash
|
||||||
|
git clone https://git.chauvet.pro/starnakin/PyMenuBOT/
|
||||||
|
cd PyMenuBOT
|
||||||
|
```
|
||||||
|
- Build the docker image.
|
||||||
|
``` bash
|
||||||
|
docker build -t pymenu .
|
||||||
|
```
|
||||||
|
- Config the bot
|
||||||
|
Edit the `docker-compose.yml` file and set the discord bot token
|
||||||
|
- Run the docker
|
||||||
|
```bash
|
||||||
|
docker-compose up -d
|
||||||
|
```
|
||||||
|
- Run the docker - alternative without docker-compose
|
||||||
|
```bash
|
||||||
|
docker run --restart=always --name=pymenu -e BOT_TOKEN=token -d pymenu
|
||||||
|
```
|
||||||
|
|
||||||
|
## Setting up on Your Discord Server
|
||||||
|
- Add the bot to your server (using [the official instance](https://discord.com/oauth2/authorize?client_id=818558187443716137&scope=bot+applications.commands&permissions=10737428544))
|
||||||
|
- Create a category called `listes-de-course`
|
||||||
|
- Inside this category, create channels for each of your grocery lists (e.g., `Wallmart`).
|
||||||
|
- You can now start adding items to your lists by sending messages in the respective channels.
|
9
docker-compose.yml
Normal file
9
docker-compose.yml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
version: "3"
|
||||||
|
services:
|
||||||
|
pymenu:
|
||||||
|
container_name: pymenu
|
||||||
|
image: pymenu
|
||||||
|
build: .
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
- BOT_TOKEN=TOKEN
|
5
src/config.h
Normal file
5
src/config.h
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
const std::string BOT_TOKEN = "token";
|
||||||
|
const std::string GROCERY_LIST_CATEGORY = "listes-de-course";
|
70
src/grocery.cpp
Normal file
70
src/grocery.cpp
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#include <dpp/cluster.h>
|
||||||
|
#include <dpp/unicode_emoji.h>
|
||||||
|
#include <dpp/dpp.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "utils.hpp"
|
||||||
|
|
||||||
|
void on_message(dpp::cluster& bot)
|
||||||
|
{
|
||||||
|
bot.on_message_create([&bot](const dpp::message_create_t& event)
|
||||||
|
{
|
||||||
|
if (event.msg.author.id == bot.me.id)
|
||||||
|
{
|
||||||
|
bot.message_add_reaction(event.msg, dpp::unicode_emoji::white_check_mark);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dpp::channel channel = bot.channel_get_sync(event.msg.channel_id);
|
||||||
|
dpp::channel category = bot.channel_get_sync(channel.parent_id);
|
||||||
|
|
||||||
|
if (category.is_category() == false || category.name != GROCERY_LIST_CATEGORY)
|
||||||
|
return;
|
||||||
|
|
||||||
|
dpp::embed embed = dpp::embed()
|
||||||
|
.set_color(dpp::colors::sea_green)
|
||||||
|
.set_title(event.msg.content)
|
||||||
|
.set_author(event.msg.author.username, "", "")
|
||||||
|
.set_footer(dpp::embed_footer().set_text("PyMenuVersion:2.0"));
|
||||||
|
|
||||||
|
std::string str = event.msg.content;
|
||||||
|
|
||||||
|
std::string quantity, price;
|
||||||
|
|
||||||
|
get_article_data(str, quantity, price);
|
||||||
|
|
||||||
|
if (!quantity.empty())
|
||||||
|
embed.add_field("Quantity", quantity);
|
||||||
|
|
||||||
|
if (!price.empty())
|
||||||
|
embed.add_field("Price", price);
|
||||||
|
|
||||||
|
embed.set_title(str);
|
||||||
|
|
||||||
|
dpp::message msg(event.msg.channel_id, embed);
|
||||||
|
event.send(msg);
|
||||||
|
|
||||||
|
bot.message_delete(event.msg.id, event.msg.channel_id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_react(dpp::cluster& bot)
|
||||||
|
{
|
||||||
|
bot.on_message_reaction_add([&bot](const dpp::message_reaction_add_t& event)
|
||||||
|
{
|
||||||
|
dpp::channel channel = bot.channel_get_sync(event.channel_id);
|
||||||
|
dpp::channel category = bot.channel_get_sync(channel.parent_id);
|
||||||
|
|
||||||
|
if (category.is_category() == false || category.name != GROCERY_LIST_CATEGORY)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (event.reacting_user.id == bot.me.id)
|
||||||
|
return;
|
||||||
|
dpp::emoji emoji = event.reacting_emoji;
|
||||||
|
if (emoji.name == dpp::unicode_emoji::white_check_mark)
|
||||||
|
bot.message_delete(event.message_id, event.channel_id);
|
||||||
|
});
|
||||||
|
}
|
44
src/main.cpp
44
src/main.cpp
@ -1,47 +1,19 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <dpp/dpp.h>
|
#include <dpp/dpp.h>
|
||||||
#include <dpp/unicode_emoji.h>
|
#include <dpp/channel.h>
|
||||||
|
|
||||||
const std::string BOT_TOKEN = "NDkyOTgxMzcwMDg0MzkyOTYw.GAaPMf.LvxTvRkd7pMozkTxC3miWnqM5g7SwxLz2iGVPo";
|
#include "utils.hpp"
|
||||||
|
#include "pymenu.hpp"
|
||||||
|
|
||||||
int main()
|
int main(int ac, char **av, char** env)
|
||||||
{
|
{
|
||||||
dpp::cluster bot(BOT_TOKEN, dpp::i_default_intents | dpp::i_message_content);
|
(void) ac;
|
||||||
|
dpp::cluster bot(get_token(av, env), dpp::i_default_intents | dpp::i_message_content);
|
||||||
|
|
||||||
bot.on_log(dpp::utility::cout_logger());
|
bot.on_log(dpp::utility::cout_logger());
|
||||||
|
|
||||||
bot.on_message_create([&bot](const dpp::message_create_t& event)
|
on_react(bot);
|
||||||
{
|
on_message(bot);
|
||||||
if (event.msg.author.id == bot.me.id)
|
|
||||||
{
|
|
||||||
bot.message_add_reaction(event.msg, dpp::unicode_emoji::white_check_mark);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dpp::embed embed = dpp::embed()
|
|
||||||
.set_color(dpp::colors::sea_green)
|
|
||||||
.set_title(event.msg.content)
|
|
||||||
.add_field("Quantite", "1", true)
|
|
||||||
.add_field("Prix", "3.29")
|
|
||||||
.set_author(event.msg.author.username, "", "")
|
|
||||||
.set_footer(dpp::embed_footer().set_text("PyMenuVersion:2.0"));
|
|
||||||
|
|
||||||
bot.message_delete(event.msg.id, event.msg.channel_id);
|
|
||||||
|
|
||||||
dpp::message msg(event.msg.channel_id, embed);
|
|
||||||
|
|
||||||
event.send(msg);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
bot.on_message_reaction_add([&bot](const dpp::message_reaction_add_t& event)
|
|
||||||
{
|
|
||||||
if (event.reacting_user.id == bot.me.id)
|
|
||||||
return;
|
|
||||||
dpp::emoji emoji = event.reacting_emoji;
|
|
||||||
if (emoji.name == dpp::unicode_emoji::white_check_mark)
|
|
||||||
bot.message_delete(event.message_id, event.channel_id);
|
|
||||||
});
|
|
||||||
|
|
||||||
bot.on_ready([&bot](const dpp::ready_t& event)
|
bot.on_ready([&bot](const dpp::ready_t& event)
|
||||||
{
|
{
|
||||||
|
6
src/pymenu.hpp
Normal file
6
src/pymenu.hpp
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <dpp/cluster.h>
|
||||||
|
|
||||||
|
void on_react(dpp::cluster& bot);
|
||||||
|
void on_message(dpp::cluster& bot);
|
70
src/utils.cpp
Normal file
70
src/utils.cpp
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#include <cctype>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstring>
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
static std::string get_price(std::string& str)
|
||||||
|
{
|
||||||
|
std::string price;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i != str.size(); i++)
|
||||||
|
{
|
||||||
|
if (std::strcmp(str.substr(i, 3).c_str(), "€") == 0)
|
||||||
|
{
|
||||||
|
if (price.empty())
|
||||||
|
{
|
||||||
|
price = "";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
price += "€";
|
||||||
|
str.erase(i - (price.size() - 3), price.size());
|
||||||
|
return price;
|
||||||
|
}
|
||||||
|
else if (std::isdigit(str[i]) || str[i] == '.')
|
||||||
|
price += str[i];
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string get_quantity(std::string& str)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
std::string quantity;
|
||||||
|
|
||||||
|
for (i = 0; i != str.size(); i++)
|
||||||
|
{
|
||||||
|
if (!std::isdigit(str[i]))
|
||||||
|
{
|
||||||
|
if (quantity.empty())
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
quantity += str[i];
|
||||||
|
}
|
||||||
|
str.erase(i - quantity.size(), quantity.size());
|
||||||
|
return quantity;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_article_data(std::string& str, std::string& quantity, std::string& price)
|
||||||
|
{
|
||||||
|
price = get_price(str);
|
||||||
|
quantity = get_quantity(str);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string get_token(char** av, char** env)
|
||||||
|
{
|
||||||
|
if (av[1] != NULL)
|
||||||
|
return av[1];
|
||||||
|
for (size_t i = 0; env[i] != NULL; ++i)
|
||||||
|
{
|
||||||
|
if (std::strncmp("BOT_TOKEN", env[i], 9) == 0)
|
||||||
|
return env[i] + 10;
|
||||||
|
}
|
||||||
|
return BOT_TOKEN;
|
||||||
|
}
|
6
src/utils.hpp
Normal file
6
src/utils.hpp
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
int get_article_data(std::string& str, std::string& quantity, std::string& price);
|
||||||
|
std::string get_token(char** av, char** env);
|
Reference in New Issue
Block a user