File size: 5,796 Bytes
adb3bbe
b560569
896ae69
d252c6d
adb3bbe
538b42b
 
506f1ee
adb3bbe
 
b560569
adb3bbe
 
 
 
 
896ae69
adb3bbe
896ae69
 
 
 
 
 
adb3bbe
b560569
896ae69
a0b418d
8a531f0
adb3bbe
896ae69
8a531f0
 
b560569
 
adb3bbe
6e2376b
8a531f0
adb3bbe
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8a531f0
 
adb3bbe
8a531f0
4cc3230
 
 
 
 
88d3a6e
adb3bbe
 
 
88d3a6e
4cc3230
adb3bbe
bff5b73
cb4dce3
 
 
 
b8b7e00
538b42b
 
adb3bbe
 
 
 
 
 
 
 
 
 
 
 
 
 
8a531f0
 
73e88eb
 
adb3bbe
73e88eb
 
e3447a5
adb3bbe
d45a226
73e88eb
adb3bbe
 
 
 
 
 
 
 
 
 
 
 
 
 
7ab0240
adb3bbe
 
 
4cc3230
 
 
 
 
 
88d3a6e
 
 
4cc3230
adb3bbe
 
 
88d3a6e
adb3bbe
06d22e5
4cc3230
538b42b
 
 
b8b7e00
10b91c3
538b42b
 
bff5b73
b8b7e00
538b42b
 
 
b8b7e00
adb3bbe
 
 
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
# -*- coding: utf-8 -*-
import gradio as gr
import json
from Data_Fetching_and_Rendering import fetch_and_render_dashboard
from analytics_fetch_and_rendering import fetch_and_render_analytics
from mentions_dashboard import generate_mentions_dashboard


# Shared state
token_received = {"status": False, "token": None, "client_id": None}

# --- Handlers for token reception and status ---
def receive_token(accessToken: str, client_id: str):
    """
    Called by a hidden POST mechanism to supply the OAuth code/token and client ID.
    """
    try:
        token_dict = json.loads(accessToken.replace("'", '"'))
    except json.JSONDecodeError as e:
        return {
            "status": "❌ Invalid token format",
            "token": "",
            "client_id": client_id
        }
    
    token_received["status"] = True
    token_received["token"] = token_dict
    token_received["client_id"] = client_id
    return {
        "status": "βœ… Token received",
        "token": token_dict.get("access_token", ""),
        "client_id": client_id
    }

def check_status():
    return "βœ… Token received" if token_received["status"] else "❌ Waiting for token…"

def show_token():
    return token_received["token"].get("access_token", "") if token_received["status"] else ""

def show_client():
    return token_received["client_id"] or "" if token_received["status"] else ""

# --- Guarded fetch functions ---
def guarded_fetch_dashboard():
    if not token_received["status"]:
        return "<p style='color:red; text-align:center;'>❌ Access denied. No token available. Please send token first.</p>"
    # token_received["client_id"] and token_received["token"] required by fetch function
    html = fetch_and_render_dashboard(
        token_received["client_id"],
        token_received["token"]
    )
    return html


def guarded_fetch_analytics():
    if not token_received["status"]:
        return (
            "<p style='color:red; text-align:center;'>❌ Access denied. No token available.</p>",
            None,
            None
        )
    count_md, plot, growth_plot, avg_post_eng_rate = fetch_and_render_analytics(
        token_received["client_id"],
        token_received["token"]
    )
    return count_md, plot, growth_plot, avg_post_eng_rate


def run_mentions_and_load():
    html, fig = generate_mentions_dashboard(
        token_received["client_id"],
        token_received["token"]
    )
    return html, fig


# --- Build the Gradio UI ---
with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky"),
               title="LinkedIn Post Viewer & Analytics") as app:
    gr.Markdown("# πŸš€ LinkedIn Organization Post Viewer & Analytics")
    gr.Markdown("Send your OAuth token via API call, then explore dashboard and analytics.")

    # Hidden elements: simulate POST endpoint
    hidden_token = gr.Textbox(visible=False, elem_id="hidden_token")
    hidden_client = gr.Textbox(visible=False, elem_id="hidden_client_id")
    hidden_btn = gr.Button(visible=False, elem_id="hidden_btn")

    status_box = gr.Textbox(value=check_status(), label="Status", interactive=False)
    token_display = gr.Textbox(value=show_token(), label="Access Token", interactive=False)
    client_display = gr.Textbox(value=show_client(), label="Client ID", interactive=False)

    # Wire hidden POST handler
    hidden_btn.click(
        fn=receive_token,
        inputs=[hidden_token, hidden_client],
        outputs=[status_box, token_display, client_display]
    )

    # Polling timer to update status and displays
    timer = gr.Timer(1.0)
    timer.tick(fn=check_status, outputs=status_box)
    timer.tick(fn=show_token, outputs=token_display)
    timer.tick(fn=show_client, outputs=client_display)

    # Tabs for functionality
    with gr.Tabs():
        with gr.TabItem("1️⃣ Dashboard"):
            gr.Markdown("View your organization's recent posts and their engagement statistics.")
            fetch_dashboard_btn = gr.Button("πŸ“Š Fetch Posts & Stats", variant="primary")
            dashboard_html = gr.HTML(value="<p style='text-align: center; color: #555;'>Waiting for token...</p>")
            fetch_dashboard_btn.click(
                fn=guarded_fetch_dashboard,
                inputs=[],
                outputs=[dashboard_html]
            )

        with gr.TabItem("2️⃣ Analytics"):
            gr.Markdown("View follower count and monthly gains for your organization.")
            fetch_analytics_btn = gr.Button("πŸ“ˆ Fetch Follower Analytics", variant="primary")
            
            follower_count = gr.Markdown("<p style='text-align: center; color: #555;'>Waiting for token...</p>")
            
            with gr.Row():  # Use Row to align the two plots side-by-side
                follower_plot = gr.Plot(visible=False)
                growth_rate_plot = gr.Plot(visible=False)

            with gr.Row():
                post_eng_rate_plot = gr.Plot(visible=False)
        
            fetch_analytics_btn.click(
                fn=guarded_fetch_analytics,
                inputs=[],
                outputs=[follower_count, follower_plot, growth_rate_plot, post_eng_rate_plot]
            )


        with gr.TabItem("3️⃣ Mentions"):
            gr.Markdown("Analyze sentiment of recent posts that mention your organization.")
            fetch_mentions_btn = gr.Button("🧠 Fetch Mentions & Sentiment", variant="primary")
            mentions_html = gr.HTML()
            mentions_plot = gr.Plot(visible=False)
            fetch_mentions_btn.click(
                fn=run_mentions_and_load,
                inputs=[],
                outputs=[mentions_html, mentions_plot]
            )



# Launch the app
if __name__ == "__main__":
    app.launch(server_name="0.0.0.0", server_port=7860, share=True)