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

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +30 -85
app.py CHANGED
@@ -10,48 +10,6 @@ import json
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,7 +70,8 @@ def load_css():
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,21 +117,21 @@ def generate_citation_hash(author, year, url, fragment_text, cited_text, usernam
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,47 +139,33 @@ def copy_to_clipboard_js(html_text, button_id):
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,8 +308,8 @@ with tabs[0]:
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,7 +424,7 @@ with tabs[1]:
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,7 +481,7 @@ with tabs[1]:
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
 
 
10
  # --- Constants ---
11
  MELBOURNE_TIMEZONE = 'Australia/Melbourne'
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  # --- Custom CSS for simplified UI ---
14
  def load_css():
15
  st.markdown("""
 
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
  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 text to clipboard using a textarea."""
130
+ # Encode the text as a JavaScript-safe string
131
+ escaped_text = json.dumps(text, ensure_ascii=False)[1:-1].replace('</', '<\\/')
132
  return f"""
133
  <div>
134
+ <textarea id="copy_text_{button_id}" style="display: none;">{escaped_text}</textarea>
135
  <button onclick="copyToClipboard_{button_id}()" class="copy-button">Copy to Clipboard</button>
136
  <span id="copy_status_{button_id}" style="margin-left: 10px; font-weight: bold;"></span>
137
  </div>
 
139
  function copyToClipboard_{button_id}() {{
140
  console.log('Copy function triggered for {button_id}');
141
  const textElement = document.getElementById('copy_text_{button_id}');
142
+ const textToCopy = textElement ? textElement.value : '';
143
+ if (!textToCopy) {{
144
  console.error('No text to copy for {button_id}');
145
  const statusElement = document.getElementById('copy_status_{button_id}');
146
  if (statusElement) statusElement.innerHTML = 'No text to copy';
147
  return;
148
  }}
149
+ if (navigator.clipboard) {{
150
+ navigator.clipboard.writeText(textToCopy).then(function() {{
151
+ console.log('Text copied successfully for {button_id}: ' + textToCopy);
152
+ const statusElement = document.getElementById('copy_status_{button_id}');
153
+ if (statusElement) {{
154
+ statusElement.innerHTML = 'Copied!';
155
+ setTimeout(function() {{
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156
  statusElement.innerHTML = '';
157
  }}, 2000);
158
  }}
159
+ }}, function(err) {{
160
+ console.error('Copy failed for {button_id}: ', err);
161
+ const statusElement = document.getElementById('copy_status_{button_id}');
162
+ if (statusElement) statusElement.innerHTML = 'Copy failed';
163
+ }});
164
+ }} else {{
165
+ console.error('Clipboard API not supported');
166
  const statusElement = document.getElementById('copy_status_{button_id}');
167
+ if (statusElement) statusElement.innerHTML = 'Clipboard API not supported';
168
  }}
 
 
 
 
169
  }}
170
  </script>
171
  """
 
308
  """, unsafe_allow_html=True)
309
  else:
310
  scc_hash = generate_citation_hash(author_name, publication_year, source_url, annotated_text, annotated_text, username, task_name, current_date, current_time)
311
+ citation_link_start = f'<a href="{source_url}#:~:text={urllib.parse.quote(annotated_text)}" data-hash="{scc_hash}">{author_name} ({publication_year})</a>'
312
+ citation_link_end = f'<a href="{source_url}#:~:text={urllib.parse.quote(annotated_text)}" data-hash="{scc_hash}">({author_name}, {publication_year})</a>'
313
 
314
  st.markdown("## Generated Citations")
315
  col_html1, col_html2 = st.columns(2)
 
424
  "Year": verify_publication_year,
425
  "URL": verify_source_url,
426
  "Fragment text": verify_annotated_text,
427
+ "Outlined text": verify_annotated_text,
428
  "Username": verify_username,
429
  "Task name": verify_task_name,
430
  "Date": verify_date,
 
481
  # Clear history button
482
  if st.button("Clear Verification History", type="secondary"):
483
  st.session_state.verified_hashes = []
484
+ st.experimental_rerun()
485
 
486
  st.markdown('</div>', unsafe_allow_html=True)
487