mnoorchenar commited on
Commit
f2bdec3
Β·
1 Parent(s): 3e10738

Update 2026-01-29 00:53:13

Browse files
Files changed (2) hide show
  1. app.py +46 -0
  2. templates/index.html +31 -7
app.py CHANGED
@@ -88,6 +88,26 @@ def parse_bibtex_input(bibtex_content):
88
 
89
  return pd.DataFrame(papers).drop_duplicates(subset="Key", keep="first").reset_index(drop=True)
90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
  def protect_acronyms_in_fields(bibtex):
92
  """Protect acronyms with braces"""
93
  def clean_field(field_name, text):
@@ -204,6 +224,15 @@ def add_journal_abbreviations(df):
204
  row_data.get('Crossref_BibTeX_Abbrev', row['BibTeX'])
205
  )
206
 
 
 
 
 
 
 
 
 
 
207
  abbreviated_rows.append(row_data)
208
 
209
  return pd.DataFrame(abbreviated_rows)
@@ -413,6 +442,23 @@ def export_database():
413
  except Exception as e:
414
  return jsonify({'error': str(e)}), 500
415
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
416
  @app.route('/api/database/export-bibtex', methods=['GET'])
417
  def export_bibtex():
418
  """Export database as BibTeX"""
 
88
 
89
  return pd.DataFrame(papers).drop_duplicates(subset="Key", keep="first").reset_index(drop=True)
90
 
91
+ def clean_bibtex_fields(bibtex):
92
+ """Remove unwanted fields from BibTeX entries"""
93
+ # Fields to remove
94
+ fields_to_remove = ['url', 'source', 'publication_stage', 'note']
95
+
96
+ for field in fields_to_remove:
97
+ # Remove field with its value (handles multi-line values)
98
+ bibtex = re.sub(
99
+ rf'\s*{field}\s*=\s*\{{[^}}]*\}},?\s*',
100
+ '\n ',
101
+ bibtex,
102
+ flags=re.IGNORECASE
103
+ )
104
+
105
+ # Clean up extra commas and whitespace
106
+ bibtex = re.sub(r',\s*,', ',', bibtex)
107
+ bibtex = re.sub(r',(\s*)\}', r'\1}', bibtex)
108
+
109
+ return bibtex
110
+
111
  def protect_acronyms_in_fields(bibtex):
112
  """Protect acronyms with braces"""
113
  def clean_field(field_name, text):
 
224
  row_data.get('Crossref_BibTeX_Abbrev', row['BibTeX'])
225
  )
226
 
227
+ # Clean unwanted fields from all BibTeX versions
228
+ row_data['BibTeX'] = clean_bibtex_fields(row_data['BibTeX'])
229
+ if row_data.get('Crossref_BibTeX'):
230
+ row_data['Crossref_BibTeX'] = clean_bibtex_fields(row_data['Crossref_BibTeX'])
231
+ if row_data.get('Crossref_BibTeX_Abbrev'):
232
+ row_data['Crossref_BibTeX_Abbrev'] = clean_bibtex_fields(row_data['Crossref_BibTeX_Abbrev'])
233
+ if row_data.get('Crossref_BibTeX_Protected'):
234
+ row_data['Crossref_BibTeX_Protected'] = clean_bibtex_fields(row_data['Crossref_BibTeX_Protected'])
235
+
236
  abbreviated_rows.append(row_data)
237
 
238
  return pd.DataFrame(abbreviated_rows)
 
442
  except Exception as e:
443
  return jsonify({'error': str(e)}), 500
444
 
445
+ @app.route('/api/database/download', methods=['GET'])
446
+ def download_database():
447
+ """Download the SQLite database file"""
448
+ try:
449
+ db_path = app.config['DATABASE']
450
+ if not os.path.exists(db_path):
451
+ return jsonify({'error': 'Database file not found'}), 404
452
+
453
+ return send_file(
454
+ db_path,
455
+ mimetype='application/x-sqlite3',
456
+ as_attachment=True,
457
+ download_name='refs_management.db'
458
+ )
459
+ except Exception as e:
460
+ return jsonify({'error': str(e)}), 500
461
+
462
  @app.route('/api/database/export-bibtex', methods=['GET'])
463
  def export_bibtex():
464
  """Export database as BibTeX"""
templates/index.html CHANGED
@@ -514,6 +514,7 @@
514
  <button class="export-btn" onclick="loadDatabaseEntries()">πŸ”„ Refresh</button>
515
  <button class="export-btn" onclick="exportCSV()">πŸ“₯ Export CSV</button>
516
  <button class="export-btn" onclick="exportBibTeX()">πŸ“₯ Export BibTeX</button>
 
517
  </div>
518
 
519
  <div id="databaseEntries"></div>
@@ -660,7 +661,10 @@
660
  const bibtexPreview = document.getElementById('bibtexPreview');
661
  const jsonPreview = document.getElementById('jsonPreview');
662
 
663
- resultsInfo.innerHTML = `<strong>βœ… Processed ${data.count} references</strong>`;
 
 
 
664
 
665
  // Table view
666
  let tableHtml = '<table class="results-table"><thead><tr>';
@@ -670,7 +674,8 @@
670
  });
671
  tableHtml += '</tr></thead><tbody>';
672
 
673
- data.data.forEach(row => {
 
674
  tableHtml += '<tr>';
675
  tableHtml += `<td><span class="badge badge-info">${row.Key}</span></td>`;
676
  tableHtml += `<td>${row.Type}</td>`;
@@ -680,21 +685,36 @@
680
  tableHtml += '</tr>';
681
  });
682
 
 
 
 
 
683
  tableHtml += '</tbody></table>';
684
  resultsTable.innerHTML = tableHtml;
685
 
686
- // BibTeX view
687
  let bibtexText = '';
688
- data.full_data.forEach(row => {
 
689
  const bibField = document.getElementById('protectCheckbox').checked ?
690
  'Crossref_BibTeX_Protected' :
691
  'Crossref_BibTeX_Abbrev';
692
  bibtexText += (row[bibField] || row.BibTeX) + '\n\n';
693
  });
 
 
 
 
 
694
  bibtexPreview.textContent = bibtexText;
695
 
696
- // JSON view
697
- jsonPreview.textContent = JSON.stringify(data.full_data, null, 2);
 
 
 
 
 
698
  }
699
 
700
  async function loadDatabaseEntries() {
@@ -770,6 +790,10 @@
770
  window.location.href = '/api/database/export-bibtex';
771
  }
772
 
 
 
 
 
773
  function clearInput() {
774
  document.getElementById('bibtexInput').value = '';
775
  }
@@ -784,4 +808,4 @@
784
  loadStats();
785
  </script>
786
  </body>
787
- </html>
 
514
  <button class="export-btn" onclick="loadDatabaseEntries()">πŸ”„ Refresh</button>
515
  <button class="export-btn" onclick="exportCSV()">πŸ“₯ Export CSV</button>
516
  <button class="export-btn" onclick="exportBibTeX()">πŸ“₯ Export BibTeX</button>
517
+ <button class="export-btn" onclick="downloadDatabase()">πŸ’Ύ Download Database</button>
518
  </div>
519
 
520
  <div id="databaseEntries"></div>
 
661
  const bibtexPreview = document.getElementById('bibtexPreview');
662
  const jsonPreview = document.getElementById('jsonPreview');
663
 
664
+ const previewLimit = 10;
665
+ const hasMore = data.count > previewLimit;
666
+
667
+ resultsInfo.innerHTML = `<strong>βœ… Processed ${data.count} references</strong>${hasMore ? ` <span style="color: #666;">(Showing first ${previewLimit} in preview)</span>` : ''}`;
668
 
669
  // Table view
670
  let tableHtml = '<table class="results-table"><thead><tr>';
 
674
  });
675
  tableHtml += '</tr></thead><tbody>';
676
 
677
+ const displayData = data.data.slice(0, previewLimit);
678
+ displayData.forEach(row => {
679
  tableHtml += '<tr>';
680
  tableHtml += `<td><span class="badge badge-info">${row.Key}</span></td>`;
681
  tableHtml += `<td>${row.Type}</td>`;
 
685
  tableHtml += '</tr>';
686
  });
687
 
688
+ if (hasMore) {
689
+ tableHtml += `<tr><td colspan="5" style="text-align: center; padding: 20px; color: #666; font-style: italic;">... and ${data.count - previewLimit} more references (check Database tab or export to see all)</td></tr>`;
690
+ }
691
+
692
  tableHtml += '</tbody></table>';
693
  resultsTable.innerHTML = tableHtml;
694
 
695
+ // BibTeX view - limit to first few entries
696
  let bibtexText = '';
697
+ const displayFullData = data.full_data.slice(0, previewLimit);
698
+ displayFullData.forEach(row => {
699
  const bibField = document.getElementById('protectCheckbox').checked ?
700
  'Crossref_BibTeX_Protected' :
701
  'Crossref_BibTeX_Abbrev';
702
  bibtexText += (row[bibField] || row.BibTeX) + '\n\n';
703
  });
704
+
705
+ if (hasMore) {
706
+ bibtexText += `\n... and ${data.count - previewLimit} more references\n(Export BibTeX from Database tab to get all entries)`;
707
+ }
708
+
709
  bibtexPreview.textContent = bibtexText;
710
 
711
+ // JSON view - limit preview
712
+ const jsonData = hasMore ? data.full_data.slice(0, previewLimit) : data.full_data;
713
+ let jsonText = JSON.stringify(jsonData, null, 2);
714
+ if (hasMore) {
715
+ jsonText += `\n\n// ... and ${data.count - previewLimit} more references`;
716
+ }
717
+ jsonPreview.textContent = jsonText;
718
  }
719
 
720
  async function loadDatabaseEntries() {
 
790
  window.location.href = '/api/database/export-bibtex';
791
  }
792
 
793
+ async function downloadDatabase() {
794
+ window.location.href = '/api/database/download';
795
+ }
796
+
797
  function clearInput() {
798
  document.getElementById('bibtexInput').value = '';
799
  }
 
808
  loadStats();
809
  </script>
810
  </body>
811
+ </html>