File size: 7,027 Bytes
0e82287
b4647d9
3263161
816442c
67b56c1
3263161
 
0e82287
816442c
 
 
f610f97
816442c
 
b24c605
 
 
 
 
1108709
67b56c1
b24c605
 
5647172
 
b24c605
 
 
 
 
 
 
 
 
 
 
 
 
67b56c1
b24c605
 
5647172
 
b24c605
 
 
 
 
 
 
 
 
67b56c1
b24c605
 
 
 
 
 
67b56c1
b24c605
80cfe5c
b24c605
 
 
 
 
 
 
1108709
67b56c1
0e82287
80cfe5c
1108709
 
0e82287
 
 
 
 
5813da0
0e82287
 
 
67b56c1
0e82287
80cfe5c
1108709
 
0e82287
 
 
 
9a075f0
0e82287
67b56c1
0e82287
80cfe5c
1108709
0e82287
1108709
 
 
0e82287
 
 
 
 
 
 
 
 
67b56c1
0e82287
5813da0
 
 
80cfe5c
 
5813da0
 
 
 
 
 
 
 
0e82287
 
 
 
 
3fee6ee
0e82287
9a075f0
 
3a5a033
9a075f0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0e82287
3a5a033
0e82287
80cfe5c
 
b24c605
 
 
 
 
 
 
5813da0
b24c605
 
 
 
 
5813da0
b24c605
 
5813da0
 
b24c605
 
 
 
 
 
 
 
 
31cd757
 
b24c605
31cd757
 
3a5a033
 
 
80cfe5c
3a5a033
 
 
80cfe5c
 
3a5a033
80cfe5c
 
 
 
 
 
1108709
0e82287
b4647d9
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
import streamlit as st

from postly.clients.singleton_client import SingletonPostlyClient
from postly.common.css import get_theme

# Initialize the PostlyClient singleton
client = SingletonPostlyClient.get_instance()

# Custom CSS for Twitter-like feel
st.markdown(
    get_theme(),
    unsafe_allow_html=True,
)

# Initialize user session state
if "logged_in" not in st.session_state:
    st.session_state.logged_in = False
if "current_user" not in st.session_state:
    st.session_state.current_user = None


def register():
    st.title("Register")
    user_name = st.text_input("Enter user name", placeholder="Username")
    password = st.text_input("Enter password", type="password", placeholder="Password")
    if st.button("Register"):
        if user_name and password:
            try:
                client.add_user(user_name, password)
                st.session_state.logged_in = True
                st.session_state.current_user = user_name
                st.success(f"User '{user_name}' registered and logged in successfully.")
                st.rerun()
            except ValueError as e:
                st.error(f"Error: {e}")
        else:
            st.error("Please enter both user name and password.")


def login():
    st.title("Login")
    user_name = st.text_input("Enter user name", placeholder="Username")
    password = st.text_input("Enter password", type="password", placeholder="Password")
    if st.button("Login"):
        if client.authenticate_user(user_name, password):
            st.session_state.logged_in = True
            st.session_state.current_user = user_name
            st.success(f"User '{user_name}' logged in successfully.")
            st.rerun()
        else:
            st.error("Invalid user name or password.")


def logout():
    st.session_state.logged_in = False
    st.session_state.current_user = None
    st.success("Logged out successfully.")
    st.rerun()


def delete_own_user():
    st.title("Delete Account ❌")
    if st.button("Delete Account"):
        try:
            client.delete_user(st.session_state.current_user)
            st.success(f"User '{st.session_state.current_user}' deleted successfully.")
            logout()
        except KeyError as e:
            st.error(f"Error: {e}")


def get_posts_for_user():
    st.title("Get Posts for User πŸ”Ž")
    users = client.get_users()
    user_name = st.selectbox("Select user name", users)
    if st.button("Get Posts"):
        try:
            posts = client.get_posts_for_user(user_name)
            st.write(f"Posts for user '{user_name}':")
            for post in posts:
                st.markdown(post)
        except KeyError as e:
            st.error(f"Error: {e}")


def get_posts_for_topic():
    st.title("Get Posts for Topic πŸ”Ž")
    topics = client.get_topics()
    topic = st.selectbox("Enter topic", topics)
    if st.button("Get Posts"):
        posts = client.get_posts_for_topic(topic)
        st.write(f"Posts for topic '{topic}':")
        for post in posts:
            st.markdown(post)


def get_trending_topics():
    st.title("Get Trending Topics πŸ“Š")
    current_timestamp = client.get_current_timestamp()
    from_timestamp = st.number_input("Enter from timestamp", min_value=0, step=1)
    to_timestamp = st.number_input(
        "Enter to timestamp", min_value=0, max_value=current_timestamp, step=1, value=current_timestamp
    )
    if st.button("Get Trending Topics"):
        try:
            topics = client.get_trending_topics(int(from_timestamp), int(to_timestamp))
            st.write("Trending topics:")
            for topic in topics:
                st.write(topic)
        except ValueError as e:
            st.error(f"Error: {e}")


def get_all_posts():
    st.title("Feed")

    # Add post section at the top
    post_text = st.text_area("What's happening? πŸ’¬", key="new_post_text")
    if st.button("Add Post πŸ–ŠοΈ"):
        try:
            client.add_post(st.session_state.current_user, post_text)
            st.success("Post added successfully.")
            st.rerun()
        except Exception as e:
            st.error(f"Error: {e}")

    # Display all posts
    posts = client.get_posts()
    all_posts = []
    for user_name, user_posts in posts.items():
        for post in user_posts:
            all_posts.append((user_name, post))
    sorted_posts = sorted(all_posts, key=lambda x: x[1].timestamp)[::-1]
    for user_name, post in sorted_posts:
        liked = st.session_state.current_user in post.liked_by
        like_button_label = "πŸ‘" if not liked else "πŸ‘Ž"

        col1, col2 = st.columns([4, 1])
        with col1:
            st.markdown(
                f"""
                <div class="post-container">
                    <div class="post-header">{user_name}</div>
                    <div class="post-content">{post.content}</div>
                    <div class="post-timestamp">{post.timestamp}</div>
                    <div class="post-likes">Likes: {post.likes}</div>
                </div>
                """,
                unsafe_allow_html=True,
            )
        with col2:
            if st.button(like_button_label, key=f"like_{post.timestamp}"):
                client.like_post(st.session_state.current_user, post.timestamp)
                st.rerun()


def main():
    st.sidebar.title("Postly πŸ“\nSimple social media platform")

    if st.session_state.logged_in:
        st.sidebar.write(f"Logged in as: {st.session_state.current_user}")
        if st.sidebar.button("Logout"):
            logout()
        page = st.sidebar.selectbox(
            "Choose an action",
            [
                "View All Posts",
                "Delete Account",
                "Get Posts for User",
                "Get Posts for Topic",
                "Get Trending Topics",
            ],
            index=0,
        )

        if page == "View All Posts":
            get_all_posts()
        elif page == "Delete Account":
            delete_own_user()
        elif page == "Get Posts for User":
            get_posts_for_user()
        elif page == "Get Posts for Topic":
            get_posts_for_topic()
        elif page == "Get Trending Topics":
            get_trending_topics()
    else:
        page = st.sidebar.selectbox("Choose an action", ["Register", "Login"], index=0)
        if page == "Register":
            register()
        elif page == "Login":
            login()

    st.sidebar.markdown(
        """
        **About Postly**

        Welcome to Postly, a simple social media platform created for fun.
        This app allows different users to share posts and like each other's posts.

        **Important Information**

        - The entire app is kept in global memory for all users accessing the app on the same instance.
        - Do not use a username and password actually used with any other apps.
        - We hash the password, but no real attempt to make a bulletproof solution was made.
        """
    )


if __name__ == "__main__":
    main()