Compare commits
	
		
			78 Commits
		
	
	
		
			secretbran
			...
			c75fb0b7a3
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					c75fb0b7a3 | ||
| 
						 | 
					b2820ce902 | ||
| 
						 | 
					b605ce315b | ||
| 
						 | 
					dc14eb0aec | ||
| 
						 | 
					393ac72191 | ||
| 
						 | 
					f235b27916 | ||
| 
						 | 
					c4fbd089cc | ||
| 
						 | 
					ec87c6751c | ||
| 724b17c4b7 | |||
| 
						 | 
					8b7a318e6b | ||
| 
						 | 
					a0e1aaa779 | ||
| c9254a3e88 | |||
| 
						 | 
					3097594482 | ||
| 49df5a4495 | |||
| 
						 | 
					9eb7f5bb77 | ||
| 35dbbe4ece | |||
| 6b63276dd7 | |||
| 
						 | 
					d40afca1a4 | ||
| 0e2b714848 | |||
| df55dbf6c7 | |||
| 
						 | 
					c1e7c0eb38 | ||
| c58e256194 | |||
| 
						 | 
					cbaedb04cb | ||
| 008cf08163 | |||
| b1a9e5fa46 | |||
| 
						 | 
					7e3cf46765 | ||
| d6447c54d1 | |||
| 
						 | 
					db44a38eb7 | ||
| 
						 | 
					a77ab50f82 | ||
| 
						 | 
					63daf6845c | ||
| 
						 | 
					7d793c571c | ||
| 
						 | 
					a805775707 | ||
| 
						 | 
					9ee7302f65 | ||
| 
						 | 
					58fb79820f | ||
| 
						 | 
					9518b813f6 | ||
| 
						 | 
					122b090475 | ||
| 
						 | 
					6a100e7364 | ||
| 
						 | 
					0a14e8be4a | ||
| 
						 | 
					bdb58c8a5f | ||
| 
						 | 
					c526c23e3a | ||
| 
						 | 
					8ff3f05034 | ||
| 
						 | 
					1ce47df5f4 | ||
| 
						 | 
					fa5427ec09 | ||
| 
						 | 
					378795d3ef | ||
| 
						 | 
					8ea0c2f517 | ||
| 
						 | 
					3622e76639 | ||
| 
						 | 
					d5349433d4 | ||
| 
						 | 
					282a3d305d | ||
| 
						 | 
					e5d24b0171 | ||
| 
						 | 
					0fb841fce4 | ||
| 
						 | 
					3507d16394 | ||
| 
						 | 
					6952e7f12f | ||
| 
						 | 
					674a88f6ab | ||
| 
						 | 
					11aefc0322 | ||
| 
						 | 
					7273dd5121 | ||
| 
						 | 
					350bd19b08 | ||
| e3f643e805 | |||
| 970d6931db | |||
| b39aa6ecb1 | |||
| 9b54f05d75 | |||
| 
						 | 
					cd7594350f | ||
| c202ad8035 | |||
| 
						 | 
					50e7226709 | ||
| 
						 | 
					ae330eb389 | ||
| ebc89b48e2 | |||
| 0f49cbf4fb | |||
| cd3bbe9b00 | |||
| 1bc829f53d | |||
| 3975ca5997 | |||
| 2afde219a9 | |||
| a666b8e9ae | |||
| e77c106813 | |||
| 86a9762f39 | |||
| 3455946996 | |||
| 3f58eab8c7 | |||
| 
						 | 
					1613e05b61 | ||
| 
						 | 
					0860196a53 | ||
| 49339ebcb9 | 
@@ -16,7 +16,10 @@ steps:
 | 
			
		||||
      from_secret: docker_pw
 | 
			
		||||
 | 
			
		||||
    repo: mollre/journal-bot
 | 
			
		||||
    tags: latest
 | 
			
		||||
    tags: 
 | 
			
		||||
      - 1.0.${DRONE_BUILD_NUMBER}
 | 
			
		||||
      - latest
 | 
			
		||||
    build_args: "BOT_VERSION=1.0.${DRONE_BUILD_NUMBER}"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
trigger:
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,16 @@
 | 
			
		||||
FROM python:3.10-slim
 | 
			
		||||
FROM python:3-slim
 | 
			
		||||
ENV DOCKERIZED=true
 | 
			
		||||
ARG BOT_VERSION
 | 
			
		||||
# set at build time
 | 
			
		||||
ENV BOT_VERSION=$BOT_VERSION
 | 
			
		||||
 | 
			
		||||
WORKDIR /app
 | 
			
		||||
RUN pip install pipenv
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
COPY Pipfile Pipfile.lock ./
 | 
			
		||||
 | 
			
		||||
RUN pip install pipenv && pipenv install --system --deploy
 | 
			
		||||
RUN pipenv install --system --deploy
 | 
			
		||||
 | 
			
		||||
COPY bot .
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								Pipfile
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								Pipfile
									
									
									
									
									
								
							@@ -4,7 +4,11 @@ verify_ssl = true
 | 
			
		||||
name = "pypi"
 | 
			
		||||
 | 
			
		||||
[packages]
 | 
			
		||||
python-telegram-bot = "*"
 | 
			
		||||
peewee = "*"
 | 
			
		||||
python-telegram-bot = {extras = ["job-queue"], version = "*"}
 | 
			
		||||
anyio = "*"
 | 
			
		||||
 | 
			
		||||
[dev-packages]
 | 
			
		||||
 | 
			
		||||
[pipenv]
 | 
			
		||||
allow_prereleases = true
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										79
									
								
								Pipfile.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										79
									
								
								Pipfile.lock
									
									
									
										generated
									
									
									
								
							@@ -1,7 +1,7 @@
 | 
			
		||||
{
 | 
			
		||||
    "_meta": {
 | 
			
		||||
        "hash": {
 | 
			
		||||
            "sha256": "e95b9deab62bd0c661f20a178b8701fc84420db5f663fa4416666e1d05f6ce76"
 | 
			
		||||
            "sha256": "5458e81c4f85af776acc44f46af838644ef8c00ccf4223fbe06f9d76a4717fc6"
 | 
			
		||||
        },
 | 
			
		||||
        "pipfile-spec": 6,
 | 
			
		||||
        "requires": {},
 | 
			
		||||
@@ -16,19 +16,26 @@
 | 
			
		||||
    "default": {
 | 
			
		||||
        "anyio": {
 | 
			
		||||
            "hashes": [
 | 
			
		||||
                "sha256:25ea0d673ae30af41a0c442f81cf3b38c7e79fdc7b60335a4c14e05eb0947421",
 | 
			
		||||
                "sha256:fbbe32bd270d2a2ef3ed1c5d45041250284e31fc0a4df4a5a6071842051a51e3"
 | 
			
		||||
                "sha256:48d53f0b141f5757c38d648309e6fe254857fae092d67f938fa248d7c0f36804",
 | 
			
		||||
                "sha256:596b09c520820e7eed961ddc889540972f92d5e8fcb081117fc054c409df34ae"
 | 
			
		||||
            ],
 | 
			
		||||
            "markers": "python_full_version >= '3.6.2'",
 | 
			
		||||
            "version": "==3.6.2"
 | 
			
		||||
            "index": "pypi",
 | 
			
		||||
            "version": "==4.0.0rc1"
 | 
			
		||||
        },
 | 
			
		||||
        "apscheduler": {
 | 
			
		||||
            "hashes": [
 | 
			
		||||
                "sha256:0293937d8f6051a0f493359440c1a1b93e882c57daf0197afeff0e727777b96e",
 | 
			
		||||
                "sha256:e813ad5ada7aff36fb08cdda746b520531eaac7757832abc204868ba78e0c8f6"
 | 
			
		||||
            ],
 | 
			
		||||
            "version": "==3.10.1"
 | 
			
		||||
        },
 | 
			
		||||
        "certifi": {
 | 
			
		||||
            "hashes": [
 | 
			
		||||
                "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3",
 | 
			
		||||
                "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"
 | 
			
		||||
                "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082",
 | 
			
		||||
                "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9"
 | 
			
		||||
            ],
 | 
			
		||||
            "markers": "python_version >= '3.6'",
 | 
			
		||||
            "version": "==2022.12.7"
 | 
			
		||||
            "version": "==2023.7.22"
 | 
			
		||||
        },
 | 
			
		||||
        "h11": {
 | 
			
		||||
            "hashes": [
 | 
			
		||||
@@ -40,19 +47,19 @@
 | 
			
		||||
        },
 | 
			
		||||
        "httpcore": {
 | 
			
		||||
            "hashes": [
 | 
			
		||||
                "sha256:c5d6f04e2fc530f39e0c077e6a30caa53f1451096120f1f38b954afd0b17c0cb",
 | 
			
		||||
                "sha256:da1fb708784a938aa084bde4feb8317056c55037247c787bd7e19eb2c2949dc0"
 | 
			
		||||
                "sha256:a6f30213335e34c1ade7be6ec7c47f19f50c56db36abef1a9dfa3815b1cb3888",
 | 
			
		||||
                "sha256:c2789b767ddddfa2a5782e3199b2b7f6894540b17b16ec26b2c4d8e103510b87"
 | 
			
		||||
            ],
 | 
			
		||||
            "markers": "python_version >= '3.7'",
 | 
			
		||||
            "version": "==0.16.3"
 | 
			
		||||
            "version": "==0.17.3"
 | 
			
		||||
        },
 | 
			
		||||
        "httpx": {
 | 
			
		||||
            "hashes": [
 | 
			
		||||
                "sha256:9818458eb565bb54898ccb9b8b251a28785dd4a55afbc23d0eb410754fe7d0f9",
 | 
			
		||||
                "sha256:a211fcce9b1254ea24f0cd6af9869b3d29aba40154e947d2a07bb499b3e310d6"
 | 
			
		||||
                "sha256:06781eb9ac53cde990577af654bd990a4949de37a28bdb4a230d434f3a30b9bd",
 | 
			
		||||
                "sha256:5853a43053df830c20f8110c5e69fe44d035d850b2dfe795e196f00fdb774bdd"
 | 
			
		||||
            ],
 | 
			
		||||
            "markers": "python_version >= '3.7'",
 | 
			
		||||
            "version": "==0.23.3"
 | 
			
		||||
            "version": "==0.24.1"
 | 
			
		||||
        },
 | 
			
		||||
        "idna": {
 | 
			
		||||
            "hashes": [
 | 
			
		||||
@@ -70,22 +77,38 @@
 | 
			
		||||
            "version": "==3.16.2"
 | 
			
		||||
        },
 | 
			
		||||
        "python-telegram-bot": {
 | 
			
		||||
            "extras": [
 | 
			
		||||
                "job-queue"
 | 
			
		||||
            ],
 | 
			
		||||
            "hashes": [
 | 
			
		||||
                "sha256:4d1d4b643ce158aa17a0987b84005eaf25fe0ce8b38fd234099594985611c198",
 | 
			
		||||
                "sha256:d0aa53e1f06d7cb7919cc0e2d6c81a02d968fc29921aeaa962edd1efb816a9bd"
 | 
			
		||||
                "sha256:a6ac3f9c9674aaf7d1c7e652d8b75cde969fb872f75e9521b8516eceaba82b1b",
 | 
			
		||||
                "sha256:e426404b0006989a5bcc05e11a7ef3ffe0c086b684a4e963db5bda1d361a049a"
 | 
			
		||||
            ],
 | 
			
		||||
            "index": "pypi",
 | 
			
		||||
            "version": "==20.2"
 | 
			
		||||
            "version": "==20.4"
 | 
			
		||||
        },
 | 
			
		||||
        "rfc3986": {
 | 
			
		||||
            "extras": [
 | 
			
		||||
                "idna2008"
 | 
			
		||||
            ],
 | 
			
		||||
        "pytz": {
 | 
			
		||||
            "hashes": [
 | 
			
		||||
                "sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835",
 | 
			
		||||
                "sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97"
 | 
			
		||||
                "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588",
 | 
			
		||||
                "sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb"
 | 
			
		||||
            ],
 | 
			
		||||
            "version": "==1.5.0"
 | 
			
		||||
            "version": "==2023.3"
 | 
			
		||||
        },
 | 
			
		||||
        "setuptools": {
 | 
			
		||||
            "hashes": [
 | 
			
		||||
                "sha256:11e52c67415a381d10d6b462ced9cfb97066179f0e871399e006c4ab101fc85f",
 | 
			
		||||
                "sha256:baf1fdb41c6da4cd2eae722e135500da913332ab3f2f5c7d33af9b492acb5235"
 | 
			
		||||
            ],
 | 
			
		||||
            "markers": "python_version >= '3.7'",
 | 
			
		||||
            "version": "==68.0.0"
 | 
			
		||||
        },
 | 
			
		||||
        "six": {
 | 
			
		||||
            "hashes": [
 | 
			
		||||
                "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926",
 | 
			
		||||
                "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"
 | 
			
		||||
            ],
 | 
			
		||||
            "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
 | 
			
		||||
            "version": "==1.16.0"
 | 
			
		||||
        },
 | 
			
		||||
        "sniffio": {
 | 
			
		||||
            "hashes": [
 | 
			
		||||
@@ -94,6 +117,14 @@
 | 
			
		||||
            ],
 | 
			
		||||
            "markers": "python_version >= '3.7'",
 | 
			
		||||
            "version": "==1.3.0"
 | 
			
		||||
        },
 | 
			
		||||
        "tzlocal": {
 | 
			
		||||
            "hashes": [
 | 
			
		||||
                "sha256:46eb99ad4bdb71f3f72b7d24f4267753e240944ecfc16f25d2719ba89827a803",
 | 
			
		||||
                "sha256:f3596e180296aaf2dbd97d124fe76ae3a0e3d32b258447de7b939b3fd4be992f"
 | 
			
		||||
            ],
 | 
			
		||||
            "markers": "python_version >= '3.7'",
 | 
			
		||||
            "version": "==5.0.1"
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    "develop": {}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,12 +2,21 @@ from datetime import date
 | 
			
		||||
from telegram.ext import ConversationHandler, CommandHandler, MessageHandler, filters, CallbackQueryHandler, CallbackContext
 | 
			
		||||
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update, InputMediaPhoto
 | 
			
		||||
import random
 | 
			
		||||
import os
 | 
			
		||||
from pathlib import Path
 | 
			
		||||
# ACTION_CHOICE, DATE_ENTRY, ADD_CONTENT = range(3)
 | 
			
		||||
ACTION, TUERCHEN_CHOICE = range(2)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
from .basehandler import BaseHandler
 | 
			
		||||
 | 
			
		||||
MEDIA_DIR = Path(os.getenv("MEDIA_DIR"))
 | 
			
		||||
GIF_LOCATION = MEDIA_DIR / "advent" / "gifs"
 | 
			
		||||
GIFS = list(GIF_LOCATION.glob("*.mp4"))
 | 
			
		||||
STICKER_LOCATION = MEDIA_DIR / "advent" / "stickers"
 | 
			
		||||
STICKERS = list(STICKER_LOCATION.glob("*.tgs"))
 | 
			
		||||
PICTURE_LOCATION = MEDIA_DIR / "advent" / "pretty_pictures"
 | 
			
		||||
PICTURES = list(PICTURE_LOCATION.glob("*.jpg"))
 | 
			
		||||
 | 
			
		||||
class AdventsHandler(BaseHandler):
 | 
			
		||||
    def __init__(self, entry_string):
 | 
			
		||||
        self.entry_string = entry_string
 | 
			
		||||
@@ -66,7 +75,7 @@ class AdventsHandler(BaseHandler):
 | 
			
		||||
        keyboard = [[InlineKeyboardButton("Bubo Küsschen", callback_data="kuss")], [InlineKeyboardButton("Türchen öffnen", callback_data="tuer")], [InlineKeyboardButton("Pretty Bubo Picture", callback_data="picture")]]
 | 
			
		||||
 | 
			
		||||
        reply_markup = InlineKeyboardMarkup(keyboard)
 | 
			
		||||
        await update.message.reply_sticker(sticker=open(".bot_storage\stickers\stickerwhat.tgs", "rb"))
 | 
			
		||||
        await update.message.reply_sticker(sticker=STICKER_LOCATION/"stickerwhat.tgs")
 | 
			
		||||
        await update.message.reply_text(text="Hallo, mein süßer Weihnachts-Bubo! Ich bin dein Adventskalender ^^. Was möchtest du tun?", reply_markup=reply_markup)
 | 
			
		||||
 | 
			
		||||
        return ACTION
 | 
			
		||||
@@ -79,7 +88,7 @@ class AdventsHandler(BaseHandler):
 | 
			
		||||
        keyboard = [[InlineKeyboardButton("Kalendertürchen öffnen", callback_data="tuer")], [InlineKeyboardButton("Noch ein Küsschen!", callback_data="kuss")], [InlineKeyboardButton("Pretty Bubo Picture", callback_data="picture")], [InlineKeyboardButton("Bis zum nächsten Mal!", callback_data="bye")]]
 | 
			
		||||
        reply_markup = InlineKeyboardMarkup(keyboard)
 | 
			
		||||
 | 
			
		||||
        await update.effective_message.reply_sticker(sticker=open(".bot_storage\stickers\stickerkiss.tgs", "rb"))
 | 
			
		||||
        await update.effective_message.reply_sticker(sticker=STICKER_LOCATION/"stickerkiss.tgs")
 | 
			
		||||
        await update.effective_message.reply_text(text="Mua!", reply_markup=reply_markup)
 | 
			
		||||
 | 
			
		||||
        return ACTION
 | 
			
		||||
@@ -101,7 +110,8 @@ class AdventsHandler(BaseHandler):
 | 
			
		||||
        reply_markup = InlineKeyboardMarkup(keyboard)
 | 
			
		||||
 | 
			
		||||
        picture_number = random.randint(1,31)
 | 
			
		||||
        await update.effective_message.reply_photo(photo=open(".bot_storage\pretty_pictures\photo_"+f"{picture_number}"+"_2023-11-25_14-25-53.jpg", "rb"), caption="So ein cutes Foto!", reply_markup=reply_markup)
 | 
			
		||||
        #print(picture_number-1)
 | 
			
		||||
        await update.effective_message.reply_photo(photo=PICTURES[picture_number-1], caption="So ein cutes Foto!", reply_markup=reply_markup)
 | 
			
		||||
 | 
			
		||||
        return ACTION
 | 
			
		||||
    
 | 
			
		||||
@@ -118,9 +128,9 @@ class AdventsHandler(BaseHandler):
 | 
			
		||||
        
 | 
			
		||||
        #if tuer_nummer <= int(date.today().strftime("%d")):
 | 
			
		||||
        if (tuer_nummer <= int(date.today().strftime("%d"))) and (int(date.today().strftime("%m"))==12):
 | 
			
		||||
            await update.message.reply_document(document=open(".bot_storage\gifs\gif"+f"{tuer_nummer}"+".mp4", "rb"),caption=f"Türchen für den {tuer_nummer}. Dezember: \n" + self.tuerchen_texte[tuerchen], reply_markup=reply_markup)
 | 
			
		||||
            await update.message.reply_document(document=GIFS[tuer_nummer-1], caption=f"Türchen für den {tuer_nummer}. Dezember: \n" + self.tuerchen_texte[tuerchen], reply_markup=reply_markup)
 | 
			
		||||
        else:
 | 
			
		||||
            await update.message.reply_sticker(sticker=open(".bot_storage\stickers\stickerangry.tgs", "rb"))
 | 
			
		||||
            await update.message.reply_sticker(sticker=STICKER_LOCATION/"stickerangry.tgs")
 | 
			
		||||
            await update.message.reply_text(text="Hey, nicht schummeln! Dieses Türchen darfst du noch nicht sehen.", reply_markup=reply_markup)
 | 
			
		||||
 | 
			
		||||
        return ACTION
 | 
			
		||||
@@ -129,7 +139,7 @@ class AdventsHandler(BaseHandler):
 | 
			
		||||
        query = update.callback_query
 | 
			
		||||
        await query.answer()
 | 
			
		||||
 | 
			
		||||
        await update.effective_message.reply_sticker(sticker=open(".bot_storage\stickers\stickerbye.tgs", "rb"))
 | 
			
		||||
        await update.effective_message.reply_sticker(sticker=STICKER_LOCATION/"stickerbye.tgs")
 | 
			
		||||
        await update.effective_message.reply_text(text="Bye bye, Bubo! Hab dich ganz doll lieb! 😘")
 | 
			
		||||
 | 
			
		||||
        return ConversationHandler.END
 | 
			
		||||
 
 | 
			
		||||
@@ -5,4 +5,4 @@ class BaseHandler:
 | 
			
		||||
    entry_string: str
 | 
			
		||||
 | 
			
		||||
    async def entry_point(self, update, context) -> None:
 | 
			
		||||
        self.logger.info(f"Chat said: {self.entry_string}")
 | 
			
		||||
        self.logger.info(f"Chat ({update.message.chat_id}) said: {self.entry_string}")
 | 
			
		||||
@@ -2,28 +2,30 @@ import datetime
 | 
			
		||||
import os
 | 
			
		||||
from telegram.ext import ConversationHandler, CommandHandler, MessageHandler, filters, CallbackQueryHandler
 | 
			
		||||
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
 | 
			
		||||
ACTION_CHOICE, DATE_ENTRY, ADD_CONTENT = range(3)
 | 
			
		||||
from telegram.constants import ParseMode
 | 
			
		||||
import models
 | 
			
		||||
 | 
			
		||||
ENTRY_OPTIONS, CONTENT_ENTRY = range(2)
 | 
			
		||||
BUTTON_COUNT = 5
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
from .basehandler import BaseHandler
 | 
			
		||||
 | 
			
		||||
class JournalHandler(BaseHandler):
 | 
			
		||||
    def __init__(self, entry_string, models):
 | 
			
		||||
        self.models = models
 | 
			
		||||
    def __init__(self, entry_string):
 | 
			
		||||
        self.entry_string = entry_string
 | 
			
		||||
        self.handler = ConversationHandler(
 | 
			
		||||
            entry_points=[CommandHandler(entry_string, self.entry_point)],
 | 
			
		||||
            states={
 | 
			
		||||
                ACTION_CHOICE: [
 | 
			
		||||
                    CallbackQueryHandler(self.date_choice, pattern="today|yesterday"),
 | 
			
		||||
                    CallbackQueryHandler(self.date_custom, pattern="custom"),
 | 
			
		||||
                    CallbackQueryHandler(self.option_delete, pattern="delete")
 | 
			
		||||
                    ],
 | 
			
		||||
                DATE_ENTRY: [
 | 
			
		||||
                ENTRY_OPTIONS: [
 | 
			
		||||
                    CallbackQueryHandler(self.date_button, pattern=r"^\d{8}$"), # a serialized date
 | 
			
		||||
                    CallbackQueryHandler(self.date_custom, pattern=r"^\d{1,3}$"), # a ~ small delta, symbolizing a new range to show
 | 
			
		||||
                    CallbackQueryHandler(self.option_delete, pattern="delete"),
 | 
			
		||||
                    MessageHandler(filters.ALL, self.date_entry),
 | 
			
		||||
                    ],
 | 
			
		||||
                ADD_CONTENT: [
 | 
			
		||||
                CONTENT_ENTRY: [
 | 
			
		||||
                    MessageHandler(filters.ALL, self.content_save),
 | 
			
		||||
                    ]
 | 
			
		||||
                    ],
 | 
			
		||||
            },
 | 
			
		||||
            fallbacks=[],
 | 
			
		||||
        )
 | 
			
		||||
@@ -37,52 +39,83 @@ class JournalHandler(BaseHandler):
 | 
			
		||||
            await update.message.reply_text("You are not authorized to use this bot")
 | 
			
		||||
            return ConversationHandler.END
 | 
			
		||||
 | 
			
		||||
        dates = [(datetime.datetime.now() - datetime.timedelta(days = i)).date() for i in range(BUTTON_COUNT + 2)][::-1]
 | 
			
		||||
        # since there are two buttons additional buttons, we need to have two more days
 | 
			
		||||
        names = [d.strftime("%d.%m.") for d in dates]
 | 
			
		||||
        callbacks = [d.strftime("%d%m%Y") for d in dates]
 | 
			
		||||
        names[-1] = "Today"
 | 
			
		||||
        names[-2] = "Yesterday"
 | 
			
		||||
 | 
			
		||||
        options = [[
 | 
			
		||||
                InlineKeyboardButton("Today", callback_data="today"),
 | 
			
		||||
                InlineKeyboardButton("Yesterday", callback_data="yesterday"),
 | 
			
		||||
                InlineKeyboardButton("Custom date", callback_data="custom"),
 | 
			
		||||
        options = [
 | 
			
		||||
            [
 | 
			
		||||
                InlineKeyboardButton(names[-1], callback_data=callbacks[-1])
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                InlineKeyboardButton(names[-2], callback_data=callbacks[-2])
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                InlineKeyboardButton(n, callback_data=c) for n,c in zip(names[:-2], callbacks[:-2])
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                InlineKeyboardButton("<<", callback_data=BUTTON_COUNT + 2)
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                InlineKeyboardButton("Delete", callback_data="delete")
 | 
			
		||||
            ]
 | 
			
		||||
        ]
 | 
			
		||||
        keyboard = InlineKeyboardMarkup(options)
 | 
			
		||||
        await update.message.reply_text("Please choose an option for the entry:", reply_markup=keyboard)
 | 
			
		||||
        return ACTION_CHOICE
 | 
			
		||||
        await update.message.reply_text("Please choose a date \(or type it in the format _DDMMYYYY_\)", reply_markup=keyboard, parse_mode=ParseMode.MARKDOWN_V2)
 | 
			
		||||
        return ENTRY_OPTIONS
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    async def date_choice(self, update, context):
 | 
			
		||||
    async def date_button(self, update, context):
 | 
			
		||||
        query = update.callback_query
 | 
			
		||||
        await query.answer()
 | 
			
		||||
        if query.data == "today":
 | 
			
		||||
            date = datetime.datetime.now().date()
 | 
			
		||||
        elif query.data == "yesterday":
 | 
			
		||||
            date = datetime.datetime.now().date() - datetime.timedelta(days=1)
 | 
			
		||||
        else:
 | 
			
		||||
            raise ValueError("Invalid date choice")
 | 
			
		||||
        date = datetime.datetime.strptime(query.data, "%d%m%Y").date()
 | 
			
		||||
 | 
			
		||||
        with self.models.db:
 | 
			
		||||
            self.current_model, new = self.models.JournalEntry.get_or_create(
 | 
			
		||||
        with models.db:
 | 
			
		||||
            self.current_model, new = models.JournalEntry.get_or_create(
 | 
			
		||||
                date = date
 | 
			
		||||
            )
 | 
			
		||||
        if new:
 | 
			
		||||
            count = models.JournalEntry.select().count()
 | 
			
		||||
            await query.edit_message_text(
 | 
			
		||||
                text=f"What is your entry for {self.current_model.date_pretty}?"
 | 
			
		||||
                text=f"Journal entry no. {count}. What happened on {self.current_model.date_pretty}?"
 | 
			
		||||
            )
 | 
			
		||||
        else:
 | 
			
		||||
            await query.edit_message_text(text="An entry already exists for this date")
 | 
			
		||||
            return ConversationHandler.END
 | 
			
		||||
        
 | 
			
		||||
        return ADD_CONTENT
 | 
			
		||||
        return CONTENT_ENTRY
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    async def date_custom(self, update, context):
 | 
			
		||||
        query = update.callback_query
 | 
			
		||||
        await query.answer()
 | 
			
		||||
        await query.edit_message_text(text="Please enter the date in the format DDMMYYYY")
 | 
			
		||||
        return DATE_ENTRY
 | 
			
		||||
        delta = int(query.data)
 | 
			
		||||
 | 
			
		||||
        dates = [(datetime.datetime.now() - datetime.timedelta(days = i + delta)).date() for i in range(BUTTON_COUNT)][::-1]
 | 
			
		||||
        names = [d.strftime("%d.%m.") for d in dates]
 | 
			
		||||
        callbacks = [d.strftime("%d%m%Y") for d in dates]
 | 
			
		||||
 | 
			
		||||
        options = [
 | 
			
		||||
            [
 | 
			
		||||
                InlineKeyboardButton(">>", callback_data=delta - BUTTON_COUNT)
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                InlineKeyboardButton(n, callback_data=c) for n,c in zip(names, callbacks)
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                InlineKeyboardButton("<<", callback_data=delta + BUTTON_COUNT)
 | 
			
		||||
            ],
 | 
			
		||||
            [
 | 
			
		||||
                InlineKeyboardButton("Delete", callback_data="delete")
 | 
			
		||||
            ]
 | 
			
		||||
        ]
 | 
			
		||||
        keyboard = InlineKeyboardMarkup(options)
 | 
			
		||||
        await query.edit_message_text("Please choose a date \(or type it in the format _DDMMYYYY_\)", parse_mode=ParseMode.MARKDOWN_V2, reply_markup=keyboard)
 | 
			
		||||
 | 
			
		||||
        return ENTRY_OPTIONS
 | 
			
		||||
 | 
			
		||||
    async def date_entry(self, update, context):
 | 
			
		||||
        date = update.message.text
 | 
			
		||||
@@ -90,12 +123,12 @@ class JournalHandler(BaseHandler):
 | 
			
		||||
        try:
 | 
			
		||||
            date = datetime.datetime.strptime(date, "%d%m%Y").date()
 | 
			
		||||
        except ValueError:
 | 
			
		||||
            await update.message.reply_text("Please enter the date in the format DDMMYYYY")
 | 
			
		||||
            return DATE_ENTRY
 | 
			
		||||
            await update.message.reply_text("Please enter the date in the format _DDMMYYYY_", parse_mode=ParseMode.MARKDOWN_V2)
 | 
			
		||||
            return ENTRY_OPTIONS
 | 
			
		||||
        
 | 
			
		||||
        if context.chat_data.get("delete", False): # if not set, delete was not chosen
 | 
			
		||||
            with self.models.db:
 | 
			
		||||
                self.current_model = self.models.JournalEntry.get_or_none(
 | 
			
		||||
            with models.db:
 | 
			
		||||
                self.current_model = models.JournalEntry.get_or_none(
 | 
			
		||||
                    date = date
 | 
			
		||||
                )
 | 
			
		||||
            if self.current_model:
 | 
			
		||||
@@ -105,20 +138,23 @@ class JournalHandler(BaseHandler):
 | 
			
		||||
                context.chat_data["delete"] = False
 | 
			
		||||
            return ConversationHandler.END
 | 
			
		||||
        else:
 | 
			
		||||
            with self.models.db:
 | 
			
		||||
                self.current_model, new = self.models.JournalEntry.get_or_create(
 | 
			
		||||
            with models.db:
 | 
			
		||||
                self.current_model, new = models.JournalEntry.get_or_create(
 | 
			
		||||
                    date = date
 | 
			
		||||
                )
 | 
			
		||||
            if not new:
 | 
			
		||||
                await update.message.reply_text("An entry already exists for this date")
 | 
			
		||||
                return ConversationHandler.END
 | 
			
		||||
            else:
 | 
			
		||||
                await update.message.reply_text(f"What is your entry for {self.current_model.date_pretty}?")
 | 
			
		||||
                return ADD_CONTENT
 | 
			
		||||
                count = models.JournalEntry.select().count()
 | 
			
		||||
                await update.message.reply_text(
 | 
			
		||||
                    text=f"Journal entry no. {count}. What happened on {self.current_model.date_pretty}?"
 | 
			
		||||
                )
 | 
			
		||||
                return CONTENT_ENTRY
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    async def content_save(self, update, context):
 | 
			
		||||
        with self.models.db:
 | 
			
		||||
        with models.db:
 | 
			
		||||
            self.current_model.author_id = update.message.from_user.id
 | 
			
		||||
 | 
			
		||||
            if update.message.text:
 | 
			
		||||
@@ -144,13 +180,13 @@ class JournalHandler(BaseHandler):
 | 
			
		||||
    async def option_delete(self, update, context):
 | 
			
		||||
        query = update.callback_query
 | 
			
		||||
        await query.answer()
 | 
			
		||||
        await query.edit_message_text(text="Please enter the date in the format DDMMYYYY")
 | 
			
		||||
        await query.edit_message_text(text="Please enter the date in the format _DDMMYYYY_", parse_mode=ParseMode.MARKDOWN_V2)
 | 
			
		||||
        context.chat_data["delete"] = True
 | 
			
		||||
        return DATE_ENTRY
 | 
			
		||||
        return ENTRY_OPTIONS
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    async def delete_entry(self, update, context):
 | 
			
		||||
        with self.models.db:
 | 
			
		||||
        with models.db:
 | 
			
		||||
            self.current_model.delete_instance()
 | 
			
		||||
        context.chat_data["delete"] = False
 | 
			
		||||
        await update.message.reply_text(text="Entry deleted ✅")
 | 
			
		||||
@@ -5,10 +5,7 @@ from telegram import InlineKeyboardButton, InlineKeyboardMarkup
 | 
			
		||||
 | 
			
		||||
from .models import ListModel, set_db, db
 | 
			
		||||
 | 
			
		||||
MEDIA_DIR = Path(os.getenv("MEDIA_DIR"))
 | 
			
		||||
DB_DIR = MEDIA_DIR / "lists_db"
 | 
			
		||||
DB_DIR.mkdir(parents=True, exist_ok=True)
 | 
			
		||||
 | 
			
		||||
PERSISTENCE_DIR = Path(os.getenv("PERSISTENCE_DIR"))
 | 
			
		||||
 | 
			
		||||
NAME, NEW, ACTION, ITEMADD, ITEMREMOVE, ITEMTOGGLE = range(6)
 | 
			
		||||
 | 
			
		||||
@@ -18,16 +15,17 @@ from ..basehandler import BaseHandler
 | 
			
		||||
class ListHandler(BaseHandler):
 | 
			
		||||
    """Create and edit lists"""
 | 
			
		||||
 | 
			
		||||
    def __init__(self, entry_string, models):
 | 
			
		||||
        self.journal_models = models # not needed here
 | 
			
		||||
    def __init__(self, entry_string):
 | 
			
		||||
        self.entry_string = entry_string
 | 
			
		||||
 | 
			
		||||
        set_db(PERSISTENCE_DIR / "lists.sqlite")
 | 
			
		||||
 | 
			
		||||
        self.list_overview_keyboard = [
 | 
			
		||||
            [InlineKeyboardButton("Print list", callback_data="print")],
 | 
			
		||||
            [InlineKeyboardButton("Add item", callback_data="add")],
 | 
			
		||||
            [InlineKeyboardButton("Toggle item", callback_data="toggle")],
 | 
			
		||||
            [InlineKeyboardButton("Remove item", callback_data="remove")],
 | 
			
		||||
            [InlineKeyboardButton("Clear list", callback_data="clear")],
 | 
			
		||||
            [InlineKeyboardButton("Print list", callback_data="print")],
 | 
			
		||||
            [InlineKeyboardButton("Delete list", callback_data="delete")],
 | 
			
		||||
            
 | 
			
		||||
        ]
 | 
			
		||||
@@ -40,13 +38,13 @@ class ListHandler(BaseHandler):
 | 
			
		||||
                    ],
 | 
			
		||||
                NEW : [MessageHandler(filters.TEXT, callback=self.new_listname)],
 | 
			
		||||
                ACTION: [
 | 
			
		||||
                    CallbackQueryHandler(self.list_print, pattern="^print$"),
 | 
			
		||||
                    CallbackQueryHandler(self.list_add, pattern="^add$"),
 | 
			
		||||
                    CallbackQueryHandler(self.list_toggle, pattern="^toggle$"),
 | 
			
		||||
                    CallbackQueryHandler(self.list_menu, pattern="^overview$"),
 | 
			
		||||
                    CallbackQueryHandler(self.list_remove, pattern="^remove$"),
 | 
			
		||||
                    CallbackQueryHandler(self.list_clear, pattern="^clear$"),
 | 
			
		||||
                    CallbackQueryHandler(self.list_delete, pattern="^delete$"),
 | 
			
		||||
                    CallbackQueryHandler(self.list_print, pattern="^print$"),
 | 
			
		||||
                    CallbackQueryHandler(self.list_menu, pattern="^overview$"),
 | 
			
		||||
                    ],
 | 
			
		||||
                ITEMADD : [MessageHandler(filters.TEXT, callback=self.list_add_item)],
 | 
			
		||||
                ITEMTOGGLE: [CallbackQueryHandler(self.list_toggle_index)],
 | 
			
		||||
@@ -58,10 +56,9 @@ class ListHandler(BaseHandler):
 | 
			
		||||
 | 
			
		||||
    async def entry_point(self, update, context) -> None:
 | 
			
		||||
        await super().entry_point(update, context)
 | 
			
		||||
        set_db(DB_DIR / f"chat_{update.message.chat_id}.db")
 | 
			
		||||
        with db:
 | 
			
		||||
            lists = ListModel.select()
 | 
			
		||||
        keyboard = [[InlineKeyboardButton(k.name, callback_data=f"list-{k.name}")] for k in lists] + \
 | 
			
		||||
            lists = ListModel.select().where(ListModel.chat_id == update.effective_chat.id)
 | 
			
		||||
        keyboard = [[InlineKeyboardButton(k.name, callback_data=f"list-{k.id}")] for k in lists] + \
 | 
			
		||||
            [[InlineKeyboardButton("New list", callback_data="new")]]
 | 
			
		||||
 | 
			
		||||
        reply_markup = InlineKeyboardMarkup(keyboard)
 | 
			
		||||
@@ -72,13 +69,13 @@ class ListHandler(BaseHandler):
 | 
			
		||||
    async def choose_list(self, update, context: CallbackContext) -> None:
 | 
			
		||||
        query = update.callback_query
 | 
			
		||||
        data = query.data
 | 
			
		||||
        name = data.replace("list-","")
 | 
			
		||||
        id = data.replace("list-","")
 | 
			
		||||
        await query.answer()
 | 
			
		||||
        context.user_data["current_list"] = ListModel.get(name = name)
 | 
			
		||||
        context.user_data["current_list"] = ListModel.get(id = id)
 | 
			
		||||
 | 
			
		||||
        reply_markup = InlineKeyboardMarkup(self.list_overview_keyboard)
 | 
			
		||||
 | 
			
		||||
        await query.edit_message_text("Very well. For " + name + " the following actions are available:", reply_markup=reply_markup)
 | 
			
		||||
        await query.edit_message_text(f"Using {context.user_data['current_list'].name}. Available actions:", reply_markup=reply_markup)
 | 
			
		||||
        return ACTION
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -88,7 +85,7 @@ class ListHandler(BaseHandler):
 | 
			
		||||
 | 
			
		||||
        reply_markup = InlineKeyboardMarkup(self.list_overview_keyboard)
 | 
			
		||||
 | 
			
		||||
        await query.edit_message_text(f"Very well. For {context.user_data['current_list'].name} the following actions are available:", reply_markup=reply_markup)
 | 
			
		||||
        await query.edit_message_text(f"Using {context.user_data['current_list'].name}. Available actions:", reply_markup=reply_markup)
 | 
			
		||||
        return ACTION
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -103,7 +100,7 @@ class ListHandler(BaseHandler):
 | 
			
		||||
        name = update.message.text
 | 
			
		||||
        try:
 | 
			
		||||
            with db:
 | 
			
		||||
                context.user_data["current_list"] = ListModel.create(name = name)
 | 
			
		||||
                context.user_data["current_list"] = ListModel.create(name = name, chat_id=update.effective_chat.id)
 | 
			
		||||
            keyboard = [[InlineKeyboardButton("Add an item", callback_data="add"), InlineKeyboardButton("To the menu!", callback_data="overview")]]
 | 
			
		||||
            reply_markup = InlineKeyboardMarkup(keyboard)
 | 
			
		||||
            await update.message.reply_text("Thanks. List " + name + " was successfully created.", reply_markup=reply_markup)
 | 
			
		||||
@@ -125,10 +122,17 @@ class ListHandler(BaseHandler):
 | 
			
		||||
        await query.answer()
 | 
			
		||||
 | 
			
		||||
        list_object = context.user_data["current_list"]
 | 
			
		||||
        keyboard = [[InlineKeyboardButton(v, callback_data=k)] for k,v in list_object.content.items()]
 | 
			
		||||
        reply_markup = InlineKeyboardMarkup(keyboard)
 | 
			
		||||
        readable_it = printable_list(list_object)
 | 
			
		||||
       
 | 
			
		||||
        await query.edit_message_text("Which item would you like to toggle?", reply_markup = reply_markup)
 | 
			
		||||
        if readable_it:
 | 
			
		||||
            msg_content = "Which item would you like to toggle?"
 | 
			
		||||
            keyboard = [[InlineKeyboardButton(v, callback_data=k)] for k,v in zip(list_object.content.keys(), readable_it)]
 | 
			
		||||
            reply_markup = InlineKeyboardMarkup(keyboard)
 | 
			
		||||
        else:
 | 
			
		||||
            msg_content = "List empty"
 | 
			
		||||
            reply_markup = None
 | 
			
		||||
 | 
			
		||||
        await query.edit_message_text(msg_content, reply_markup = reply_markup)
 | 
			
		||||
        return ITEMTOGGLE
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -170,14 +174,10 @@ class ListHandler(BaseHandler):
 | 
			
		||||
        await query.answer()
 | 
			
		||||
        list_object = context.user_data["current_list"]
 | 
			
		||||
 | 
			
		||||
        content_it = list_object.content.values()
 | 
			
		||||
        done_it = [
 | 
			
		||||
            "· " if e is None \
 | 
			
		||||
            else "✅ " if e \
 | 
			
		||||
            else "❌ " \
 | 
			
		||||
            for e in list_object.done_dict.values()]
 | 
			
		||||
        if content_it:
 | 
			
		||||
            msg_content = "\n".join([f"{d} {c}" for d, c in zip(done_it, content_it)])
 | 
			
		||||
        readable_it = printable_list(list_object)
 | 
			
		||||
       
 | 
			
		||||
        if readable_it:
 | 
			
		||||
            msg_content = "\n".join(readable_it)
 | 
			
		||||
        else:
 | 
			
		||||
            msg_content = "List empty"
 | 
			
		||||
        
 | 
			
		||||
@@ -193,7 +193,6 @@ class ListHandler(BaseHandler):
 | 
			
		||||
        new = list_object.content
 | 
			
		||||
        new.update({"random_key": item})
 | 
			
		||||
        list_object.content = new
 | 
			
		||||
        # TODO test me!
 | 
			
		||||
        keyboard = [[InlineKeyboardButton("Add some more", callback_data="add"), InlineKeyboardButton("Back to the menu", callback_data="overview")]]
 | 
			
		||||
        reply_markup = InlineKeyboardMarkup(keyboard)
 | 
			
		||||
        await update.message.reply_text(f"Added {item}", reply_markup=reply_markup)
 | 
			
		||||
@@ -206,11 +205,10 @@ class ListHandler(BaseHandler):
 | 
			
		||||
        await query.answer()
 | 
			
		||||
 | 
			
		||||
        list_object = context.user_data["current_list"]
 | 
			
		||||
        old = list_object.done_dict[toggle_key]
 | 
			
		||||
        # if all None or all False (first toggle or all false) then set all dones to False
 | 
			
		||||
        if not any(list_object.done_dict.values()):
 | 
			
		||||
            new_done_dict = dict.fromkeys(list_object.done_dict, False)
 | 
			
		||||
        else: new_done_dict = list_object.done_dict
 | 
			
		||||
        old = list_object.done_dict[toggle_key] or False
 | 
			
		||||
        # if it was previously unset (None), we can later on set it to not old = True
 | 
			
		||||
        
 | 
			
		||||
        new_done_dict = list_object.done_dict
 | 
			
		||||
        new_done_dict[toggle_key] = not old
 | 
			
		||||
        list_object.done_dict = new_done_dict
 | 
			
		||||
 | 
			
		||||
@@ -236,3 +234,22 @@ class ListHandler(BaseHandler):
 | 
			
		||||
 | 
			
		||||
        await query.edit_message_text(f"Removed {name}", reply_markup=reply_markup)
 | 
			
		||||
        return ACTION
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def printable_list(list_object: ListModel):
 | 
			
		||||
    content_it = list_object.content.values()
 | 
			
		||||
    done_bool_it = list_object.done_dict.values()
 | 
			
		||||
    # distinguish the enumeration:
 | 
			
		||||
    # either all done_dict values are None -> the list is not toggleable
 | 
			
		||||
    # or at least one value is of type bool -> the list is toggleable and None === False
 | 
			
		||||
    if any([type(e) == bool for e in done_bool_it]):
 | 
			
		||||
        done_it = [
 | 
			
		||||
        "✅" if e else "❌" \
 | 
			
		||||
        for e in list_object.done_dict.values()
 | 
			
		||||
        ]
 | 
			
		||||
    else:
 | 
			
		||||
        done_it = ["-" for e in done_bool_it]
 | 
			
		||||
    
 | 
			
		||||
    readable_it = [f"{d} {c}" for d, c in zip(done_it, content_it)]
 | 
			
		||||
    return readable_it
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,7 @@ class BaseModel(Model):
 | 
			
		||||
 | 
			
		||||
class ListModel(BaseModel):
 | 
			
		||||
    name = CharField(default="")
 | 
			
		||||
    chat_id = IntegerField()
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def content(self) -> dict:
 | 
			
		||||
@@ -45,22 +46,6 @@ class ListEntryModel(BaseModel):
 | 
			
		||||
    done = BooleanField(default=None, null=True)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# class ListModel(BaseModel):
 | 
			
		||||
#     name = CharField(unique=True)
 | 
			
		||||
#     content = TextField(default="") # unlimited length, use to serialise list into
 | 
			
		||||
 | 
			
		||||
#     @property
 | 
			
		||||
#     def content_list(self):
 | 
			
		||||
#         return json.loads(self.content or '[]')
 | 
			
		||||
    
 | 
			
		||||
#     @content_list.setter
 | 
			
		||||
#     def content_list(self, list_content):
 | 
			
		||||
#         self.content = json.dumps(list_content)
 | 
			
		||||
#         with db:
 | 
			
		||||
#             self.save()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def set_db(db_path):
 | 
			
		||||
    db.initialize(SqliteDatabase(db_path))
 | 
			
		||||
    with db:
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,8 @@
 | 
			
		||||
import datetime
 | 
			
		||||
import os
 | 
			
		||||
from telegram.ext import ConversationHandler, CommandHandler, MessageHandler, filters, CallbackQueryHandler, CallbackContext
 | 
			
		||||
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update, InputMediaPhoto
 | 
			
		||||
import models
 | 
			
		||||
from telegram.constants import ParseMode
 | 
			
		||||
# ACTION_CHOICE, DATE_ENTRY, ADD_CONTENT = range(3)
 | 
			
		||||
MEMORY_CHOICE = range(1)
 | 
			
		||||
 | 
			
		||||
@@ -8,8 +10,7 @@ MEMORY_CHOICE = range(1)
 | 
			
		||||
from .basehandler import BaseHandler
 | 
			
		||||
 | 
			
		||||
class MemoryHandler(BaseHandler):
 | 
			
		||||
    def __init__(self, entry_string, models):
 | 
			
		||||
        self.models = models
 | 
			
		||||
    def __init__(self, entry_string):
 | 
			
		||||
        self.entry_string = entry_string
 | 
			
		||||
        self.handler = ConversationHandler(
 | 
			
		||||
            entry_points=[CommandHandler(entry_string, self.entry_point, )],
 | 
			
		||||
@@ -27,20 +28,27 @@ class MemoryHandler(BaseHandler):
 | 
			
		||||
 | 
			
		||||
    async def entry_point(self, update: Update, context: CallbackContext):
 | 
			
		||||
        await super().entry_point(update, context)
 | 
			
		||||
        if os.getenv("DOCKERIZED", "false") == "true" and os.getenv("CHAT_ID") != str(update.message.chat_id):
 | 
			
		||||
            await update.message.reply_text("You are not authorized to use this bot")
 | 
			
		||||
            return ConversationHandler.END
 | 
			
		||||
 | 
			
		||||
        search_string = " ".join(context.args)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        if search_string == '~photo':
 | 
			
		||||
            matching_models = self.models.JournalEntry.select().where(self.models.JournalEntry.media_path != "").order_by(self.models.JournalEntry.date)
 | 
			
		||||
            matching_models = models.JournalEntry.select().where(models.JournalEntry.media_path != "").order_by(models.JournalEntry.date)
 | 
			
		||||
        else: # searching for text
 | 
			
		||||
            matching_models = self.models.JournalEntry.select().where(
 | 
			
		||||
                self.models.JournalEntry.text.contains(
 | 
			
		||||
            matching_models = models.JournalEntry.select().where(
 | 
			
		||||
                models.JournalEntry.text.contains(
 | 
			
		||||
                    search_string
 | 
			
		||||
                )
 | 
			
		||||
            ).order_by(self.models.JournalEntry.date)
 | 
			
		||||
            ).order_by(models.JournalEntry.date)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        # exit if no memory matches the string
 | 
			
		||||
        if len(matching_models) == 0:
 | 
			
		||||
            await update.message.reply_text(f"There is no matching memory yet.")
 | 
			
		||||
            return ConversationHandler.END
 | 
			
		||||
 | 
			
		||||
        options = [[InlineKeyboardButton(m.date_pretty, callback_data=i)] for i,m in enumerate(matching_models)]
 | 
			
		||||
 | 
			
		||||
        keyboard = InlineKeyboardMarkup(options)
 | 
			
		||||
@@ -68,13 +76,15 @@ class MemoryHandler(BaseHandler):
 | 
			
		||||
                caption=
 | 
			
		||||
                    f"On {chosen_match.date_pretty}, "
 | 
			
		||||
                    f"{chosen_match.author} wrote: \n"
 | 
			
		||||
                    f"{chosen_match.text}"
 | 
			
		||||
                    f"{chosen_match.spoiler_text}",
 | 
			
		||||
                parse_mode=ParseMode.HTML
 | 
			
		||||
                )
 | 
			
		||||
        else:
 | 
			
		||||
            await query.edit_message_text(
 | 
			
		||||
                f"On {chosen_match.date_pretty}, "
 | 
			
		||||
                f"{chosen_match.author} wrote: \n"
 | 
			
		||||
                f"{chosen_match.text}"
 | 
			
		||||
                f"{chosen_match.spoiler_text}",
 | 
			
		||||
                parse_mode=ParseMode.HTML
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
        return ConversationHandler.END
 | 
			
		||||
 
 | 
			
		||||
@@ -4,18 +4,16 @@ import socket
 | 
			
		||||
from telegram.ext import ConversationHandler, CommandHandler, CallbackQueryHandler
 | 
			
		||||
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
 | 
			
		||||
from telegram.constants import ParseMode
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
FIRST = 1
 | 
			
		||||
from .basehandler import BaseHandler
 | 
			
		||||
class StatusHandler(BaseHandler):
 | 
			
		||||
    """Shows a short status of the program."""
 | 
			
		||||
    
 | 
			
		||||
    def __init__(self, entry_string, models):
 | 
			
		||||
    def __init__(self, entry_string):
 | 
			
		||||
        self.start_time = datetime.datetime.now()
 | 
			
		||||
        self.entry_string = entry_string
 | 
			
		||||
        self.models = models
 | 
			
		||||
        self.handler = ConversationHandler(
 | 
			
		||||
            entry_points=[CommandHandler(self.entry_string, self.entry_point)],
 | 
			
		||||
            states={
 | 
			
		||||
@@ -50,9 +48,11 @@ class StatusHandler(BaseHandler):
 | 
			
		||||
            local_ips = "not fetchable"
 | 
			
		||||
 | 
			
		||||
        message += "Status: Running 🟢\n"
 | 
			
		||||
        message += f"Version: `{os.getenv('BOT_VERSION', 'dev')}`\n"
 | 
			
		||||
        message += f"Uptime: `{delta[:delta.rfind('.')]}`\n"
 | 
			
		||||
        message += f"IP \(public\): `{ip}`\n"
 | 
			
		||||
        message += f"IP \(private\): `{local_ips}`\n"
 | 
			
		||||
        message += f"Chat ID: `{update.effective_chat.id}`\n"
 | 
			
		||||
 | 
			
		||||
        if update.message:
 | 
			
		||||
            await update.message.reply_text(message, reply_markup=reply_markup, parse_mode=ParseMode.MARKDOWN_V2)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,6 @@
 | 
			
		||||
import os
 | 
			
		||||
from pathlib import Path
 | 
			
		||||
from telegram.ext import ConversationHandler, CommandHandler, MessageHandler, filters, CallbackQueryHandler
 | 
			
		||||
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
 | 
			
		||||
from telegram.ext import MessageHandler, filters
 | 
			
		||||
from telegram import Update
 | 
			
		||||
import re
 | 
			
		||||
import random
 | 
			
		||||
@@ -18,37 +17,47 @@ TURTLE_VIDEOS = list(TURTLE_VIDEO_LOCATION.glob("*.mp4"))
 | 
			
		||||
class TurtleHandler(BaseHandler):
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self.entry_string = "Variation of hallo"
 | 
			
		||||
        self.handler = MessageHandler(filters.Regex(r"[hH]([aA]+|[eE]+)[lL]{2,}[oOöÖ]+(le)?|(chen)") |  # react to hello strings
 | 
			
		||||
                                      filters.Regex(b"\xF0\x9F\x90\xA2".decode("utf8")) |               # react to turtle emoji
 | 
			
		||||
                                      filters.Regex(r"[sS](childkröte)|[tT](urtle)"),                   # react to turtle string
 | 
			
		||||
                                      self.entry_point)
 | 
			
		||||
        pass
 | 
			
		||||
        self.handler = MessageHandler(
 | 
			
		||||
            filters.Regex(r"[hH]([aA]+|[eE]+)[lL]{2,}[oOöÖ]+(le|chen)?") |
 | 
			
		||||
            # react to hello strings
 | 
			
		||||
            filters.Regex(b"\xF0\x9F\x90\xA2".decode("utf8")) |
 | 
			
		||||
            # react to turtle emoji
 | 
			
		||||
            filters.Regex(r"[sS](childkröte)|[tT](urtle)"),
 | 
			
		||||
            # react to turtle string
 | 
			
		||||
            self.entry_point
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    async def entry_point(self, update: Update, context):
 | 
			
		||||
        await super().entry_point(update, context)
 | 
			
		||||
        msgtxt = update.message.text
 | 
			
		||||
        turtle_emoji = b"\xF0\x9F\x90\xA2".decode("utf8")
 | 
			
		||||
 | 
			
		||||
        if "hallo" in msgtxt:                                               # react to hallo
 | 
			
		||||
        if "hallo" in msgtxt:
 | 
			
		||||
            # react to hallo
 | 
			
		||||
            vid = TURTLE_VIDEOS[0]
 | 
			
		||||
            answertxt = "Hallo!"
 | 
			
		||||
        elif re.search("[eE][lL]{2,}[oO]", msgtxt):                         # react to hello
 | 
			
		||||
        elif re.search("[eE][lL]{2,}[oO]", msgtxt):
 | 
			
		||||
            # react to hello
 | 
			
		||||
            vid = TURTLE_VIDEOS[2]
 | 
			
		||||
            answertxt = "Hello!"        
 | 
			
		||||
        elif re.search("([aA]{4,}|[lL]{4,}|[oO]{4,}|[öÖ]{4,})", msgtxt):    # react to stretched hello
 | 
			
		||||
        elif re.search("([aA]{4,}|[lL]{4,}|[oO]{4,}|[öÖ]{4,})", msgtxt):
 | 
			
		||||
            # react to stretched hello
 | 
			
		||||
            vid = TURTLE_VIDEOS[5]
 | 
			
		||||
            answertxt = "That's a lot of letters!"
 | 
			
		||||
        elif re.search(turtle_emoji, msgtxt):                               # react to turtle emoji
 | 
			
		||||
            vid=TURTLE_VIDEOS[0] # TODO: choose video for smiley reaction
 | 
			
		||||
        elif re.search(turtle_emoji, msgtxt):
 | 
			
		||||
            # react to turtle emoji
 | 
			
		||||
            vid=TURTLE_VIDEOS[0]
 | 
			
		||||
            answertxt="Turtle detected! Self-destruction mode activated..."
 | 
			
		||||
        elif re.search("[sS](childkröte)|[tT](urtle)", msgtxt):             # react to turtle string
 | 
			
		||||
        elif re.search("[sS](childkröte)|[tT](urtle)", msgtxt):
 | 
			
		||||
            # react to turtle string
 | 
			
		||||
            vid=None
 | 
			
		||||
            answertxt=turtle_emoji
 | 
			
		||||
        else:
 | 
			
		||||
            vid = random.choice(TURTLE_VIDEOS[1:2]+TURTLE_VIDEOS[3:5]+TURTLE_VIDEOS[6:])
 | 
			
		||||
            answertxt = ""
 | 
			
		||||
 | 
			
		||||
        if vid!=None:
 | 
			
		||||
        if vid != None:
 | 
			
		||||
            if re.search(turtle_emoji, msgtxt):
 | 
			
		||||
                await update.message.reply_text(text=answertxt)
 | 
			
		||||
                time.sleep(1)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,22 +1,45 @@
 | 
			
		||||
import os
 | 
			
		||||
from pathlib import Path
 | 
			
		||||
from telegram.ext import ExtBot
 | 
			
		||||
import random
 | 
			
		||||
from telegram.error import BadRequest
 | 
			
		||||
import logging
 | 
			
		||||
from datetime import time, timedelta, timezone, datetime, date
 | 
			
		||||
from peewee import fn
 | 
			
		||||
import models
 | 
			
		||||
 | 
			
		||||
MEDIA_DIR = Path(os.getenv("MEDIA_DIR"))
 | 
			
		||||
CHAT_ID = os.getenv("CHAT_ID")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def set_random(bot: ExtBot) -> None:
 | 
			
		||||
    """Set a random chat photo."""
 | 
			
		||||
    if os.getenv("DOCKERIZED", "false") == "false":
 | 
			
		||||
        # only change image on prod
 | 
			
		||||
        return
 | 
			
		||||
class SetChatPhotoJob():
 | 
			
		||||
    def __init__(self, bot: ExtBot, job_queue):
 | 
			
		||||
        self.bot = bot
 | 
			
		||||
        self.logger = logging.getLogger(self.__class__.__name__)
 | 
			
		||||
        
 | 
			
		||||
    photos = list(MEDIA_DIR.glob("*.jpg")) + list(MEDIA_DIR.glob("*.png")) + list(MEDIA_DIR.glob("*.jpeg"))
 | 
			
		||||
        if os.getenv("DOCKERIZED", "false") != "true":
 | 
			
		||||
            # when running locally, annoy the programmer every 60 seconds <3
 | 
			
		||||
            job_queue.run_repeating(self.callback_photo, interval=60)
 | 
			
		||||
        else:
 | 
			
		||||
            # set the message sending time; include UTC shift +2
 | 
			
		||||
            sending_time = time(hour=12, minute=0, second=0, tzinfo=timezone(timedelta(hours=2)))
 | 
			
		||||
            job_queue.run_monthly(self.callback_photo, when=sending_time, day=-1)
 | 
			
		||||
 | 
			
		||||
    if len(photos) == 0:
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    photo = random.choice(photos)
 | 
			
		||||
    await bot.set_chat_photo(CHAT_ID, photo)
 | 
			
		||||
    async def callback_photo(self, context):
 | 
			
		||||
        
 | 
			
		||||
        # last_seen of memory must be older than 10 days in past or None
 | 
			
		||||
        with models.db:
 | 
			
		||||
            possible_photos = models.JournalEntry.select().where(
 | 
			
		||||
                models.JournalEntry.media_path != None
 | 
			
		||||
            ).order_by(fn.Random())
 | 
			
		||||
        
 | 
			
		||||
            try:
 | 
			
		||||
                chosen_entry = possible_photos.get()
 | 
			
		||||
            except:
 | 
			
		||||
                self.logger.warning("No photos available.")
 | 
			
		||||
                return
 | 
			
		||||
 | 
			
		||||
        chat_id = os.getenv("CHAT_ID")
 | 
			
		||||
        try:
 | 
			
		||||
            await self.bot.set_chat_photo(chat_id, chosen_entry.media_path)
 | 
			
		||||
        except BadRequest:
 | 
			
		||||
            self.logger.error("This is a private chat!")
 | 
			
		||||
            return
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										64
									
								
								bot/cronjob/random_memory.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								bot/cronjob/random_memory.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,64 @@
 | 
			
		||||
from datetime import time, timedelta, timezone, datetime, date
 | 
			
		||||
from telegram.constants import ParseMode
 | 
			
		||||
import os
 | 
			
		||||
from peewee import fn
 | 
			
		||||
import logging
 | 
			
		||||
import models
 | 
			
		||||
 | 
			
		||||
class RandomMemoryJob():
 | 
			
		||||
    def __init__(self, bot, job_queue):
 | 
			
		||||
        self.bot = bot
 | 
			
		||||
        self.logger = logging.getLogger(self.__class__.__name__)
 | 
			
		||||
        
 | 
			
		||||
        if os.getenv("DOCKERIZED", "false") != "true":
 | 
			
		||||
            # when running locally, annoy the programmer every 60 seconds <3
 | 
			
		||||
            job_queue.run_repeating(self.callback_memory, interval=3600)
 | 
			
		||||
            self.min_age = 0 # do not filter messages: show them all
 | 
			
		||||
        else:
 | 
			
		||||
            # set the message sending time; include UTC shift +2
 | 
			
		||||
            sending_time = time(hour=12, minute=0, second=0, tzinfo=timezone(timedelta(hours=2)))
 | 
			
		||||
            job_queue.run_daily(self.callback_memory, sending_time)
 | 
			
		||||
            self.min_age = 30 # days
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    async def callback_memory(self, context):
 | 
			
		||||
        
 | 
			
		||||
        # last_seen of memory must be older than 10 days in past or None
 | 
			
		||||
        with models.db:
 | 
			
		||||
            possible_entries = models.JournalEntry.select().where(
 | 
			
		||||
                (models.JournalEntry.last_shown <= datetime.today().date() - timedelta(days=self.min_age)) | \
 | 
			
		||||
                (models.JournalEntry.last_shown == None)
 | 
			
		||||
            ).order_by(fn.Random())
 | 
			
		||||
        
 | 
			
		||||
            try:
 | 
			
		||||
                chosen_entry = possible_entries.get()
 | 
			
		||||
            except:
 | 
			
		||||
                self.logger.warning("Come back later for another memory.")
 | 
			
		||||
                return
 | 
			
		||||
 | 
			
		||||
            # update the last_shown of the chosen entry
 | 
			
		||||
            chosen_entry.last_shown = datetime.today().date()
 | 
			
		||||
            chosen_entry.save()
 | 
			
		||||
 | 
			
		||||
        chat_id = os.getenv("CHAT_ID")
 | 
			
		||||
 | 
			
		||||
        if chosen_entry.media_path:
 | 
			
		||||
            await self.bot.send_photo(
 | 
			
		||||
                chat_id = chat_id,
 | 
			
		||||
                photo = chosen_entry.media_path,
 | 
			
		||||
                caption =
 | 
			
		||||
                    f"On {chosen_entry.date_pretty}, "
 | 
			
		||||
                    f"{chosen_entry.author} wrote: \n"
 | 
			
		||||
                    f"{chosen_entry.spoiler_text}",
 | 
			
		||||
                parse_mode=ParseMode.HTML
 | 
			
		||||
                )
 | 
			
		||||
        else:
 | 
			
		||||
            await self.bot.send_message(
 | 
			
		||||
                chat_id = chat_id,
 | 
			
		||||
                text =
 | 
			
		||||
                    f"On {chosen_entry.date_pretty}, "
 | 
			
		||||
                    f"{chosen_entry.author} wrote: \n"
 | 
			
		||||
                    f"{chosen_entry.spoiler_text}",
 | 
			
		||||
                parse_mode=ParseMode.HTML
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										23
									
								
								bot/main.py
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								bot/main.py
									
									
									
									
									
								
							@@ -5,14 +5,13 @@ import logging
 | 
			
		||||
import models
 | 
			
		||||
from commands import journal, status, turtle, memory, advent
 | 
			
		||||
from commands.list import list
 | 
			
		||||
from cronjob import chat_photo
 | 
			
		||||
from cronjob import chat_photo, random_memory
 | 
			
		||||
 | 
			
		||||
logging.basicConfig(
 | 
			
		||||
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
 | 
			
		||||
    level=logging.INFO
 | 
			
		||||
)
 | 
			
		||||
import asyncio
 | 
			
		||||
 | 
			
		||||
logging.getLogger("httpx").setLevel(logging.WARNING)
 | 
			
		||||
logger = logging.getLogger(__name__)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -24,22 +23,16 @@ def main() -> None:
 | 
			
		||||
    models.set_db(db_path)
 | 
			
		||||
    application = Application.builder().token(token).build()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    application.add_handler(journal.JournalHandler("journal", models).handler)
 | 
			
		||||
    application.add_handler(list.ListHandler("list", models).handler)
 | 
			
		||||
    application.add_handler(status.StatusHandler("status", models).handler)
 | 
			
		||||
    application.add_handler(journal.JournalHandler("journal").handler)
 | 
			
		||||
    application.add_handler(list.ListHandler("list").handler)
 | 
			
		||||
    application.add_handler(status.StatusHandler("status").handler)
 | 
			
		||||
    application.add_handler(turtle.TurtleHandler().handler)
 | 
			
		||||
    application.add_handler(memory.MemoryHandler("memory", models).handler)
 | 
			
		||||
    application.add_handler(memory.MemoryHandler("memory").handler)
 | 
			
		||||
    application.add_handler(advent.AdventsHandler("advent").handler)
 | 
			
		||||
 | 
			
		||||
    # application.add_handler(CommandHandler("help", help_command))
 | 
			
		||||
    # on non command i.e message - echo the message on Telegram
 | 
			
		||||
    # application.add_handler(InlineQueryHandler(inline_query))
 | 
			
		||||
    random_memory.RandomMemoryJob(application.bot, application.job_queue)
 | 
			
		||||
    chat_photo.SetChatPhotoJob(application.bot, application.job_queue)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    # on every start set a new chat photo
 | 
			
		||||
    # loop = asyncio.get_event_loop()
 | 
			
		||||
    asyncio.ensure_future(chat_photo.set_random(application.bot))
 | 
			
		||||
    # Run the bot until the user presses Ctrl-C
 | 
			
		||||
    application.run_polling()
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
from peewee import *
 | 
			
		||||
from pathlib import Path
 | 
			
		||||
import re
 | 
			
		||||
import os
 | 
			
		||||
import datetime
 | 
			
		||||
 | 
			
		||||
@@ -60,6 +61,25 @@ class JournalEntry(BaseModel):
 | 
			
		||||
        except ValueError: #fck windows
 | 
			
		||||
            return self.date.strftime('%a, %d. %b %Y')
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def spoiler_text(self) -> str:
 | 
			
		||||
        """Returns the text with all the frisky details hidden away"""
 | 
			
		||||
        new_text = self.text.replace("<", "<").replace(">", ">").replace("&", "&")
 | 
			
		||||
        pattern = re.compile(
 | 
			
		||||
            "("
 | 
			
		||||
            "(((?<=(\.|\!|\?)\s)[A-Z])|(^[A-Z]))" # beginning of a sentence
 | 
			
		||||
            "([^\.\!\?])+" # any character being part of a sentence
 | 
			
		||||
            "((\:\))|😇|😈)" # the smiley
 | 
			
		||||
            "([^\.\!\?])*" # continuation of sentence
 | 
			
		||||
            "(\.|\!|\?|\,|$)" # end of the sentence
 | 
			
		||||
            ")"
 | 
			
		||||
        )
 | 
			
		||||
        matches = pattern.findall(new_text)
 | 
			
		||||
        for match in matches:
 | 
			
		||||
            group_to_replace = match[0]
 | 
			
		||||
            new_text = new_text.replace(group_to_replace, f"<tg-spoiler>{group_to_replace}</tg-spoiler>")
 | 
			
		||||
        return new_text
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
def set_db(db_path):
 | 
			
		||||
    db.initialize(SqliteDatabase(db_path))
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +1,11 @@
 | 
			
		||||
apiVersion: apps/v1
 | 
			
		||||
kind: Deployment
 | 
			
		||||
metadata:
 | 
			
		||||
  namespace: journal
 | 
			
		||||
  name: journal-bot
 | 
			
		||||
  labels:
 | 
			
		||||
    app: journal-bot
 | 
			
		||||
spec:
 | 
			
		||||
# deployment running a single container
 | 
			
		||||
  # deployment running a single container
 | 
			
		||||
  selector:
 | 
			
		||||
    matchLabels:
 | 
			
		||||
      app: journal-bot
 | 
			
		||||
@@ -18,8 +17,7 @@ spec:
 | 
			
		||||
    spec:
 | 
			
		||||
      containers:
 | 
			
		||||
        - name: journal
 | 
			
		||||
          image: mollre/journal-bot:latest
 | 
			
		||||
          imagePullPolicy: Always
 | 
			
		||||
          image: mollre/journal-bot:1.0.19
 | 
			
		||||
          envFrom:
 | 
			
		||||
            - secretRef:
 | 
			
		||||
                name: journal-secret-env
 | 
			
		||||
@@ -39,10 +37,7 @@ spec:
 | 
			
		||||
apiVersion: v1
 | 
			
		||||
kind: PersistentVolume
 | 
			
		||||
metadata:
 | 
			
		||||
  namespace: journal
 | 
			
		||||
  name: "journal-data-nfs"
 | 
			
		||||
  # labels:
 | 
			
		||||
  #   directory: "journal-data"
 | 
			
		||||
spec:
 | 
			
		||||
  storageClassName: fast
 | 
			
		||||
  capacity:
 | 
			
		||||
@@ -52,12 +47,10 @@ spec:
 | 
			
		||||
  nfs:
 | 
			
		||||
    path: /export/kluster/journal-bot
 | 
			
		||||
    server: 192.168.1.157
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
apiVersion: v1
 | 
			
		||||
kind: PersistentVolumeClaim
 | 
			
		||||
metadata:
 | 
			
		||||
  namespace: journal
 | 
			
		||||
  name: "journal-data-nfs"
 | 
			
		||||
spec:
 | 
			
		||||
  storageClassName: "fast"
 | 
			
		||||
@@ -66,7 +59,3 @@ spec:
 | 
			
		||||
  resources:
 | 
			
		||||
    requests:
 | 
			
		||||
      storage: "5Gi"
 | 
			
		||||
  # selector:
 | 
			
		||||
  #   matchLabels:
 | 
			
		||||
  #     directory: "journal-data"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										9
									
								
								deployment/kustomization.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								deployment/kustomization.yaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
apiVersion: kustomize.config.k8s.io/v1beta1
 | 
			
		||||
kind: Kustomization
 | 
			
		||||
resources:
 | 
			
		||||
- ./namespace.yaml
 | 
			
		||||
- ./deployment.yaml
 | 
			
		||||
- ./sealedsecret.yaml
 | 
			
		||||
images:
 | 
			
		||||
- name: mollre/journal-bot
 | 
			
		||||
  newTag: 1.0.60
 | 
			
		||||
							
								
								
									
										6
									
								
								deployment/namespace.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								deployment/namespace.yaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
apiVersion: v1
 | 
			
		||||
kind: Namespace
 | 
			
		||||
metadata:
 | 
			
		||||
  name: journal
 | 
			
		||||
  labels:
 | 
			
		||||
    name: journal
 | 
			
		||||
							
								
								
									
										25
									
								
								deployment/sealedsecret.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								deployment/sealedsecret.yaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
{
 | 
			
		||||
  "kind": "SealedSecret",
 | 
			
		||||
  "apiVersion": "bitnami.com/v1alpha1",
 | 
			
		||||
  "metadata": {
 | 
			
		||||
    "name": "journal-secret-env",
 | 
			
		||||
    "namespace": "journal",
 | 
			
		||||
    "creationTimestamp": null
 | 
			
		||||
  },
 | 
			
		||||
  "spec": {
 | 
			
		||||
    "template": {
 | 
			
		||||
      "metadata": {
 | 
			
		||||
        "name": "journal-secret-env",
 | 
			
		||||
        "namespace": "journal",
 | 
			
		||||
        "creationTimestamp": null
 | 
			
		||||
      },
 | 
			
		||||
      "type": "Opaque"
 | 
			
		||||
    },
 | 
			
		||||
    "encryptedData": {
 | 
			
		||||
      "BOT_TOKEN": "AgBcFTg4wRI37/sXlk7bNO3IB9dC2CaVi/Oh9TQeQ/wN+rRkTTqp/dBpzX3Y1Zcp16d59AqT7y3DafGGZ/V87zcxG1bngdCZUsZfDmZMP0+z+10caMxjbSY4xfBW1/MEL3rW6ONOibhTAI9DDS3p3YCu1V92xRLvOUkwc+mCkV7fneWWGU/wgeci+C75PKTyGIilo5NZXROOyytN7BQwvOiY70j9m/NC9L0Ulbcppho9iuVsYVfkkWHOU6/OcOeL7vjWcvYFTleyI0oclLgtBUSJzBTqe5eJeZPGoVWMGwyMw2BqR8DgeGpDIuSnMEgssh9wUlhVvqkoI7CEUrJy5Rb2YnWcriIbfUfUMwbfc4EpBKt1VVlQcEQmN9jJdoOJ81ywRXl6CJTMMM4apB3iHsBWdzVXCG4I5c6Mv8+xg0V+AYdDt4pGwuRX9s66LShnjFJKnn68chNLnGfNlU68YdwFio0GJkV0/FnXIgTrOwdOovtBz1Gl3ORIWTmSkY7yBRyYBzvzEBlXBAuj51yhdykrmuW6B5CvwqXsm3ia1fvtWwNfvmKySjzbHZQHmbbYR9hLvWm+rPS7TFXw52W6jUyvHh6U2mSHwpwI2byIE+uhXjVQgYbmDgJW2gif3Aam+2VSaGSqWUz7ECSGy4mVC755CyoZl0HDP4PxuHq5kcGm34qmjTRNYM6Y2QvaVb7cBplsZfs+cH+gcfVu2gg3KvAEaFJk85Hz4pirRhcPsLNce6Iw5OegCZ5IQBrzOJXC",
 | 
			
		||||
      "CHAT_ID": "AgDIgpsygMIcsTDy8a49isS4Hfkmqa0oav+q7Mu7VtcPyrZ4o7hR1u/IlH8Qt4Cg/9QxOw7rJ4DfbK4GDmiOO1oOf0uaR6btLl+/GoKT3mbSHusWfHPrJDGX0SBFw7rOopC+LyFgDHPJEhbKviwnyrBkUuI6gnf1sic4jJ9arb/B97y89dMKFlVCbEzRCrTCK6WDBQ3Lpk+5MI+ugAPSKC8CqsjNc6jmWymdGMk/9n3sAdalfYBCucxHKeVgkrv4sPr9jEUEzIziKansavTs8qVbZgSUMEAAob2KBIAXLcRmo5ISwKvppuA6DMbbXEYEMHVJH9B4gI2eAxClOPVEOBElL+BtsJaSJnJbVEclMzOqwxXQRFPOq4BKxhguA+Uj8Vl8/2diwXEJoUiCZ5emGVvCFQd+Dr2LUPj4AO1AL4zAg+VahuqNV2gI/Dkxgt7Hj+i6jY/jmbk3MIJYjeZh0irmfsWQmUMcmizhxutQdV3kXhHSlomVDHuIdFHFIbjQrI8vSgeysQARSxrJZvt/qeNUNnD1InKa/EQ8I5XDX4o4qIV/pqY8XLVoTcciYDOPZEy3OleHK+26SJDkJOiDOAHbfIBeinaLvYIEW3BwgrakBD16HaNzYBPLPW2ikDCSBTyFRayvfkWHHUGawhdrauxvZzp5UsJViZogypBJuDT3SPvAOlAR4X8Yfr9SmwQYKv8rALH+wW7QtON6R9D7UA==",
 | 
			
		||||
      "DB_PATH": "AgACucJGoBiO/ymyf6FvEeuQ2MDo+c+VgNk30xY2EZSQZpAbNE6VbaMO0lZj++T82OOBnhfmXID+TWJTIwIHaD2nkPq/ISppBIobVmtUmsR+sm76tao02HJCtPGycyCu1zhEpKtwy3k5nsd0jclq4bQFHccnBaBdZ6xcvmevvJ+YddysHhjSb6ESOoah/5lGiAa3sHe1Hwg57FPZeVuZOCx+MbbmhAXCYbu2bdZzSWA/mFAf1F6qkxSAuVFMJtijPrM13UIVONBPg5E02NO1VEV+LkI5NTUNx9YHVlGNPxogabDq+lhNwulWtLPbKkAXn/CTgcB2vb03geeVN20yz1UzbrdV5CKpIGGZ1At8ehuNypFa595XBVFSmL8RWNmfHCAvypAypjxOMWa89qC0diJW4tY+BUrl2jrIXpARNlD2GTqp7InLtwFsFb3AUbpg+0mnqqiqmtqYKQWJj0WDvfs7ol6k6Qx7P0FdAfRq3ojzArRQ7MruI24CS1hGTQ/hBJaHrcMzEIn/ZkKqZ2fEdNkJt8tTfxVsZ/paE97ERfYeKsuK2uHqUgvSQ+0w7FK7m6PYNpY9gmqZMaqRA7VIRblNauEuLDAGw8Jgyb3YUiV3xLjBuvaCaAEbXOsNsIF35+ZCw2bsYmgSxqNO2b1LvW/uFSUonjVJ9yT9+Qv6V0YJhMztzDLpNKRIEBKgyUN/BE7hV9vtygaan/AkUVmHVA9BwrU=",
 | 
			
		||||
      "PERSISTENCE_DIR": "AgDF8D5PfJ4DF7wNd8hpEPdph3r/MvK8R/sREX83/b7jFJgSGb/Dku82vwtkDTzsk9A+gGgU//EILYt5Irlo5ObHlcKfimR4fTvdcO9lpBHJnbwXipUcg20Xz/awIGbD3yJmy0LJqgc5MVPtWicF/ZsxQkkcv3+DN4+BgXczncEL+3g55eEbCAwbmFSvdHWIZGbi04VmtmAlSduPVzi7nqH05Nslqtu4p5mZaxPHjGvna0DcIVQNFQC/Wgobox8pezeJ6tANUPFAUpJUp+E5N3q8DofZXiHBQTpNXo3tyM2JYT/IwovSIdPSgJeIhbrfP6hVKOeZjKqaC8/SV67R/1LUpdO7KeKig5d7LJa3vjeeDmrM/3+1vb0C96Xrgv39j4MyPx7HrZxFdOQif4PZlpLEfarEtuSFUAUXx4N2uhLbTyAXyl4dfGkqdbQ5O/UT6xxXw44JsK6DzOz5OkT6cB0uUvJa5TrHk+cVoxlUu3Ex/5o6KXnMFaxfzyizPXeiIs/mTT9Bq6nAtvGad84U6Wvua3ZPofOlH0gFyN8/uMJxwqXbKuO1iScjkxuCNX8YRFzcoWH7VXzbbNPIQLORTu9/PhAIRZXOSxZw2iPZVg3LKuyyW3MgTtnVvgrKYnynw1Yrvc7gu35MhwjvnRrPlVQ+yFrZuB3l2Cf0OWZwonlMr36TsPHIJq+wD4ZEja+ciOsRAWzWuxBEDQ=="
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user