Merge branch 'main' of https://git.krzak.org/N0VA/CLARA
This commit is contained in:
@@ -41,8 +41,47 @@ class FileShareHandler(BaseHTTPRequestHandler):
|
|||||||
raise RuntimeError(f"HTML template not found at {template_path}")
|
raise RuntimeError(f"HTML template not found at {template_path}")
|
||||||
return cls.html_template
|
return cls.html_template
|
||||||
|
|
||||||
|
def _generate_shared_text_html(self, text: str) -> str:
|
||||||
|
if not text:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
escaped_text = html.escape(text)
|
||||||
|
return f'''<h2>Shared Text</h2>
|
||||||
|
<p>Select the text below and copy it to your clipboard.</p>
|
||||||
|
<textarea class="share-text" readonly="readonly">{escaped_text}</textarea>'''
|
||||||
|
|
||||||
|
def _generate_shared_files_html(self, files: List[str]) -> str:
|
||||||
|
"""Generate HTML for shared files section."""
|
||||||
|
if not files:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
rows = ""
|
||||||
|
for i, filepath in enumerate(files):
|
||||||
|
try:
|
||||||
|
path = Path(filepath)
|
||||||
|
if path.exists() and path.is_file():
|
||||||
|
name = html.escape(path.name)
|
||||||
|
size = format_size(path.stat().st_size)
|
||||||
|
rows += f'''<tr>
|
||||||
|
<td>{name}</td>
|
||||||
|
<td>{size}</td>
|
||||||
|
<td><a class="button" href="/download/{i}">Download</a></td>
|
||||||
|
</tr>'''
|
||||||
|
except Exception:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if not rows:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
return f'''<h2>Shared Files</h2>
|
||||||
|
<p>Click a button to download the corresponding file.</p>
|
||||||
|
<table class="file-list" cellpadding="0" cellspacing="0">
|
||||||
|
<tr><th>Filename</th><th>Size</th><th>Action</th></tr>
|
||||||
|
{rows}
|
||||||
|
</table>'''
|
||||||
|
|
||||||
def _get_base_html(self, hostname: str, url: str, total_size_info: str,
|
def _get_base_html(self, hostname: str, url: str, total_size_info: str,
|
||||||
no_content_display: str, initial_data_json: str) -> str:
|
no_content_display: str, shared_text_html: str, shared_files_html: str) -> str:
|
||||||
template = self.load_html_template()
|
template = self.load_html_template()
|
||||||
|
|
||||||
replacements = {
|
replacements = {
|
||||||
@@ -51,7 +90,8 @@ class FileShareHandler(BaseHTTPRequestHandler):
|
|||||||
'{{URL}}': html.escape(url),
|
'{{URL}}': html.escape(url),
|
||||||
'{{TOTAL_SIZE_INFO}}': total_size_info,
|
'{{TOTAL_SIZE_INFO}}': total_size_info,
|
||||||
'{{NO_CONTENT_DISPLAY}}': no_content_display,
|
'{{NO_CONTENT_DISPLAY}}': no_content_display,
|
||||||
'{{INITIAL_DATA_JSON}}': initial_data_json
|
'{{SHARED_TEXT_HTML}}': shared_text_html,
|
||||||
|
'{{SHARED_FILES_HTML}}': shared_files_html
|
||||||
}
|
}
|
||||||
|
|
||||||
result = template
|
result = template
|
||||||
@@ -106,19 +146,20 @@ class FileShareHandler(BaseHTTPRequestHandler):
|
|||||||
if total_size_bytes > 0:
|
if total_size_bytes > 0:
|
||||||
total_size_info = format_size(total_size_bytes)
|
total_size_info = format_size(total_size_bytes)
|
||||||
|
|
||||||
initial_data_dict = self._get_api_data_dict()
|
|
||||||
json_string = json.dumps(initial_data_dict)
|
|
||||||
initial_data_json = json.dumps(json_string)
|
|
||||||
|
|
||||||
url = f"http://{self._get_local_ip()}:{self.server.server_address[1]}/" #type: ignore
|
url = f"http://{self._get_local_ip()}:{self.server.server_address[1]}/" #type: ignore
|
||||||
no_content_display = 'none' if has_content else 'block'
|
no_content_display = 'none' if has_content else 'block'
|
||||||
|
|
||||||
|
# Generate HTML server-side
|
||||||
|
shared_text_html = self._generate_shared_text_html(self.shared_text or "")
|
||||||
|
shared_files_html = self._generate_shared_files_html(self.shared_files)
|
||||||
|
|
||||||
html_content = self._get_base_html(
|
html_content = self._get_base_html(
|
||||||
hostname=hostname,
|
hostname=hostname,
|
||||||
url=url,
|
url=url,
|
||||||
total_size_info=total_size_info,
|
total_size_info=total_size_info,
|
||||||
no_content_display=no_content_display,
|
no_content_display=no_content_display,
|
||||||
initial_data_json=initial_data_json
|
shared_text_html=shared_text_html,
|
||||||
|
shared_files_html=shared_files_html
|
||||||
).encode('utf-8')
|
).encode('utf-8')
|
||||||
|
|
||||||
self.send_response(200)
|
self.send_response(200)
|
||||||
@@ -245,6 +286,8 @@ class FileShareServer:
|
|||||||
for f in files:
|
for f in files:
|
||||||
if f not in current_files:
|
if f not in current_files:
|
||||||
self.shared_files.append(f)
|
self.shared_files.append(f)
|
||||||
|
|
||||||
|
FileShareHandler.shared_files = self.shared_files
|
||||||
|
|
||||||
def share_text(self, text: str) -> str:
|
def share_text(self, text: str) -> str:
|
||||||
self.shared_text = text
|
self.shared_text = text
|
||||||
|
|||||||
@@ -147,8 +147,12 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="main clearfix">
|
<div class="main clearfix">
|
||||||
<div class="left-col">
|
<div class="left-col">
|
||||||
<div class="section" id="shared-text-container"></div>
|
<div class="section" id="shared-text-container">
|
||||||
<div class="section" id="shared-files-container"></div>
|
{{SHARED_TEXT_HTML}}
|
||||||
|
</div>
|
||||||
|
<div class="section" id="shared-files-container">
|
||||||
|
{{SHARED_FILES_HTML}}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="right-col">
|
<div class="right-col">
|
||||||
<div class="section">
|
<div class="section">
|
||||||
@@ -167,7 +171,6 @@
|
|||||||
<p>Powered by <a href="https://github.com/n0va-bot/CLARA" target="_blank">CLARA</a>, your friendly desktop assistant.</p>
|
<p>Powered by <a href="https://github.com/n0va-bot/CLARA" target="_blank">CLARA</a>, your friendly desktop assistant.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script type="text/javascript">var initialDataJSON = {{INITIAL_DATA_JSON}};</script>
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
(function() {
|
(function() {
|
||||||
var lastData = '';
|
var lastData = '';
|
||||||
@@ -232,14 +235,7 @@
|
|||||||
xhr.send(null);
|
xhr.send(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof initialDataJSON !== 'undefined' && initialDataJSON) {
|
// Refresh data every 5 seconds
|
||||||
lastData = initialDataJSON;
|
|
||||||
try {
|
|
||||||
var initialData = JSON.parse(initialDataJSON);
|
|
||||||
updateContent(initialData);
|
|
||||||
} catch (e) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
setInterval(fetchData, 5000);
|
setInterval(fetchData, 5000);
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user