mabuseif commited on
Commit
6f1e227
·
verified ·
1 Parent(s): e4f4c54

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +83 -25
app.py CHANGED
@@ -10,6 +10,48 @@ import json
10
  # --- Constants ---
11
  MELBOURNE_TIMEZONE = 'Australia/Melbourne'
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  # --- Custom CSS for simplified UI ---
14
  def load_css():
15
  st.markdown("""
@@ -70,8 +112,7 @@ def load_css():
70
 
71
  .footer {
72
  text-align: center;
73
- padding: 2rem;
74
- margin-top: 2rem;
75
  border-top: 1px solid #e0e0e0;
76
  font-size: 0.9rem;
77
  }
@@ -117,23 +158,21 @@ def generate_citation_hash(author, year, url, fragment_text, cited_text, usernam
117
  data = f"{author}, {year} | {url} | {fragment_text} | {cited_text} | {username} | {task_name} | {current_date} | {current_time}"
118
  return hashlib.sha256(data.encode('utf-8')).hexdigest()
119
 
120
- def format_citation_html(url, fragment_text, author, year, scc_hash):
121
  encoded_fragment = urllib.parse.quote(fragment_text)
122
  full_url = f"{url}#:~:text={encoded_fragment}"
123
- return f'<a href="{full_url}" data-hash="{scc_hash}">{author} ({year})</a>'
124
 
125
  def check_for_fragment(url):
126
  return '#:~:text=' in url
127
 
128
- def copy_to_clipboard_js(text, button_id):
129
  """Generate JavaScript for copying HTML content to clipboard."""
130
- # Create a clean text version for copying (remove HTML tags and keep only visible text)
131
- clean_text = f"{text.split('>')[1].split('<')[0]}"
132
- # Encode the clean text as a JavaScript-safe string
133
- escaped_text = json.dumps(clean_text, ensure_ascii=False)[1:-1].replace('</', '<\\/')
134
  return f"""
135
  <div>
136
- <textarea id="copy_text_{button_id}" style="display: none;">{escaped_text}</textarea>
137
  <button onclick="copyToClipboard_{button_id}()" class="copy-button">Copy to Clipboard</button>
138
  <span id="copy_status_{button_id}" style="margin-left: 10px; font-weight: bold;"></span>
139
  </div>
@@ -141,28 +180,47 @@ def copy_to_clipboard_js(text, button_id):
141
  function copyToClipboard_{button_id}() {{
142
  console.log('Copy function triggered for {button_id}');
143
  const textElement = document.getElementById('copy_text_{button_id}');
144
- const textToCopy = textElement ? textElement.value : '';
145
- if (!textToCopy) {{
146
  console.error('No text to copy for {button_id}');
147
  const statusElement = document.getElementById('copy_status_{button_id}');
148
  if (statusElement) statusElement.innerHTML = 'No text to copy';
149
  return;
150
  }}
151
- // Use navigator.clipboard API for plain text copying
152
- navigator.clipboard.writeText(textToCopy).then(() => {{
153
- console.log('Text copied successfully for {button_id}');
 
 
 
 
 
 
 
 
 
 
 
 
 
154
  const statusElement = document.getElementById('copy_status_{button_id}');
155
  if (statusElement) {{
156
- statusElement.innerHTML = 'Copied!';
157
- setTimeout(() => {{
158
- statusElement.innerHTML = '';
159
- }}, 2000);
 
 
160
  }}
161
- }}).catch(err => {{
162
  console.error('Copy failed for {button_id}: ', err);
163
  const statusElement = document.getElementById('copy_status_{button_id}');
164
  if (statusElement) statusElement.innerHTML = 'Copy failed';
165
- }});
 
 
 
 
166
  }}
167
  </script>
168
  """
@@ -305,8 +363,8 @@ with tabs[0]:
305
  """, unsafe_allow_html=True)
306
  else:
307
  scc_hash = generate_citation_hash(author_name, publication_year, source_url, annotated_text, annotated_text, username, task_name, current_date, current_time)
308
- citation_link_start = format_citation_html(source_url, annotated_text, author_name, publication_year, scc_hash)
309
- citation_link_end = format_citation_html(source_url, annotated_text, f"({author_name}, {publication_year})", publication_year, scc_hash)
310
 
311
  st.markdown("## Generated Citations")
312
  col_html1, col_html2 = st.columns(2)
@@ -421,7 +479,7 @@ with tabs[1]:
421
  "Year": verify_publication_year,
422
  "URL": verify_source_url,
423
  "Fragment text": verify_annotated_text,
424
- "Outlined text": verify_annotated_text,
425
  "Username": verify_username,
426
  "Task name": verify_task_name,
427
  "Date": verify_date,
@@ -478,7 +536,7 @@ with tabs[1]:
478
  # Clear history button
479
  if st.button("Clear Verification History", type="secondary"):
480
  st.session_state.verified_hashes = []
481
- st.experimental_rerun()
482
 
483
  st.markdown('</div>', unsafe_allow_html=True)
484
 
 
10
  # --- Constants ---
11
  MELBOURNE_TIMEZONE = 'Australia/Melbourne'
12
 
13
+ # --- Custom CSS for simplified UI ---
14
+ def load_css():
15
+ st.markdown("""
16
+ <style>
17
+ .main-header {
18
+ padding: 2rem;
19
+ text-align: center;
20
+ margin-bottom: 2rem;
21
+ }
22
+
23
+ .citation-output {
24
+ background: #f8f8f8;
25
+ border: 1px solid #e0e0e0;
26
+ border-radius: 4px;
27
+ padding: 1rem;
28
+ margin: 1rem 0;
29
+ font-family: 'Courier New', monospace;
30
+ }
31
+
32
+ .copy-button {
33
+ background: #e0e0e0;
34
+ color: black;
35
+ border: none;
36
+ padding: 0.5rem 1rem;
37
+ border-radius: 4px;
38
+ cursor: pointer;
39
+ font-size: 0.9rem;
40
+ Gentiles
41
+
42
+ System: <xaiArtifact artifact_id="9742b08f-bd1c-4ab1-9763-3ba142fe8ff2" artifact_version_id="905b7ac0-d0b9-4b2e-b9ad-4814e3320ff5" title="app.py" contentType="text/python">
43
+ import streamlit as st
44
+ import streamlit.components.v1 as components
45
+ import hashlib
46
+ import urllib.parse
47
+ from datetime import datetime
48
+ import pytz
49
+ import pandas as pd
50
+ import json
51
+
52
+ # --- Constants ---
53
+ MELBOURNE_TIMEZONE = 'Australia/Melbourne'
54
+
55
  # --- Custom CSS for simplified UI ---
56
  def load_css():
57
  st.markdown("""
 
112
 
113
  .footer {
114
  text-align: center;
115
+ padding: 2rem margin-top: 2rem;
 
116
  border-top: 1px solid #e0e0e0;
117
  font-size: 0.9rem;
118
  }
 
158
  data = f"{author}, {year} | {url} | {fragment_text} | {cited_text} | {username} | {task_name} | {current_date} | {current_time}"
159
  return hashlib.sha256(data.encode('utf-8')).hexdigest()
160
 
161
+ def format_citation_html(url, fragment_text, display_text, scc_hash):
162
  encoded_fragment = urllib.parse.quote(fragment_text)
163
  full_url = f"{url}#:~:text={encoded_fragment}"
164
+ return f'<a href="{full_url}" data-hash="{scc_hash}" target="_blank">{display_text}</a>'
165
 
166
  def check_for_fragment(url):
167
  return '#:~:text=' in url
168
 
169
+ def copy_to_clipboard_js(html_text, button_id):
170
  """Generate JavaScript for copying HTML content to clipboard."""
171
+ # Encode the full HTML content as a JavaScript-safe string
172
+ escaped_html = json.dumps(html_text, ensure_ascii=False)[1:-1].replace('</', '<\\/')
 
 
173
  return f"""
174
  <div>
175
+ <textarea id="copy_text_{button_id}" style="display: none;">{escaped_html}</textarea>
176
  <button onclick="copyToClipboard_{button_id}()" class="copy-button">Copy to Clipboard</button>
177
  <span id="copy_status_{button_id}" style="margin-left: 10px; font-weight: bold;"></span>
178
  </div>
 
180
  function copyToClipboard_{button_id}() {{
181
  console.log('Copy function triggered for {button_id}');
182
  const textElement = document.getElementById('copy_text_{button_id}');
183
+ const htmlToCopy = textElement ? textElement.value : '';
184
+ if (!htmlToCopy) {{
185
  console.error('No text to copy for {button_id}');
186
  const statusElement = document.getElementById('copy_status_{button_id}');
187
  if (statusElement) statusElement.innerHTML = 'No text to copy';
188
  return;
189
  }}
190
+ // Create a temporary div to hold the HTML content
191
+ const tempDiv = document.createElement('div');
192
+ tempDiv.innerHTML = htmlToCopy;
193
+ document.body.appendChild(tempDiv);
194
+
195
+ // Select the content
196
+ const range = document.createRange();
197
+ range.selectNodeContents(tempDiv);
198
+ const selection = window.getSelection();
199
+ selection.removeAllRanges();
200
+ selection.addRange(range);
201
+
202
+ // Copy to clipboard as HTML
203
+ try {{
204
+ const successful = document.execCommand('copy');
205
+ console.log('Copy command executed for {button_id}: ' + (successful ? 'success' : 'failed'));
206
  const statusElement = document.getElementById('copy_status_{button_id}');
207
  if (statusElement) {{
208
+ statusElement.innerHTML = successful ? 'Copied!' : 'Copy failed';
209
+ if (successful) {{
210
+ setTimeout(() => {{
211
+ statusElement.innerHTML = '';
212
+ }}, 2000);
213
+ }}
214
  }}
215
+ }} catch (err) {{
216
  console.error('Copy failed for {button_id}: ', err);
217
  const statusElement = document.getElementById('copy_status_{button_id}');
218
  if (statusElement) statusElement.innerHTML = 'Copy failed';
219
+ }}
220
+
221
+ // Clean up
222
+ selection.removeAllRanges();
223
+ document.body.removeChild(tempDiv);
224
  }}
225
  </script>
226
  """
 
363
  """, unsafe_allow_html=True)
364
  else:
365
  scc_hash = generate_citation_hash(author_name, publication_year, source_url, annotated_text, annotated_text, username, task_name, current_date, current_time)
366
+ citation_link_start = format_citation_html(source_url, annotated_text, f"{author_name} ({publication_year})", scc_hash)
367
+ citation_link_end = format_citation_html(source_url, annotated_text, f"({author_name}, {publication_year})", scc_hash)
368
 
369
  st.markdown("## Generated Citations")
370
  col_html1, col_html2 = st.columns(2)
 
479
  "Year": verify_publication_year,
480
  "URL": verify_source_url,
481
  "Fragment text": verify_annotated_text,
482
+ "Cited text": verify_annotated_text,
483
  "Username": verify_username,
484
  "Task name": verify_task_name,
485
  "Date": verify_date,
 
536
  # Clear history button
537
  if st.button("Clear Verification History", type="secondary"):
538
  st.session_state.verified_hashes = []
539
+ st.rerun()
540
 
541
  st.markdown('</div>', unsafe_allow_html=True)
542