Spaces:
Paused
Paused
Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,115 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import dash
|
2 |
+
from dash import dcc, html, Input, Output, State, callback
|
3 |
+
import dash_bootstrap_components as dbc
|
4 |
+
import uuid
|
5 |
+
import sqlite3
|
6 |
+
|
7 |
+
app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
|
8 |
+
|
9 |
+
# Initialize SQLite database
|
10 |
+
conn = sqlite3.connect('links.db', check_same_thread=False)
|
11 |
+
c = conn.cursor()
|
12 |
+
|
13 |
+
# Create table if it doesn't exist
|
14 |
+
c.execute('''CREATE TABLE IF NOT EXISTS links
|
15 |
+
(id TEXT PRIMARY KEY, name TEXT, url TEXT)''')
|
16 |
+
conn.commit()
|
17 |
+
|
18 |
+
# Function to get all links from the database
|
19 |
+
def get_links():
|
20 |
+
c.execute("SELECT * FROM links")
|
21 |
+
return [{"id": row[0], "name": row[1], "url": row[2]} for row in c.fetchall()]
|
22 |
+
|
23 |
+
# Initialize with some example URLs if the table is empty
|
24 |
+
if not get_links():
|
25 |
+
initial_urls = [
|
26 |
+
{"id": str(uuid.uuid4()), "name": "Google", "url": "https://www.google.com"},
|
27 |
+
{"id": str(uuid.uuid4()), "name": "Bing", "url": "https://www.bing.com"},
|
28 |
+
]
|
29 |
+
c.executemany("INSERT INTO links VALUES (:id, :name, :url)", initial_urls)
|
30 |
+
conn.commit()
|
31 |
+
|
32 |
+
app.layout = dbc.Container([
|
33 |
+
dbc.Row([
|
34 |
+
# Left navigation column
|
35 |
+
dbc.Col([
|
36 |
+
html.H2("My URL App", className="mt-3 mb-4"),
|
37 |
+
html.Div(id='url-list'),
|
38 |
+
dbc.Input(id='new-url-name', placeholder="New URL Name", className="mb-2"),
|
39 |
+
dbc.Input(id='new-url-link', placeholder="New URL", className="mb-2"),
|
40 |
+
dbc.Button("Add URL", id='add-url-button', color="primary", className="mb-3"),
|
41 |
+
], width=3, className="bg-light p-3"),
|
42 |
+
|
43 |
+
# Main content column with iframe
|
44 |
+
dbc.Col([
|
45 |
+
html.Iframe(id='content-iframe', style={'width': '100%', 'height': '800px'})
|
46 |
+
], width=9)
|
47 |
+
])
|
48 |
+
], fluid=True)
|
49 |
+
|
50 |
+
@callback(
|
51 |
+
Output('url-list', 'children'),
|
52 |
+
Input('add-url-button', 'n_clicks'),
|
53 |
+
State('new-url-name', 'value'),
|
54 |
+
State('new-url-link', 'value')
|
55 |
+
)
|
56 |
+
def update_url_list(n_clicks, new_name, new_link):
|
57 |
+
ctx = dash.callback_context
|
58 |
+
if ctx.triggered_id == 'add-url-button' and new_name and new_link:
|
59 |
+
new_id = str(uuid.uuid4())
|
60 |
+
c.execute("INSERT INTO links VALUES (?, ?, ?)", (new_id, new_name, new_link))
|
61 |
+
conn.commit()
|
62 |
+
|
63 |
+
links = get_links()
|
64 |
+
return [
|
65 |
+
dbc.Button(
|
66 |
+
link['name'],
|
67 |
+
id={'type': 'url-button', 'index': link['id']},
|
68 |
+
color="link",
|
69 |
+
className="d-block text-left mb-2"
|
70 |
+
) for link in links
|
71 |
+
] + [
|
72 |
+
dbc.Button(
|
73 |
+
"Delete",
|
74 |
+
id={'type': 'delete-button', 'index': link['id']},
|
75 |
+
color="danger",
|
76 |
+
size="sm",
|
77 |
+
className="mr-2 mb-2"
|
78 |
+
) for link in links
|
79 |
+
]
|
80 |
+
|
81 |
+
@callback(
|
82 |
+
Output('content-iframe', 'src'),
|
83 |
+
Input({'type': 'url-button', 'index': dash.ALL}, 'n_clicks')
|
84 |
+
)
|
85 |
+
def update_iframe(n_clicks):
|
86 |
+
ctx = dash.callback_context
|
87 |
+
if not ctx.triggered:
|
88 |
+
return dash.no_update
|
89 |
+
button_id = ctx.triggered[0]['prop_id'].split('.')[0]
|
90 |
+
clicked_id = eval(button_id)['index']
|
91 |
+
c.execute("SELECT url FROM links WHERE id = ?", (clicked_id,))
|
92 |
+
result = c.fetchone()
|
93 |
+
if result:
|
94 |
+
return result[0]
|
95 |
+
return dash.no_update
|
96 |
+
|
97 |
+
@callback(
|
98 |
+
Output('url-list', 'children', allow_duplicate=True),
|
99 |
+
Input({'type': 'delete-button', 'index': dash.ALL}, 'n_clicks'),
|
100 |
+
prevent_initial_call=True
|
101 |
+
)
|
102 |
+
def delete_url(n_clicks):
|
103 |
+
ctx = dash.callback_context
|
104 |
+
if not ctx.triggered:
|
105 |
+
return dash.no_update
|
106 |
+
button_id = ctx.triggered[0]['prop_id'].split('.')[0]
|
107 |
+
delete_id = eval(button_id)['index']
|
108 |
+
c.execute("DELETE FROM links WHERE id = ?", (delete_id,))
|
109 |
+
conn.commit()
|
110 |
+
return update_url_list(None, None, None)
|
111 |
+
|
112 |
+
if __name__ == '__main__':
|
113 |
+
print("Starting the Dash application...")
|
114 |
+
app.run(debug=True, host='0.0.0.0', port=7860)
|
115 |
+
print("Dash application has finished running.")
|