itachi-ai commited on
Commit
745dedb
·
verified ·
1 Parent(s): 7fb384d

initial commit

Browse files
Files changed (5) hide show
  1. admin.py +125 -0
  2. app.py +9 -0
  3. home.py +27 -0
  4. mongodb.py +70 -0
  5. requirements.txt +3 -0
admin.py ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import streamlit as st
3
+ from mongodb import add_post,get_post_titles, get_post_by_id, update_post, delete_post
4
+ from dotenv import load_dotenv
5
+ load_dotenv()
6
+
7
+
8
+ USERNAME = os.getenv("_USERNAME_")
9
+ PASSWORD = os.getenv("_PASSWORD_")
10
+
11
+ print(USERNAME, PASSWORD)
12
+ def admin():
13
+
14
+ # Create a placeholder for the password input field
15
+ user_placeholder = st.empty()
16
+ password_placeholder = st.empty()
17
+
18
+ # Show password input if it's not already correct
19
+ username = user_placeholder.text_input("Enter Username")
20
+ password = password_placeholder.text_input("Enter Password", type="password")
21
+
22
+ # Check if the password is correct
23
+ if password == PASSWORD and username == USERNAME:
24
+ password_placeholder.empty() # Hide the password input
25
+ user_placeholder.empty() # Hide the password input
26
+
27
+ tab1, tab2, tab3 = st.tabs(["Read Post", "Add Post", "Update & Delete Post"])
28
+
29
+ with tab1:
30
+ if st.session_state.get('selected_post_id', None):
31
+ selected_post = get_post_by_id(st.session_state.selected_post_id)
32
+
33
+ # Display the content of the selected post
34
+ st.subheader(selected_post["title"])
35
+ st.divider()
36
+ st.markdown(selected_post["content"]) # Render the content as Markdown
37
+
38
+ with tab2:
39
+ st.subheader("Add a new Post")
40
+ title = st.text_input("Post Title")
41
+
42
+ # Text input area for Markdown content
43
+ content = st.text_area("Post Content (Markdown supported)", height=800)
44
+
45
+ status = st.selectbox("Status", ["private", "public", "achieve"], index=0)
46
+
47
+ if st.button("Add Post"):
48
+ if title and content:
49
+ res = add_post(title, content, status, username)
50
+ st.write(res)
51
+ else:
52
+ st.error("Please fill both the title and content.")
53
+
54
+ with tab3:
55
+
56
+ show_status = st.sidebar.selectbox("Status", ["private", "public", "achieve"], index = 1)
57
+ post_titles = list(get_post_titles(show_status))
58
+
59
+ if post_titles:
60
+ # Use session state to remember the selected post ID
61
+ if "selected_post_id" not in st.session_state:
62
+ st.session_state.selected_post_id = None
63
+
64
+ # Display titles as clickable buttons in the sidebar
65
+ selected_post = None
66
+ for post in post_titles:
67
+ # Check if the post is selected
68
+ if st.sidebar.button(post["title"], key=f"button_{post['_id']}"):
69
+ st.session_state.selected_post_id = post["_id"]
70
+
71
+ # Only show the update section if a post is selected
72
+ if st.session_state.selected_post_id:
73
+ post_id = st.session_state.selected_post_id
74
+ selected_post = get_post_by_id(post_id)
75
+
76
+ if selected_post:
77
+ # Display the content of the selected post
78
+ new_title = st.text_input("New Title", value=selected_post["title"])
79
+ new_content = st.text_area("New Content (Markdown supported)", value=selected_post["content"],
80
+ height=800)
81
+
82
+ options = ["private", "public", "achieve"]
83
+ new_status = st.selectbox("Status", options, index= options.index(selected_post['status']), key="status_update")
84
+ left, right = st.columns(2)
85
+
86
+ if left.button("Update Post", use_container_width=True, key=f"update_button_{post_id}"):
87
+ if new_title and new_content:
88
+ # Call the update_post function to save the changes to MongoDB
89
+ res = update_post(post_id, new_title, new_content, new_status)
90
+ st.success(res) # Display the result from the update function
91
+ # Optionally, display updated content for the user to confirm the changes
92
+ else:
93
+ st.error("Please fill both the new title and content.")
94
+
95
+ # Permanent delete logic
96
+ delete_password = st.text_input("Password", type="password", key=f"delete_password_{post_id}")
97
+ delete_button = right.button("Permanent Delete Post", use_container_width=True,
98
+ key=f"delete_button_{post_id}")
99
+
100
+ if delete_button:
101
+ if delete_password == PASSWORD:
102
+ res = delete_post(post_id)
103
+ if res:
104
+ st.success("Post deleted successfully!")
105
+ st.session_state.selected_post_id = None # Reset selected post after deletion
106
+ post_titles = list(get_post_titles(show_status)) # Refresh the list of posts
107
+ else:
108
+ st.error("An error occurred while deleting the post.")
109
+ elif delete_password: # If password is filled but incorrect
110
+ st.error("Incorrect password.")
111
+ else:
112
+ st.error("Post not found.")
113
+ else:
114
+ st.error("Please select a post first.")
115
+
116
+ else:
117
+ st.write("No posts available.")
118
+
119
+
120
+ else:
121
+ if password: # If password is entered but incorrect
122
+ st.error("Incorrect password. Please try again.")
123
+ else: # If no password is entered
124
+ st.info("Please enter your Username & Password.")
125
+
app.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from admin import admin
3
+
4
+ pg = st.navigation([
5
+ st.Page("home.py", title="Home", icon="🔥"),
6
+ st.Page(admin, title="Itachi", icon=":material/favorite:"),
7
+ ])
8
+
9
+ pg.run()
home.py ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import streamlit as st
3
+ from mongodb import get_post_titles, get_post_by_id
4
+
5
+ post_titles = list(get_post_titles("public"))
6
+
7
+ if post_titles:
8
+ st.sidebar.subheader("Select a post to view:")
9
+
10
+ # Display titles as clickable buttons in the sidebar
11
+ selected_post = None
12
+ for post in post_titles:
13
+ if st.sidebar.button(post["title"]):
14
+ # Get the content of the clicked post
15
+ post_id = post["_id"]
16
+ selected_post = get_post_by_id(post_id)
17
+
18
+ # Display the content of the selected post
19
+ st.subheader(selected_post["title"])
20
+ st.divider()
21
+ st.markdown(selected_post["content"]) # Render the content as Markdown
22
+
23
+ # Provide options to update or delete the selected post
24
+ else:
25
+ st.sidebar.write("No posts available.")
26
+
27
+
mongodb.py ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pymongo import MongoClient
2
+ from bson.objectid import ObjectId
3
+ from datetime import datetime
4
+ import os
5
+ from dotenv import load_dotenv
6
+ load_dotenv()
7
+
8
+ uri = os.getenv("_DATABASE_URL_")
9
+ client = MongoClient(uri)
10
+ db = client["blog_db"] # Create a database called blog_db
11
+ collection = db["posts"] # Create a collection called posts
12
+
13
+
14
+ # Function to add a new post
15
+ def add_post(title, content, status, username):
16
+ now = datetime.utcnow()
17
+ post = {
18
+ "title": title,
19
+ "content": content,
20
+ "createdAt": now,
21
+ "updatedAt": now,
22
+ "status": status,
23
+ "auther": username
24
+ }
25
+ collection.insert_one(post)
26
+ return "Post added successfully!"
27
+
28
+
29
+ # Function to update a post
30
+ def update_post(post_id, title, content, status):
31
+ # Ensure post_id is a valid ObjectId
32
+ try:
33
+ post_id = ObjectId(post_id)
34
+ except Exception as e:
35
+ return f"Invalid post ID: {str(e)}"
36
+
37
+ # Update the post in the collection
38
+ result = collection.update_one({"_id": post_id}, {"$set": {"title": title,
39
+ "content": content,
40
+ "status": status,
41
+ "updatedAt": datetime.utcnow(),
42
+
43
+ }})
44
+
45
+ if result.matched_count == 1: # Check if a document was found and updated
46
+ return "Post updated successfully!"
47
+ else:
48
+ return "Post not found or no changes were made."
49
+
50
+ # Function to delete a post
51
+ def delete_post(post_id):
52
+ collection.delete_one({"_id": ObjectId(post_id)})
53
+ return "Post deleted successfully!"
54
+
55
+
56
+ # Function to get all posts (just titles for the sidebar)
57
+ def get_post_titles(status):
58
+ titles = collection.find(
59
+ {"status": status}, # Filter by status
60
+ {"_id": 1, "title": 1} # Get only title and _id
61
+ ).sort("createdAt", -1) # Sort by createdAt in descending order (latest first)
62
+
63
+ return titles
64
+
65
+
66
+ # Function to get a specific post by id
67
+ def get_post_by_id(post_id):
68
+ post = collection.find_one({"_id": ObjectId(post_id)})
69
+ return post
70
+
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ streamlit
2
+ python-dotenv
3
+ pymongo