Commit fd092ce9 authored by Markus Mößler's avatar Markus Mößler
Browse files

updated backend to get and post blog posts

parent 653562a0
Loading
Loading
Loading
Loading
+81 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import logging
# Configure logging
logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
from datetime import datetime, date

from tornado.options import define, options

@@ -77,6 +78,8 @@ class Application(tornado.web.Application):
            (r"/tornado-backend/login", AuthorLoginHandler),
            (r"/tornado-backend/logout", AuthLogoutHandler),
            (r"/tornado-backend/get-user-role", GetUserRoleHandler),
            (r"/tornado-backend/blog-entries", BlogEntriesHandler),
            (r"/tornado-backend/create-blog-entry", CreateBlogEntryHandler),            
        ]
        settings = dict(
            blog_title="Tornado Blog",
@@ -154,6 +157,12 @@ class BaseHandler(tornado.web.RequestHandler):
    async def any_author_exists(self):
        return bool(await self.query("SELECT * FROM authors LIMIT 1"))
    
    # Serialization of dates
    def date_serialization(self, obj):
        if isinstance(obj, (date, datetime)):
            return obj.isoformat()
        raise TypeError(f"Object of type {obj.__class__.__name__} is not JSON serializable")
  

class HomeHandler(BaseHandler):
    async def get(self):
@@ -400,6 +409,78 @@ class GetUserRoleHandler(BaseHandler):
        return


class BlogEntriesHandler(BaseHandler):
    async def get(self):
        try:
            # Query to fetch all entries, ordered by published date
            entries = await self.query("SELECT * FROM entries ORDER BY published DESC")

            logging.info(f"logging of entries: {entries}")
            
            # Format the entries as a JSON response
            # self.write({"status": "success", "data": entries})
            self.write(json.dumps({"status": "success",
                                   "data": entries
                                   }, default=self.date_serialization))

        except Exception as e:
            logging.error(f"Error fetching blog entries: {e}")
            self.set_status(500)
            self.write({"status": "error", "message": "Failed to fetch blog entries"})


class CreateBlogEntryHandler(BaseHandler):
    @tornado.web.authenticated
    async def post(self):
        logging.info(f"Data arriving at CreateBlogEntryHandler {self.request.body}")
        try:
            # Parse JSON data from the request body
            data = json.loads(self.request.body)
            logging.info(f"Data arriving at CreateBlogEntryHandler {data}")
            title = data.get("title")
            text = data.get("markdown")

            if not title or not text:
                raise tornado.web.HTTPError(400, "Title and markdown are required")

            # Convert markdown to HTML
            html = markdown.markdown(text)

            # Generate a unique slug from the title
            slug = unicodedata.normalize("NFKD", title)
            slug = re.sub(r"[^\w]+", "-", slug)
            slug = slug.strip("-").lower()
            slug = slug.encode("ascii", "ignore").decode("ascii")
            if not slug:
                slug = "entry"

            # Ensure slug uniqueness
            while True:
                existing = await self.query("SELECT * FROM entries WHERE slug = %s", slug)
                if not existing:
                    break
                slug += "-2"

            # Insert the new entry into the database
            await self.execute(
                "INSERT INTO entries (author_id, title, slug, markdown, html, published, updated) "
                "VALUES (%s, %s, %s, %s, %s, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)",
                self.current_user.id,
                title,
                slug,
                text,
                html,
            )

            # Respond with success
            self.write({"status": "success", "message": "Blog post created", "slug": slug})

        except Exception as e:
            logging.error(f"Error creating blog post: {e}")
            self.set_status(500)
            self.write({"status": "error", "message": "Failed to create blog post"})


async def main():
    tornado.options.parse_command_line()