Upload app.py with huggingface_hub
Browse files
app.py
CHANGED
|
@@ -796,6 +796,33 @@ def analyze():
|
|
| 796 |
batch = pt.pop('_batch', '')
|
| 797 |
nc_raw = pt.pop('_nc_raw', 0)
|
| 798 |
pc_raw = pt.pop('_pc_raw', 0)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 799 |
all_patients[pc].append(pt)
|
| 800 |
if date_val:
|
| 801 |
meta[pc]['date'] = date_val
|
|
@@ -936,8 +963,9 @@ def save():
|
|
| 936 |
sero_mfi = r.get('sero_mfi', [])
|
| 937 |
|
| 938 |
submitted_by = flask_session.get('display_name', flask_session.get('username', ''))
|
|
|
|
| 939 |
rid = db.save_report(patient_id, report_date, pra_class, pra_percent,
|
| 940 |
-
overall, specificity, comment, sero_mfi, status, submitted_by)
|
| 941 |
saved.append({'report_id': rid, 'pra_class': pra_class})
|
| 942 |
|
| 943 |
return jsonify({'ok': True, 'patient_id': patient_id, 'saved': saved})
|
|
@@ -1060,7 +1088,8 @@ def admin():
|
|
| 1060 |
return redirect(url_for('dashboard'))
|
| 1061 |
import db
|
| 1062 |
users = db.get_all_users()
|
| 1063 |
-
|
|
|
|
| 1064 |
username=flask_session.get('username', ''))
|
| 1065 |
|
| 1066 |
|
|
@@ -1137,6 +1166,62 @@ def analysis():
|
|
| 1137 |
donor_hla=donor_hla)
|
| 1138 |
|
| 1139 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1140 |
if __name__ == '__main__':
|
| 1141 |
print('PRA Analysis Web App')
|
| 1142 |
print('http://127.0.0.1:5000')
|
|
|
|
| 796 |
batch = pt.pop('_batch', '')
|
| 797 |
nc_raw = pt.pop('_nc_raw', 0)
|
| 798 |
pc_raw = pt.pop('_pc_raw', 0)
|
| 799 |
+
|
| 800 |
+
# 保存原始檔案
|
| 801 |
+
import db as _dbmod
|
| 802 |
+
import xlrd as _xlrd
|
| 803 |
+
upload_dir = _dbmod.get_upload_dir()
|
| 804 |
+
patient_name = request.form.get('patient_name', '').strip()
|
| 805 |
+
chart_no = request.form.get('patient_id', '').strip()
|
| 806 |
+
class_tag = 'PRA1' if pc == 'PRA1' else 'PRA2'
|
| 807 |
+
# 從 XLS row 0 抓 EL 編號 (如 EL20022_27996823)
|
| 808 |
+
el_part = ''
|
| 809 |
+
try:
|
| 810 |
+
_wb = _xlrd.open_workbook(file_contents=raw_bytes)
|
| 811 |
+
_sh = _wb.sheet_by_index(0)
|
| 812 |
+
_r0 = str(_sh.cell_value(0, 0)).strip()
|
| 813 |
+
if not _r0:
|
| 814 |
+
_r0 = str(_sh.cell_value(0, 1)).strip()
|
| 815 |
+
if 'EL' in _r0.upper():
|
| 816 |
+
el_part = _r0.split('_')[0] # EL20022
|
| 817 |
+
except Exception:
|
| 818 |
+
pass
|
| 819 |
+
# 檔名: 姓名_EL20022_27996823_PRA1.xls
|
| 820 |
+
safe_name = f'{patient_name}_{el_part}_{chart_no}_{class_tag}{ext}'
|
| 821 |
+
safe_name = safe_name.replace('/', '_').replace('\\', '_')
|
| 822 |
+
save_path = upload_dir / safe_name
|
| 823 |
+
save_path.write_bytes(raw_bytes)
|
| 824 |
+
pt['_upload_file'] = safe_name
|
| 825 |
+
|
| 826 |
all_patients[pc].append(pt)
|
| 827 |
if date_val:
|
| 828 |
meta[pc]['date'] = date_val
|
|
|
|
| 963 |
sero_mfi = r.get('sero_mfi', [])
|
| 964 |
|
| 965 |
submitted_by = flask_session.get('display_name', flask_session.get('username', ''))
|
| 966 |
+
upload_file = r.get('upload_file', '')
|
| 967 |
rid = db.save_report(patient_id, report_date, pra_class, pra_percent,
|
| 968 |
+
overall, specificity, comment, sero_mfi, status, submitted_by, upload_file)
|
| 969 |
saved.append({'report_id': rid, 'pra_class': pra_class})
|
| 970 |
|
| 971 |
return jsonify({'ok': True, 'patient_id': patient_id, 'saved': saved})
|
|
|
|
| 1088 |
return redirect(url_for('dashboard'))
|
| 1089 |
import db
|
| 1090 |
users = db.get_all_users()
|
| 1091 |
+
storage = db.get_storage_stats()
|
| 1092 |
+
return render_template('admin.html', users=users, storage=storage,
|
| 1093 |
username=flask_session.get('username', ''))
|
| 1094 |
|
| 1095 |
|
|
|
|
| 1166 |
donor_hla=donor_hla)
|
| 1167 |
|
| 1168 |
|
| 1169 |
+
@app.route('/download_upload/<path:filename>')
|
| 1170 |
+
@login_required
|
| 1171 |
+
def download_upload(filename):
|
| 1172 |
+
"""下載上傳的原始檔案"""
|
| 1173 |
+
import db
|
| 1174 |
+
upload_dir = db.get_upload_dir()
|
| 1175 |
+
fpath = upload_dir / filename
|
| 1176 |
+
if not fpath.exists():
|
| 1177 |
+
return 'File not found', 404
|
| 1178 |
+
return send_file(str(fpath), as_attachment=True, download_name=filename)
|
| 1179 |
+
|
| 1180 |
+
|
| 1181 |
+
@app.route('/admin/download_all_uploads')
|
| 1182 |
+
@login_required
|
| 1183 |
+
def download_all_uploads():
|
| 1184 |
+
"""一鍵下載所有上傳檔案 (ZIP)"""
|
| 1185 |
+
if flask_session.get('role') != 'admin':
|
| 1186 |
+
return 'Forbidden', 403
|
| 1187 |
+
import db, zipfile
|
| 1188 |
+
upload_dir = db.get_upload_dir()
|
| 1189 |
+
files = list(upload_dir.glob('*.xls')) + list(upload_dir.glob('*.xlsx')) + list(upload_dir.glob('*.csv'))
|
| 1190 |
+
if not files:
|
| 1191 |
+
return 'No files', 404
|
| 1192 |
+
|
| 1193 |
+
buf = io.BytesIO()
|
| 1194 |
+
with zipfile.ZipFile(buf, 'w', zipfile.ZIP_DEFLATED) as zf:
|
| 1195 |
+
for f in files:
|
| 1196 |
+
zf.write(str(f), f.name)
|
| 1197 |
+
buf.seek(0)
|
| 1198 |
+
from datetime import datetime
|
| 1199 |
+
fname = f'uploads_{datetime.now().strftime("%Y%m%d_%H%M%S")}.zip'
|
| 1200 |
+
return send_file(buf, as_attachment=True, download_name=fname,
|
| 1201 |
+
mimetype='application/zip')
|
| 1202 |
+
|
| 1203 |
+
|
| 1204 |
+
@app.route('/admin/cleanup_uploads', methods=['POST'])
|
| 1205 |
+
@login_required
|
| 1206 |
+
def cleanup_uploads():
|
| 1207 |
+
"""清理 N 個月前的上傳檔案"""
|
| 1208 |
+
if flask_session.get('role') != 'admin':
|
| 1209 |
+
return jsonify({'error': '無權限'}), 403
|
| 1210 |
+
import db
|
| 1211 |
+
from datetime import datetime, timedelta
|
| 1212 |
+
months = request.json.get('months', 6)
|
| 1213 |
+
cutoff = datetime.now() - timedelta(days=months * 30)
|
| 1214 |
+
upload_dir = db.get_upload_dir()
|
| 1215 |
+
files = list(upload_dir.glob('*.xls')) + list(upload_dir.glob('*.xlsx')) + list(upload_dir.glob('*.csv'))
|
| 1216 |
+
deleted = 0
|
| 1217 |
+
for f in files:
|
| 1218 |
+
mtime = datetime.fromtimestamp(f.stat().st_mtime)
|
| 1219 |
+
if mtime < cutoff:
|
| 1220 |
+
f.unlink()
|
| 1221 |
+
deleted += 1
|
| 1222 |
+
return jsonify({'ok': True, 'deleted': deleted})
|
| 1223 |
+
|
| 1224 |
+
|
| 1225 |
if __name__ == '__main__':
|
| 1226 |
print('PRA Analysis Web App')
|
| 1227 |
print('http://127.0.0.1:5000')
|