scitex 2.13.0__py3-none-any.whl → 2.15.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- scitex/__init__.py +80 -2
- scitex/__version__.py +11 -8
- scitex/_env_loader.py +156 -0
- scitex/_mcp_resources/__init__.py +37 -0
- scitex/_mcp_resources/_cheatsheet.py +135 -0
- scitex/_mcp_resources/_figrecipe.py +138 -0
- scitex/_mcp_resources/_formats.py +102 -0
- scitex/_mcp_resources/_modules.py +337 -0
- scitex/_mcp_resources/_session.py +149 -0
- scitex/_mcp_tools/__init__.py +40 -0
- scitex/_mcp_tools/audio.py +200 -0
- scitex/_mcp_tools/canvas.py +128 -0
- scitex/_mcp_tools/capture.py +174 -0
- scitex/_mcp_tools/diagram.py +22 -0
- scitex/_mcp_tools/introspect.py +191 -0
- scitex/_mcp_tools/plt.py +305 -0
- scitex/_mcp_tools/scholar.py +447 -0
- scitex/_mcp_tools/social.py +244 -0
- scitex/_mcp_tools/stats.py +206 -0
- scitex/_mcp_tools/template.py +66 -0
- scitex/_mcp_tools/ui.py +80 -0
- scitex/_mcp_tools/writer.py +37 -0
- scitex/ai/_gen_ai/_PARAMS.py +10 -7
- scitex/ai/classification/reporters/_ClassificationReporter.py +0 -0
- scitex/ai/classification/reporters/_SingleClassificationReporter.py +45 -1603
- scitex/ai/classification/reporters/_mixins/__init__.py +36 -0
- scitex/ai/classification/reporters/_mixins/_constants.py +67 -0
- scitex/ai/classification/reporters/_mixins/_cv_summary.py +387 -0
- scitex/ai/classification/reporters/_mixins/_feature_importance.py +119 -0
- scitex/ai/classification/reporters/_mixins/_metrics.py +275 -0
- scitex/ai/classification/reporters/_mixins/_plotting.py +179 -0
- scitex/ai/classification/reporters/_mixins/_reports.py +153 -0
- scitex/ai/classification/reporters/_mixins/_storage.py +160 -0
- scitex/ai/classification/timeseries/_TimeSeriesBlockingSplit.py +0 -0
- scitex/ai/classification/timeseries/_TimeSeriesCalendarSplit.py +0 -0
- scitex/ai/classification/timeseries/_TimeSeriesSlidingWindowSplit.py +0 -0
- scitex/ai/classification/timeseries/_TimeSeriesSlidingWindowSplit_v01-not-using-n_splits.py +0 -0
- scitex/ai/classification/timeseries/_TimeSeriesStratifiedSplit.py +0 -0
- scitex/ai/classification/timeseries/_normalize_timestamp.py +0 -0
- scitex/ai/metrics/_calc_seizure_prediction_metrics.py +0 -0
- scitex/ai/plt/_plot_feature_importance.py +0 -0
- scitex/ai/plt/_plot_learning_curve.py +0 -0
- scitex/ai/plt/_plot_optuna_study.py +0 -0
- scitex/ai/plt/_plot_pre_rec_curve.py +0 -0
- scitex/ai/plt/_plot_roc_curve.py +0 -0
- scitex/ai/plt/_stx_conf_mat.py +0 -0
- scitex/ai/training/_LearningCurveLogger.py +0 -0
- scitex/audio/README.md +88 -7
- scitex/audio/__init__.py +127 -60
- scitex/audio/__main__.py +17 -21
- scitex/audio/_branding.py +185 -0
- scitex/audio/_mcp/__init__.py +36 -0
- scitex/audio/_mcp/handlers.py +419 -0
- scitex/audio/_mcp/speak_handlers.py +238 -0
- scitex/audio/_mcp/tool_schemas.py +203 -0
- scitex/audio/_relay.py +225 -0
- scitex/audio/engines/elevenlabs_engine.py +6 -1
- scitex/audio/mcp_server.py +355 -337
- scitex/bridge/_figrecipe.py +40 -8
- scitex/bridge/_stats_plt.py +2 -4
- scitex/bridge/_stats_vis.py +7 -5
- scitex/browser/automation/CookieHandler.py +0 -0
- scitex/browser/collaboration/__init__.py +0 -1
- scitex/browser/core/BrowserMixin.py +0 -0
- scitex/browser/core/ChromeProfileManager.py +10 -3
- scitex/browser/debugging/_browser_logger.py +6 -9
- scitex/browser/debugging/_highlight_element.py +0 -0
- scitex/browser/debugging/_show_grid.py +0 -0
- scitex/browser/interaction/click_center.py +0 -0
- scitex/browser/interaction/click_with_fallbacks.py +0 -0
- scitex/browser/interaction/close_popups.py +0 -0
- scitex/browser/interaction/fill_with_fallbacks.py +0 -0
- scitex/browser/pdf/click_download_for_chrome_pdf_viewer.py +0 -0
- scitex/browser/pdf/detect_chrome_pdf_viewer.py +0 -0
- scitex/browser/stealth/HumanBehavior.py +0 -0
- scitex/browser/stealth/StealthManager.py +0 -0
- scitex/canvas/README.md +1 -1
- scitex/canvas/_mcp/__init__.py +4 -0
- scitex/canvas/_mcp/handlers.py +372 -0
- scitex/canvas/_mcp/tool_schemas.py +219 -0
- scitex/canvas/editor/_dearpygui/__init__.py +25 -0
- scitex/canvas/editor/_dearpygui/_editor.py +147 -0
- scitex/canvas/editor/_dearpygui/_handlers.py +476 -0
- scitex/canvas/editor/_dearpygui/_panels/__init__.py +17 -0
- scitex/canvas/editor/_dearpygui/_panels/_control.py +119 -0
- scitex/canvas/editor/_dearpygui/_panels/_element_controls.py +190 -0
- scitex/canvas/editor/_dearpygui/_panels/_preview.py +43 -0
- scitex/canvas/editor/_dearpygui/_panels/_sections.py +390 -0
- scitex/canvas/editor/_dearpygui/_plotting.py +187 -0
- scitex/canvas/editor/_dearpygui/_rendering.py +504 -0
- scitex/canvas/editor/_dearpygui/_selection.py +295 -0
- scitex/canvas/editor/_dearpygui/_state.py +93 -0
- scitex/canvas/editor/_dearpygui/_utils.py +61 -0
- scitex/canvas/editor/flask_editor/templates/__init__.py +32 -70
- scitex/canvas/mcp_server.py +2 -2
- scitex/capture/__init__.py +0 -1
- scitex/capture/_mcp/__init__.py +11 -0
- scitex/capture/_mcp/handlers.py +438 -0
- scitex/capture/_mcp/tool_schemas.py +270 -0
- scitex/cli/__init__.py +44 -2
- scitex/cli/audio.py +150 -3
- scitex/cli/browser.py +310 -0
- scitex/cli/capture.py +14 -3
- scitex/cli/introspect.py +443 -0
- scitex/cli/main.py +230 -103
- scitex/cli/mcp.py +362 -0
- scitex/cli/repro.py +18 -0
- scitex/cli/resource.py +18 -0
- scitex/cli/scholar/__init__.py +97 -0
- scitex/cli/scholar/_crossref_scitex.py +296 -0
- scitex/cli/scholar/_fetch.py +369 -0
- scitex/cli/scholar/_jobs.py +306 -0
- scitex/cli/scholar/_library.py +152 -0
- scitex/cli/scholar/_utils.py +35 -0
- scitex/cli/social.py +314 -0
- scitex/cli/stats.py +18 -0
- scitex/cli/template.py +18 -0
- scitex/cli/tex.py +18 -0
- scitex/cli/writer.py +190 -20
- scitex/compat/__init__.py +74 -0
- scitex/config/README.md +1 -1
- scitex/config/__init__.py +16 -2
- scitex/config/_env_registry.py +191 -0
- scitex/config/default.yaml +31 -0
- scitex/cv/__init__.py +87 -0
- scitex/cv/_draw.py +236 -0
- scitex/cv/_filters.py +217 -0
- scitex/cv/_io.py +157 -0
- scitex/cv/_transform.py +184 -0
- scitex/dev/__init__.py +2 -0
- scitex/dev/cv/__init__.py +60 -0
- scitex/dev/cv/_compose.py +330 -0
- scitex/dev/cv/_title_card.py +351 -0
- scitex/dev/plt/__init__.py +0 -0
- scitex/dev/plt/demo_plotters/__init__.py +0 -0
- scitex/dev/plt/mpl/get_dir_ax.py +0 -0
- scitex/dev/plt/mpl/get_signatures.py +0 -0
- scitex/dev/plt/mpl/get_signatures_details.py +0 -0
- scitex/diagram/__init__.py +42 -19
- scitex/diagram/mcp_server.py +13 -125
- scitex/dt/_normalize_timestamp.py +0 -0
- scitex/gen/__init__.py +0 -0
- scitex/gen/misc.py +0 -0
- scitex/git/_init.py +2 -2
- scitex/git/_session.py +0 -0
- scitex/introspect/__init__.py +75 -0
- scitex/introspect/_call_graph.py +303 -0
- scitex/introspect/_class_hierarchy.py +163 -0
- scitex/introspect/_core.py +42 -0
- scitex/introspect/_docstring.py +131 -0
- scitex/introspect/_examples.py +113 -0
- scitex/introspect/_imports.py +271 -0
- scitex/introspect/_mcp/__init__.py +37 -0
- scitex/introspect/_mcp/handlers.py +208 -0
- scitex/introspect/_members.py +151 -0
- scitex/introspect/_resolve.py +89 -0
- scitex/introspect/_signature.py +131 -0
- scitex/introspect/_source.py +80 -0
- scitex/introspect/_type_hints.py +172 -0
- scitex/io/bundle/README.md +1 -1
- scitex/io/bundle/kinds/__init__.py +0 -0
- scitex/io/bundle/kinds/_figure/__init__.py +0 -0
- scitex/io/bundle/kinds/_plot/__init__.py +0 -0
- scitex/io/bundle/kinds/_shape/__init__.py +0 -0
- scitex/io/bundle/kinds/_text/__init__.py +0 -0
- scitex/logging/_context.py +5 -4
- scitex/mcp_server.py +170 -145
- scitex/plt/__init__.py +249 -548
- scitex/plt/_figrecipe_integration.py +121 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin/_wrappers.py +5 -10
- scitex/plt/_subplots/_FigWrapper.py +139 -88
- scitex/plt/_subplots/_export_as_csv_formatters/_format_pcolormesh.py +0 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stackplot.py +0 -0
- scitex/plt/docs/EXTERNAL_PACKAGE_BRANDING.md +149 -0
- scitex/plt/gallery/README.md +1 -1
- scitex/plt/styles/_plot_postprocess.py +35 -117
- scitex/plt/styles/_postprocess_helpers.py +158 -0
- scitex/plt/utils/_hitmap/__init__.py +82 -0
- scitex/plt/utils/_hitmap/_artist_extraction.py +343 -0
- scitex/plt/utils/_hitmap/_color_application.py +346 -0
- scitex/plt/utils/_hitmap/_color_conversion.py +121 -0
- scitex/plt/utils/_hitmap/_constants.py +40 -0
- scitex/plt/utils/_hitmap/_hitmap_core.py +334 -0
- scitex/plt/utils/_hitmap/_path_extraction.py +357 -0
- scitex/plt/utils/_hitmap/_query.py +113 -0
- scitex/plt/utils/_hitmap.py +46 -1616
- scitex/plt/utils/_metadata/__init__.py +80 -0
- scitex/plt/utils/_metadata/_artists/__init__.py +25 -0
- scitex/plt/utils/_metadata/_artists/_base.py +195 -0
- scitex/plt/utils/_metadata/_artists/_collections.py +356 -0
- scitex/plt/utils/_metadata/_artists/_extract.py +57 -0
- scitex/plt/utils/_metadata/_artists/_images.py +80 -0
- scitex/plt/utils/_metadata/_artists/_lines.py +261 -0
- scitex/plt/utils/_metadata/_artists/_patches.py +247 -0
- scitex/plt/utils/_metadata/_artists/_text.py +106 -0
- scitex/plt/utils/_metadata/_csv.py +416 -0
- scitex/plt/utils/_metadata/_detect.py +225 -0
- scitex/plt/utils/_metadata/_legend.py +127 -0
- scitex/plt/utils/_metadata/_rounding.py +117 -0
- scitex/plt/utils/_metadata/_verification.py +202 -0
- scitex/repro/_RandomStateManager.py +0 -0
- scitex/repro/_gen_ID.py +0 -0
- scitex/repro/_gen_timestamp.py +0 -0
- scitex/repro/_hash_array.py +0 -0
- scitex/schema/README.md +1 -1
- scitex/scholar/__init__.py +8 -0
- scitex/scholar/_mcp/__init__.py +4 -0
- scitex/scholar/_mcp/all_handlers.py +74 -0
- scitex/scholar/_mcp/crossref_handlers.py +265 -0
- scitex/scholar/_mcp/handlers.py +1478 -0
- scitex/scholar/_mcp/job_handlers.py +172 -0
- scitex/scholar/_mcp/job_tool_schemas.py +166 -0
- scitex/scholar/_mcp/tool_schemas.py +505 -0
- scitex/scholar/auth/core/BrowserAuthenticator.py +126 -9
- scitex/scholar/auth/providers/OpenAthensAuthenticator.py +55 -210
- scitex/scholar/auth/providers/_notifications.py +417 -0
- scitex/scholar/auth/sso/BaseSSOAutomator.py +36 -17
- scitex/scholar/auth/sso/UniversityOfMelbourneSSOAutomator.py +8 -15
- scitex/scholar/citation_graph/__init__.py +0 -1
- scitex/scholar/config/core/_PathManager.py +5 -1
- scitex/scholar/config/default.yaml +1 -1
- scitex/scholar/core/Paper.py +19 -41
- scitex/scholar/core/Scholar.py +64 -1688
- scitex/scholar/core/_mixins/__init__.py +36 -0
- scitex/scholar/core/_mixins/_enrichers.py +270 -0
- scitex/scholar/core/_mixins/_library_handlers.py +100 -0
- scitex/scholar/core/_mixins/_loaders.py +103 -0
- scitex/scholar/core/_mixins/_pdf_download.py +375 -0
- scitex/scholar/core/_mixins/_pipeline.py +312 -0
- scitex/scholar/core/_mixins/_project_handlers.py +125 -0
- scitex/scholar/core/_mixins/_savers.py +69 -0
- scitex/scholar/core/_mixins/_search.py +103 -0
- scitex/scholar/core/_mixins/_services.py +88 -0
- scitex/scholar/core/_mixins/_url_finding.py +105 -0
- scitex/scholar/core/journal_normalizer.py +36 -25
- scitex/scholar/crossref_scitex.py +367 -0
- scitex/scholar/docs/EXTERNAL_PACKAGE_BRANDING.md +149 -0
- scitex/scholar/examples/00_run_all.sh +120 -0
- scitex/scholar/examples/07_storage_integration.py +0 -0
- scitex/scholar/impact_factor/estimation/__init__.py +0 -1
- scitex/scholar/impact_factor/jcr/ImpactFactorJCREngine.py +19 -6
- scitex/scholar/impact_factor/jcr/build_database.py +0 -0
- scitex/scholar/jobs/_Job.py +266 -0
- scitex/scholar/jobs/_JobManager.py +458 -0
- scitex/scholar/jobs/__init__.py +74 -0
- scitex/scholar/jobs/_errors.py +346 -0
- scitex/scholar/jobs/_executors.py +397 -0
- scitex/scholar/mcp_server.py +52 -2
- scitex/scholar/pdf_download/ScholarPDFDownloader.py +38 -416
- scitex/scholar/pdf_download/_cli.py +154 -0
- scitex/scholar/pdf_download/strategies/__init__.py +11 -8
- scitex/scholar/pdf_download/strategies/chrome_pdf_viewer.py +11 -11
- scitex/scholar/pdf_download/strategies/manual_download_fallback.py +80 -3
- scitex/scholar/pipelines/ScholarPipelineBibTeX.py +73 -121
- scitex/scholar/pipelines/ScholarPipelineParallel.py +83 -140
- scitex/scholar/pipelines/ScholarPipelineSearchParallel.py +11 -13
- scitex/scholar/pipelines/ScholarPipelineSingle.py +83 -656
- scitex/scholar/pipelines/_single_steps.py +465 -0
- scitex/scholar/storage/BibTeXHandler.py +71 -23
- scitex/scholar/storage/PaperIO.py +53 -18
- scitex/scholar/storage/_BibTeXValidator.py +571 -0
- scitex/scholar/storage/_LibraryManager.py +97 -1695
- scitex/scholar/storage/__init__.py +17 -3
- scitex/scholar/storage/_mixins/__init__.py +30 -0
- scitex/scholar/storage/_mixins/_bibtex_handlers.py +128 -0
- scitex/scholar/storage/_mixins/_library_operations.py +218 -0
- scitex/scholar/storage/_mixins/_metadata_conversion.py +226 -0
- scitex/scholar/storage/_mixins/_paper_saving.py +456 -0
- scitex/scholar/storage/_mixins/_resolution.py +376 -0
- scitex/scholar/storage/_mixins/_storage_helpers.py +121 -0
- scitex/scholar/storage/_mixins/_symlink_handlers.py +226 -0
- scitex/scholar/url_finder/translators/individual/cell_press.py +131 -4
- scitex/security/README.md +3 -3
- scitex/security/__init__.py +0 -1
- scitex/session/README.md +1 -1
- scitex/session/__init__.py +0 -0
- scitex/session/_decorator.py +0 -0
- scitex/session/_lifecycle.py +0 -0
- scitex/sh/README.md +1 -1
- scitex/social/__init__.py +153 -0
- scitex/social/docs/EXTERNAL_PACKAGE_BRANDING.md +149 -0
- scitex/stats/__init__.py +14 -2
- scitex/stats/__main__.py +2 -2
- scitex/stats/_figrecipe_integration.py +116 -0
- scitex/stats/_mcp/__init__.py +4 -0
- scitex/stats/_mcp/handlers.py +1191 -0
- scitex/stats/_mcp/tool_schemas.py +384 -0
- scitex/stats/auto/__init__.py +0 -1
- scitex/stats/correct/_correct_bonferroni.py +0 -0
- scitex/stats/correct/_correct_fdr.py +0 -0
- scitex/stats/correct/_correct_fdr_.py +0 -0
- scitex/stats/correct/_correct_holm.py +0 -0
- scitex/stats/correct/_correct_sidak.py +0 -0
- scitex/stats/effect_sizes/_cliffs_delta.py +0 -0
- scitex/stats/effect_sizes/_cohens_d.py +0 -0
- scitex/stats/effect_sizes/_epsilon_squared.py +0 -0
- scitex/stats/effect_sizes/_eta_squared.py +0 -0
- scitex/stats/effect_sizes/_prob_superiority.py +0 -0
- scitex/stats/mcp_server.py +2 -2
- scitex/stats/posthoc/_dunnett.py +0 -0
- scitex/stats/posthoc/_games_howell.py +0 -0
- scitex/stats/posthoc/_tukey_hsd.py +0 -0
- scitex/stats/power/_power.py +0 -0
- scitex/stats/utils/_effect_size.py +0 -0
- scitex/stats/utils/_formatters.py +0 -0
- scitex/stats/utils/_power.py +0 -0
- scitex/template/README.md +1 -1
- scitex/template/_mcp/__init__.py +4 -0
- scitex/template/_mcp/handlers.py +259 -0
- scitex/template/_mcp/tool_schemas.py +112 -0
- scitex/template/clone_writer_directory.py +6 -6
- scitex/template/mcp_server.py +2 -2
- scitex/ui/__init__.py +173 -0
- scitex/ui/_backends/__init__.py +66 -0
- scitex/ui/_backends/_audio.py +86 -0
- scitex/ui/_backends/_config.py +250 -0
- scitex/ui/_backends/_desktop.py +184 -0
- scitex/ui/_backends/_emacs.py +210 -0
- scitex/ui/_backends/_email.py +78 -0
- scitex/ui/_backends/_matplotlib.py +118 -0
- scitex/ui/_backends/_playwright.py +109 -0
- scitex/ui/_backends/_types.py +58 -0
- scitex/ui/_backends/_webhook.py +77 -0
- scitex/ui/_backends.py +37 -0
- scitex/ui/_mcp/__init__.py +23 -0
- scitex/ui/_mcp/handlers.py +260 -0
- scitex/ui/_mcp/tool_schemas.py +107 -0
- scitex/ui/mcp_server.py +151 -0
- scitex/utils/_email.py +85 -7
- scitex/utils/_notify.py +16 -5
- scitex/utils/_search.py +11 -9
- scitex/utils/_verify_scitex_format.py +0 -0
- scitex/writer/README.md +1 -1
- scitex/writer/Writer.py +110 -111
- scitex/writer/__init__.py +26 -48
- scitex/writer/_clone_writer_project.py +0 -0
- scitex/writer/_compile/__init__.py +5 -4
- scitex/writer/_compile/_compile_async.py +130 -0
- scitex/writer/_compile/_compile_unified.py +148 -0
- scitex/writer/_compile/_runner.py +2 -2
- scitex/writer/_compile/_validator.py +3 -3
- scitex/writer/_compile/manuscript.py +1 -1
- scitex/writer/_compile/revision.py +1 -1
- scitex/writer/_compile/supplementary.py +1 -1
- scitex/writer/_dataclasses/config/_WriterConfig.py +175 -0
- scitex/writer/_dataclasses/contents/_ManuscriptContents.py +236 -0
- scitex/writer/_dataclasses/core/_Document.py +146 -0
- scitex/writer/_dataclasses/core/_DocumentSection.py +546 -0
- scitex/writer/_dataclasses/results/_CompilationResult.py +165 -0
- scitex/writer/_dataclasses/results/_LaTeXIssue.py +102 -0
- scitex/writer/_dataclasses/tree/MINIMUM_FILES.md +121 -0
- scitex/writer/_mcp/__init__.py +4 -0
- scitex/writer/_mcp/handlers.py +32 -0
- scitex/writer/_mcp/tool_schemas.py +33 -0
- scitex/writer/_project/_trees.py +2 -2
- scitex/writer/utils/__init__.py +19 -2
- scitex/writer/utils/_converters.py +635 -0
- scitex/writer/utils/_parse_latex_logs.py +1 -1
- scitex/writer/utils/_verify_tree_structure.py +205 -0
- scitex-2.15.1.dist-info/METADATA +648 -0
- scitex-2.15.1.dist-info/RECORD +2553 -0
- scitex-2.15.1.dist-info/entry_points.txt +12 -0
- scitex/audio/_mcp_handlers.py +0 -256
- scitex/audio/_mcp_tool_schemas.py +0 -203
- scitex/canvas/_mcp_handlers.py +0 -372
- scitex/canvas/_mcp_tool_schemas.py +0 -219
- scitex/canvas/editor/flask_editor/templates/_scripts.py +0 -4933
- scitex/canvas/editor/flask_editor/templates/_styles.py +0 -1658
- scitex/capture/mcp_handlers.py +0 -401
- scitex/capture/mcp_tool_defs.py +0 -192
- scitex/capture/mcp_tools.py +0 -241
- scitex/capture/mcp_utils.py +0 -30
- scitex/cli/scholar.py +0 -313
- scitex/diagram/_compile.py +0 -312
- scitex/diagram/_diagram.py +0 -355
- scitex/diagram/_mcp_handlers.py +0 -400
- scitex/diagram/_mcp_tool_schemas.py +0 -157
- scitex/diagram/_presets.py +0 -173
- scitex/diagram/_schema.py +0 -182
- scitex/diagram/_split.py +0 -278
- scitex/plt/_mcp_handlers.py +0 -361
- scitex/plt/_mcp_tool_schemas.py +0 -169
- scitex/plt/mcp_server.py +0 -205
- scitex/scholar/.legacy/Scholar.py +0 -400
- scitex/scholar/.legacy/_Scholar.py +0 -1763
- scitex/scholar/.legacy/_ScholarAPI.py +0 -316
- scitex/scholar/.legacy/_tmp/search_engine/_BaseSearchEngine.py +0 -101
- scitex/scholar/.legacy/_tmp/search_engine/_UnifiedSearcher.py +0 -392
- scitex/scholar/.legacy/_tmp/search_engine/__init__.py +0 -53
- scitex/scholar/.legacy/_tmp/search_engine/local/_LocalSearchEngine.py +0 -134
- scitex/scholar/.legacy/_tmp/search_engine/local/_VectorSearchEngine.py +0 -129
- scitex/scholar/.legacy/_tmp/search_engine/web/_ArxivSearchEngine.py +0 -279
- scitex/scholar/.legacy/_tmp/search_engine/web/_CrossRefSearchEngine.py +0 -319
- scitex/scholar/.legacy/_tmp/search_engine/web/_GoogleScholarSearchEngine.py +0 -209
- scitex/scholar/.legacy/_tmp/search_engine/web/_PubMedSearchEngine.py +0 -374
- scitex/scholar/.legacy/_tmp/search_engine/web/_SemanticScholarSearchEngine.py +0 -362
- scitex/scholar/.legacy/database/README.md +0 -121
- scitex/scholar/.legacy/database/README_CONCURRENT_ACCESS.md +0 -103
- scitex/scholar/.legacy/database/_DatabaseEntry.py +0 -232
- scitex/scholar/.legacy/database/_DatabaseIndex.py +0 -426
- scitex/scholar/.legacy/database/_LibraryManager.py +0 -276
- scitex/scholar/.legacy/database/_PaperDatabase.py +0 -543
- scitex/scholar/.legacy/database/_ScholarDatabaseIntegration.py +0 -391
- scitex/scholar/.legacy/database/_StorageIntegratedDB.py +0 -619
- scitex/scholar/.legacy/database/_ZoteroCompatibleDB.py +0 -1194
- scitex/scholar/.legacy/database/__init__.py +0 -28
- scitex/scholar/.legacy/database/manage.py +0 -274
- scitex/scholar/.legacy/lookup/_LookupIndex.py +0 -470
- scitex/scholar/.legacy/lookup/__init__.py +0 -22
- scitex/scholar/.legacy/metadata/README.md +0 -62
- scitex/scholar/.legacy/metadata/__init__.py +0 -1
- scitex/scholar/.legacy/metadata/doi/README.md +0 -368
- scitex/scholar/.legacy/metadata/doi/__init__.py +0 -7
- scitex/scholar/.legacy/metadata/doi/batch/_MetadataHandlerForBatchDOIResolution.py +0 -304
- scitex/scholar/.legacy/metadata/doi/batch/_ProgressManagerForBatchDOIResolution.py +0 -304
- scitex/scholar/.legacy/metadata/doi/batch/_SourceStatsManagerForBatchDOIResolution.py +0 -299
- scitex/scholar/.legacy/metadata/doi/batch/__init__.py +0 -26
- scitex/scholar/.legacy/metadata/doi/resolvers/_BatchDOIResolver.py +0 -586
- scitex/scholar/.legacy/metadata/doi/resolvers/_BibTeXDOIResolver.py +0 -609
- scitex/scholar/.legacy/metadata/doi/resolvers/_DOIResolver.py +0 -192
- scitex/scholar/.legacy/metadata/doi/resolvers/_SingleDOIResolver.py +0 -395
- scitex/scholar/.legacy/metadata/doi/resolvers/__init__.py +0 -2
- scitex/scholar/.legacy/metadata/doi/sources/.combined-SemanticScholarSource/_SemanticScholarSource.py +0 -289
- scitex/scholar/.legacy/metadata/doi/sources/.combined-SemanticScholarSource/_SemanticScholarSourceEnhanced.py +0 -229
- scitex/scholar/.legacy/metadata/doi/sources/_ArXivSource.py +0 -306
- scitex/scholar/.legacy/metadata/doi/sources/_BaseDOISource.py +0 -347
- scitex/scholar/.legacy/metadata/doi/sources/_CrossRefLocalSource.py +0 -79
- scitex/scholar/.legacy/metadata/doi/sources/_CrossRefSource.py +0 -225
- scitex/scholar/.legacy/metadata/doi/sources/_OpenAlexSource.py +0 -306
- scitex/scholar/.legacy/metadata/doi/sources/_PubMedSource.py +0 -302
- scitex/scholar/.legacy/metadata/doi/sources/_SemanticScholarSource.py +0 -341
- scitex/scholar/.legacy/metadata/doi/sources/_SourceManager.py +0 -317
- scitex/scholar/.legacy/metadata/doi/sources/_SourceResolutionStrategy.py +0 -595
- scitex/scholar/.legacy/metadata/doi/sources/_SourceRotationManager.py +0 -585
- scitex/scholar/.legacy/metadata/doi/sources/_URLDOISource.py +0 -394
- scitex/scholar/.legacy/metadata/doi/sources/_UnifiedSource.py +0 -412
- scitex/scholar/.legacy/metadata/doi/sources/__init__.py +0 -38
- scitex/scholar/.legacy/metadata/doi/utils/_PubMedConverter.py +0 -465
- scitex/scholar/.legacy/metadata/doi/utils/_RateLimitHandler.py +0 -707
- scitex/scholar/.legacy/metadata/doi/utils/_TextNormalizer.py +0 -587
- scitex/scholar/.legacy/metadata/doi/utils/_URLDOIExtractor.py +0 -278
- scitex/scholar/.legacy/metadata/doi/utils/__init__.py +0 -40
- scitex/scholar/.legacy/metadata/doi/utils/_to_complete_metadata_structure.py +0 -315
- scitex/scholar/.legacy/metadata/enrichment/README.md +0 -51
- scitex/scholar/.legacy/metadata/enrichment/_LibraryEnricher.py +0 -99
- scitex/scholar/.legacy/metadata/enrichment/__init__.py +0 -2
- scitex/scholar/.legacy/metadata/enrichment/enrichers/_ImpactFactorEnricher.py +0 -107
- scitex/scholar/.legacy/metadata/enrichment/enrichers/_SmartEnricher.py +0 -164
- scitex/scholar/.legacy/metadata/enrichment/enrichers/__init__.py +0 -4
- scitex/scholar/.legacy/metadata/enrichment/sources/_UnifiedMetadataSource.py +0 -126
- scitex/scholar/.legacy/metadata/enrichment/sources/__init__.py +0 -3
- scitex/scholar/.legacy/metadata/query_to_full_meta_json.py +0 -184
- scitex/scholar/.legacy/metadata/urls/.tmp/open_url/KNOWN_RESOLVERS.py +0 -462
- scitex/scholar/.legacy/metadata/urls/.tmp/open_url/README.md +0 -223
- scitex/scholar/.legacy/metadata/urls/.tmp/open_url/_DOIToURLResolver.py +0 -694
- scitex/scholar/.legacy/metadata/urls/.tmp/open_url/_OpenURLResolver.py +0 -1160
- scitex/scholar/.legacy/metadata/urls/.tmp/open_url/_ResolverLinkFinder.py +0 -344
- scitex/scholar/.legacy/metadata/urls/.tmp/open_url/__init__.py +0 -24
- scitex/scholar/.legacy/metadata/urls/README.md +0 -142
- scitex/scholar/.legacy/metadata/urls/_URLMetadataHandler.py +0 -383
- scitex/scholar/.legacy/metadata/urls/_ZoteroTranslatorRunner.py +0 -294
- scitex/scholar/.legacy/metadata/urls/__init__.py +0 -39
- scitex/scholar/.legacy/metadata/urls/_finder.py +0 -319
- scitex/scholar/.legacy/metadata/urls/_handler.py +0 -326
- scitex/scholar/.legacy/metadata/urls/_resolver.py +0 -287
- scitex/scholar/.legacy/metadata/urls/docs/CORE_URL_TYPES.md +0 -187
- scitex/scholar/.legacy/metadata/urls/docs/URL_SCHEMA.md +0 -223
- scitex/scholar/.legacy/metadata/urls/zotero_translators/.ci/.eslintrc +0 -11
- scitex/scholar/.legacy/metadata/urls/zotero_translators/.ci/AGPL +0 -22
- scitex/scholar/.legacy/metadata/urls/zotero_translators/.ci/checkDeletedTxt.sh +0 -46
- scitex/scholar/.legacy/metadata/urls/zotero_translators/.ci/eslint-plugin-zotero-translator/bin/teslint.js +0 -9
- scitex/scholar/.legacy/metadata/urls/zotero_translators/.ci/eslint-plugin-zotero-translator/index.js +0 -15
- scitex/scholar/.legacy/metadata/urls/zotero_translators/.ci/eslint-plugin-zotero-translator/package-lock.json +0 -151
- scitex/scholar/.legacy/metadata/urls/zotero_translators/.ci/eslint-plugin-zotero-translator/package.json +0 -21
- scitex/scholar/.legacy/metadata/urls/zotero_translators/.ci/eslint-plugin-zotero-translator/processor.js +0 -257
- scitex/scholar/.legacy/metadata/urls/zotero_translators/.ci/helper.sh +0 -29
- scitex/scholar/.legacy/metadata/urls/zotero_translators/.ci/lint.sh +0 -12
- scitex/scholar/.legacy/metadata/urls/zotero_translators/.ci/pull-request-check/check-pull-request.sh +0 -39
- scitex/scholar/.legacy/metadata/urls/zotero_translators/.ci/pull-request-check/selenium-test.js +0 -147
- scitex/scholar/.legacy/metadata/urls/zotero_translators/.ci/pull-request-check/translator-server.js +0 -72
- scitex/scholar/.legacy/metadata/urls/zotero_translators/.ci/updateTypes.mjs +0 -75
- scitex/scholar/.legacy/metadata/urls/zotero_translators/.editorconfig +0 -8
- scitex/scholar/.legacy/metadata/urls/zotero_translators/.eslintrc +0 -70
- scitex/scholar/.legacy/metadata/urls/zotero_translators/ABC News Australia.js +0 -224
- scitex/scholar/.legacy/metadata/urls/zotero_translators/ACLS Humanities EBook.js +0 -165
- scitex/scholar/.legacy/metadata/urls/zotero_translators/ACLWeb.js +0 -600
- scitex/scholar/.legacy/metadata/urls/zotero_translators/ACM Digital Library.js +0 -710
- scitex/scholar/.legacy/metadata/urls/zotero_translators/ACS Publications.js +0 -633
- scitex/scholar/.legacy/metadata/urls/zotero_translators/ADS Bibcode.js +0 -664
- scitex/scholar/.legacy/metadata/urls/zotero_translators/AEA Web.js +0 -450
- scitex/scholar/.legacy/metadata/urls/zotero_translators/AGRIS.js +0 -311
- scitex/scholar/.legacy/metadata/urls/zotero_translators/AIP.js +0 -295
- scitex/scholar/.legacy/metadata/urls/zotero_translators/AMS Journals.js +0 -136
- scitex/scholar/.legacy/metadata/urls/zotero_translators/AMS MathSciNet (Legacy).js +0 -313
- scitex/scholar/.legacy/metadata/urls/zotero_translators/AMS MathSciNet.js +0 -288
- scitex/scholar/.legacy/metadata/urls/zotero_translators/APA PsycNET.js +0 -915
- scitex/scholar/.legacy/metadata/urls/zotero_translators/APN.ru.js +0 -132
- scitex/scholar/.legacy/metadata/urls/zotero_translators/APS-Physics.js +0 -204
- scitex/scholar/.legacy/metadata/urls/zotero_translators/APS.js +0 -542
- scitex/scholar/.legacy/metadata/urls/zotero_translators/ARTFL Encyclopedie.js +0 -283
- scitex/scholar/.legacy/metadata/urls/zotero_translators/ARTnews.js +0 -155
- scitex/scholar/.legacy/metadata/urls/zotero_translators/ARTstor.js +0 -619
- scitex/scholar/.legacy/metadata/urls/zotero_translators/ASCE.js +0 -199
- scitex/scholar/.legacy/metadata/urls/zotero_translators/ASCO Meeting Library.js +0 -153
- scitex/scholar/.legacy/metadata/urls/zotero_translators/ASTIS.js +0 -337
- scitex/scholar/.legacy/metadata/urls/zotero_translators/ATS International Journal.js +0 -290
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Access Engineering.js +0 -384
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Access Medicine.js +0 -343
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Access Science.js +0 -391
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Adam Matthew Digital.js +0 -405
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Agencia del ISBN.js +0 -77
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Ahval News.js +0 -309
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Air University Journals.js +0 -236
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Airiti.js +0 -423
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Alexander Street Press.js +0 -198
- scitex/scholar/.legacy/metadata/urls/zotero_translators/AllAfrica.js +0 -291
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Alsharekh.js +0 -242
- scitex/scholar/.legacy/metadata/urls/zotero_translators/AlterNet.js +0 -134
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Aluka.js +0 -261
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Amazon.js +0 -1043
- scitex/scholar/.legacy/metadata/urls/zotero_translators/American Archive of Public Broadcasting.js +0 -592
- scitex/scholar/.legacy/metadata/urls/zotero_translators/American Institute of Aeronautics and Astronautics.js +0 -210
- scitex/scholar/.legacy/metadata/urls/zotero_translators/American Prospect.js +0 -114
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Ancestry.com US Federal Census.js +0 -164
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Annual Reviews.js +0 -329
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Antikvarium.hu.js +0 -280
- scitex/scholar/.legacy/metadata/urls/zotero_translators/AquaDocs.js +0 -390
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Archeion.js +0 -249
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Archiv fuer Sozialgeschichte.js +0 -157
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Archive Ouverte en Sciences de l'Information et de la Communication (AOSIC).js +0 -179
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Archives Canada.js +0 -142
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Ariana News.js +0 -203
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Art Institute of Chicago.js +0 -279
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Artefacts Canada.js +0 -192
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Artforum.js +0 -438
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Atlanta Journal-Constitution.js +0 -311
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Atypon Journals.js +0 -1204
- scitex/scholar/.legacy/metadata/urls/zotero_translators/AustLII and NZLII.js +0 -604
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Australian Dictionary of Biography.js +0 -196
- scitex/scholar/.legacy/metadata/urls/zotero_translators/BAILII.js +0 -176
- scitex/scholar/.legacy/metadata/urls/zotero_translators/BBC Genome.js +0 -254
- scitex/scholar/.legacy/metadata/urls/zotero_translators/BBC.js +0 -430
- scitex/scholar/.legacy/metadata/urls/zotero_translators/BIBSYS.js +0 -112
- scitex/scholar/.legacy/metadata/urls/zotero_translators/BOCC.js +0 -217
- scitex/scholar/.legacy/metadata/urls/zotero_translators/BOE.js +0 -229
- scitex/scholar/.legacy/metadata/urls/zotero_translators/BOFiP-Impots.js +0 -132
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Baidu Scholar.js +0 -276
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Bangkok Post.js +0 -216
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Baruch Foundation.js +0 -175
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Beobachter.js +0 -175
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Bezneng Gajit.js +0 -92
- scitex/scholar/.legacy/metadata/urls/zotero_translators/BibLaTeX.js +0 -888
- scitex/scholar/.legacy/metadata/urls/zotero_translators/BibTeX.js +0 -4236
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Biblio.com.js +0 -216
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Bibliontology RDF.js +0 -1166
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Biblioteca Nacional de Maestros.js +0 -213
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Bibliotheque et Archives Nationale du Quebec (Pistard).js +0 -147
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Bibliotheque et Archives Nationales du Quebec.js +0 -266
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Bibliotheque nationale de France.js +0 -872
- scitex/scholar/.legacy/metadata/urls/zotero_translators/BioMed Central.js +0 -585
- scitex/scholar/.legacy/metadata/urls/zotero_translators/BioOne.js +0 -233
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Bioconductor.js +0 -343
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Blaetter.js +0 -192
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Blogger.js +0 -244
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Bloomberg.js +0 -205
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Bloomsbury Food Library.js +0 -296
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Bluesky.js +0 -195
- scitex/scholar/.legacy/metadata/urls/zotero_translators/BnF ISBN.js +0 -129
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Bookmarks.js +0 -282
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Bookshop.org.js +0 -223
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Boston Review.js +0 -332
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Bosworth Toller's Anglo-Saxon Dictionary Online.js +0 -496
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Bracero History Archive.js +0 -200
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Brill.js +0 -434
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Brukerhandboken.js +0 -153
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Bryn Mawr Classical Review.js +0 -303
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Bundesgesetzblatt.js +0 -231
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Business Standard.js +0 -151
- scitex/scholar/.legacy/metadata/urls/zotero_translators/CABI - CAB Abstracts.js +0 -317
- scitex/scholar/.legacy/metadata/urls/zotero_translators/CAOD.js +0 -260
- scitex/scholar/.legacy/metadata/urls/zotero_translators/CBC.js +0 -439
- scitex/scholar/.legacy/metadata/urls/zotero_translators/CCfr (BnF).js +0 -162
- scitex/scholar/.legacy/metadata/urls/zotero_translators/CERN Document Server.js +0 -277
- scitex/scholar/.legacy/metadata/urls/zotero_translators/CEUR Workshop Proceedings.js +0 -145
- scitex/scholar/.legacy/metadata/urls/zotero_translators/CFF References.js +0 -170
- scitex/scholar/.legacy/metadata/urls/zotero_translators/CFF.js +0 -113
- scitex/scholar/.legacy/metadata/urls/zotero_translators/CIA World Factbook.js +0 -128
- scitex/scholar/.legacy/metadata/urls/zotero_translators/CLACSO.js +0 -226
- scitex/scholar/.legacy/metadata/urls/zotero_translators/CLASE.js +0 -135
- scitex/scholar/.legacy/metadata/urls/zotero_translators/CNKI.js +0 -731
- scitex/scholar/.legacy/metadata/urls/zotero_translators/COBISS.js +0 -1945
- scitex/scholar/.legacy/metadata/urls/zotero_translators/COinS.js +0 -336
- scitex/scholar/.legacy/metadata/urls/zotero_translators/CQ Press.js +0 -418
- scitex/scholar/.legacy/metadata/urls/zotero_translators/CROSBI.js +0 -227
- scitex/scholar/.legacy/metadata/urls/zotero_translators/CSIRO Publishing.js +0 -139
- scitex/scholar/.legacy/metadata/urls/zotero_translators/CSL JSON.js +0 -203
- scitex/scholar/.legacy/metadata/urls/zotero_translators/CSV.js +0 -294
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Cairn.info.js +0 -368
- scitex/scholar/.legacy/metadata/urls/zotero_translators/CalMatters.js +0 -228
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Calisphere.js +0 -355
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Camara Brasileira do Livro ISBN.js +0 -842
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Cambridge Core.js +0 -580
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Cambridge Engage Preprints.js +0 -276
- scitex/scholar/.legacy/metadata/urls/zotero_translators/CanLII.js +0 -284
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Canada.com.js +0 -171
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Canadian Letters and Images.js +0 -148
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Canadiana.ca.js +0 -196
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Cascadilla Proceedings Project.js +0 -390
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Cell Press.js +0 -516
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Central and Eastern European Online Library Journals.js +0 -313
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Champlain Society - Collection.js +0 -220
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Chicago Journal of Theoretical Computer Science.js +0 -203
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Christian Science Monitor.js +0 -148
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Chronicling America.js +0 -131
- scitex/scholar/.legacy/metadata/urls/zotero_translators/CiNii Research.js +0 -168
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Citavi 5 XML.js +0 -516
- scitex/scholar/.legacy/metadata/urls/zotero_translators/CiteSeer.js +0 -196
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Citizen Lab.js +0 -347
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Civilization.ca.js +0 -146
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Climate Change and Human Health Literature Portal.js +0 -283
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Clinical Key.js +0 -367
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Code4Lib Journal.js +0 -143
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Colorado State Legislature.js +0 -215
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Columbia University Press.js +0 -238
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Common-Place.js +0 -218
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Computer History Museum Archive.js +0 -1319
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Copernicus.js +0 -461
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Cornell LII.js +0 -252
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Cornell University Press.js +0 -235
- scitex/scholar/.legacy/metadata/urls/zotero_translators/CourtListener.js +0 -265
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Crossref REST.js +0 -1757
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Crossref Unixref XML.js +0 -965
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Current Affairs.js +0 -160
- scitex/scholar/.legacy/metadata/urls/zotero_translators/DABI.js +0 -476
- scitex/scholar/.legacy/metadata/urls/zotero_translators/DAI-Zenon.js +0 -392
- scitex/scholar/.legacy/metadata/urls/zotero_translators/DART-Europe.js +0 -176
- scitex/scholar/.legacy/metadata/urls/zotero_translators/DBLP Computer Science Bibliography.js +0 -462
- scitex/scholar/.legacy/metadata/urls/zotero_translators/DBpia.js +0 -233
- scitex/scholar/.legacy/metadata/urls/zotero_translators/DEPATISnet.js +0 -373
- scitex/scholar/.legacy/metadata/urls/zotero_translators/DOAJ.js +0 -242
- scitex/scholar/.legacy/metadata/urls/zotero_translators/DOI Content Negotiation.js +0 -352
- scitex/scholar/.legacy/metadata/urls/zotero_translators/DOI.js +0 -322
- scitex/scholar/.legacy/metadata/urls/zotero_translators/DPLA.js +0 -425
- scitex/scholar/.legacy/metadata/urls/zotero_translators/DSpace Intermediate Metadata.js +0 -208
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Dagens Nyheter.js +0 -369
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Dagstuhl Research Online Publication Server.js +0 -278
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Dar Almandumah.js +0 -253
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Data.gov.js +0 -225
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Databrary.js +0 -184
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Datacite JSON.js +0 -1182
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Dataverse.js +0 -418
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Daum News.js +0 -139
- scitex/scholar/.legacy/metadata/urls/zotero_translators/De Gruyter Brill.js +0 -674
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Defense Technical Information Center.js +0 -146
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Delpher.js +0 -413
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Demographic Research.js +0 -164
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Denik CZ.js +0 -273
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Der Freitag.js +0 -236
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Der Spiegel.js +0 -479
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Desiring God.js +0 -216
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Deutsche Fotothek.js +0 -364
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Deutsche Nationalbibliothek.js +0 -594
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Dialnet.js +0 -258
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Die Zeit.js +0 -378
- scitex/scholar/.legacy/metadata/urls/zotero_translators/DigiZeitschriften.js +0 -269
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Digital Humanities Quarterly.js +0 -207
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Digital Spy.js +0 -215
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Dimensions.js +0 -233
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Douban.js +0 -316
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Dreier Neuerscheinungsdienst.js +0 -209
- scitex/scholar/.legacy/metadata/urls/zotero_translators/DrugBank.ca.js +0 -209
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Dryad Digital Repository.js +0 -323
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Duke University Press Books.js +0 -250
- scitex/scholar/.legacy/metadata/urls/zotero_translators/E-periodica Switzerland.js +0 -347
- scitex/scholar/.legacy/metadata/urls/zotero_translators/EBSCO Discovery Layer.js +0 -147
- scitex/scholar/.legacy/metadata/urls/zotero_translators/EBSCOhost.js +0 -592
- scitex/scholar/.legacy/metadata/urls/zotero_translators/EIDR.js +0 -184
- scitex/scholar/.legacy/metadata/urls/zotero_translators/EPA National Library Catalog.js +0 -245
- scitex/scholar/.legacy/metadata/urls/zotero_translators/ERIC.js +0 -986
- scitex/scholar/.legacy/metadata/urls/zotero_translators/ESpacenet.js +0 -465
- scitex/scholar/.legacy/metadata/urls/zotero_translators/EUR-Lex.js +0 -423
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Eastview.js +0 -336
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Edinburgh University Press Journals.js +0 -178
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Education Week.js +0 -197
- scitex/scholar/.legacy/metadata/urls/zotero_translators/El Comercio (Peru).js +0 -347
- scitex/scholar/.legacy/metadata/urls/zotero_translators/El Pais.js +0 -262
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Electronic Colloquium on Computational Complexity.js +0 -230
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Elicit.js +0 -120
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Elsevier Health Journals.js +0 -531
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Elsevier Pure.js +0 -420
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Embedded Metadata.js +0 -1951
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Emerald Insight.js +0 -626
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Encyclopedia of Chicago.js +0 -162
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Encyclopedia of Korean Culture.js +0 -221
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Endnote XML.js +0 -1407
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Engineering Village.js +0 -139
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Envidat.js +0 -331
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Epicurious.js +0 -144
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Erudit.js +0 -272
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Euclid.js +0 -220
- scitex/scholar/.legacy/metadata/urls/zotero_translators/EurasiaNet.js +0 -109
- scitex/scholar/.legacy/metadata/urls/zotero_translators/EurogamerUSgamer.js +0 -380
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Europe PMC.js +0 -448
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Evernote.js +0 -104
- scitex/scholar/.legacy/metadata/urls/zotero_translators/F1000 Research.js +0 -655
- scitex/scholar/.legacy/metadata/urls/zotero_translators/FAO Publications.js +0 -1139
- scitex/scholar/.legacy/metadata/urls/zotero_translators/FAZ.NET.js +0 -231
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Fachportal Padagogik.js +0 -839
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Factiva.js +0 -302
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Failed Architecture.js +0 -114
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Fairfax Australia.js +0 -200
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Fatcat.js +0 -425
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Figshare.js +0 -191
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Financial Times.js +0 -187
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Finna.js +0 -357
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Flickr.js +0 -318
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Foreign Affairs.js +0 -485
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Foreign Policy.js +0 -146
- scitex/scholar/.legacy/metadata/urls/zotero_translators/FreeCite.js +0 -95
- scitex/scholar/.legacy/metadata/urls/zotero_translators/FreePatentsOnline.js +0 -265
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Frieze.js +0 -243
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Frontiers.js +0 -667
- scitex/scholar/.legacy/metadata/urls/zotero_translators/GMS German Medical Science.js +0 -319
- scitex/scholar/.legacy/metadata/urls/zotero_translators/GPO Access e-CFR.js +0 -134
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Gale Databases.js +0 -324
- scitex/scholar/.legacy/metadata/urls/zotero_translators/GaleGDC.js +0 -189
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Galegroup.js +0 -327
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Gallica.js +0 -194
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Game Studies.js +0 -155
- scitex/scholar/.legacy/metadata/urls/zotero_translators/GameSpot.js +0 -199
- scitex/scholar/.legacy/metadata/urls/zotero_translators/GameStar GamePro.js +0 -198
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Gasyrlar Awazy.js +0 -156
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Gemeinsamer Bibliotheksverbund ISBN.js +0 -23
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Gene Ontology.js +0 -128
- scitex/scholar/.legacy/metadata/urls/zotero_translators/GitHub.js +0 -501
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Globes.js +0 -243
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Gmail.js +0 -64
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Goodreads.js +0 -219
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Google Books.js +0 -552
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Google Patents.js +0 -959
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Google Play.js +0 -186
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Google Presentation.js +0 -104
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Google Research.js +0 -221
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Google Scholar.js +0 -1361
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Gulag Many Days, Many Lives.js +0 -179
- scitex/scholar/.legacy/metadata/urls/zotero_translators/HAL Archives Ouvertes.js +0 -429
- scitex/scholar/.legacy/metadata/urls/zotero_translators/HCSP.js +0 -312
- scitex/scholar/.legacy/metadata/urls/zotero_translators/HUDOC.js +0 -650
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Haaretz.js +0 -562
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Habr.js +0 -232
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Handelszeitung.js +0 -273
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Hanrei Watch.js +0 -123
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Harper's Magazine.js +0 -365
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Harvard Business Review.js +0 -326
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Harvard Caselaw Access Project.js +0 -244
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Harvard University Press Books.js +0 -286
- scitex/scholar/.legacy/metadata/urls/zotero_translators/HathiTrust.js +0 -311
- scitex/scholar/.legacy/metadata/urls/zotero_translators/HeinOnline.js +0 -266
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Heise.js +0 -200
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Herder.js +0 -236
- scitex/scholar/.legacy/metadata/urls/zotero_translators/HighBeam.js +0 -198
- scitex/scholar/.legacy/metadata/urls/zotero_translators/HighWire 2.0.js +0 -1355
- scitex/scholar/.legacy/metadata/urls/zotero_translators/HighWire.js +0 -209
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Hindawi Publishers.js +0 -177
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Hispanic-American Periodical Index.js +0 -236
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Homeland Security Digital Library.js +0 -426
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Huff Post.js +0 -223
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Human Rights Watch.js +0 -450
- scitex/scholar/.legacy/metadata/urls/zotero_translators/IBISWorld.js +0 -171
- scitex/scholar/.legacy/metadata/urls/zotero_translators/IDEA ALM.js +0 -536
- scitex/scholar/.legacy/metadata/urls/zotero_translators/IEEE Computer Society.js +0 -429
- scitex/scholar/.legacy/metadata/urls/zotero_translators/IEEE Xplore.js +0 -1000
- scitex/scholar/.legacy/metadata/urls/zotero_translators/IETF.js +0 -451
- scitex/scholar/.legacy/metadata/urls/zotero_translators/IGN.js +0 -136
- scitex/scholar/.legacy/metadata/urls/zotero_translators/IMDb.js +0 -566
- scitex/scholar/.legacy/metadata/urls/zotero_translators/INSPIRE.js +0 -247
- scitex/scholar/.legacy/metadata/urls/zotero_translators/IPCC.js +0 -757
- scitex/scholar/.legacy/metadata/urls/zotero_translators/ISTC.js +0 -181
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Idref.js +0 -179
- scitex/scholar/.legacy/metadata/urls/zotero_translators/In These Times.js +0 -196
- scitex/scholar/.legacy/metadata/urls/zotero_translators/InfoTrac.js +0 -279
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Informationssystem Medienpaedagogik.js +0 -305
- scitex/scholar/.legacy/metadata/urls/zotero_translators/IngentaConnect.js +0 -312
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Inside Higher Ed.js +0 -167
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Insignia OPAC.js +0 -114
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Institute of Contemporary Art.js +0 -180
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Institute of Physics.js +0 -340
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Integrum.js +0 -173
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Intellixir.js +0 -264
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Inter-Research Science Center.js +0 -185
- scitex/scholar/.legacy/metadata/urls/zotero_translators/International Nuclear Information System.js +0 -285
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Internet Archive Scholar.js +0 -106
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Internet Archive Wayback Machine.js +0 -152
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Internet Archive.js +0 -552
- scitex/scholar/.legacy/metadata/urls/zotero_translators/InvenioRDM.js +0 -1260
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Isidore.js +0 -235
- scitex/scholar/.legacy/metadata/urls/zotero_translators/J-Stage.js +0 -272
- scitex/scholar/.legacy/metadata/urls/zotero_translators/JETS.js +0 -122
- scitex/scholar/.legacy/metadata/urls/zotero_translators/JISC Historical Texts.js +0 -273
- scitex/scholar/.legacy/metadata/urls/zotero_translators/JRC Publications Repository.js +0 -569
- scitex/scholar/.legacy/metadata/urls/zotero_translators/JSTOR.js +0 -821
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Jahrbuch.js +0 -213
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Japan Times Online.js +0 -138
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Journal of Electronic Publishing.js +0 -147
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Journal of Extension.js +0 -288
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Journal of Machine Learning Research.js +0 -441
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Journal of Religion and Society.js +0 -174
- scitex/scholar/.legacy/metadata/urls/zotero_translators/JurPC.js +0 -274
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Juricaf.js +0 -141
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Juris.js +0 -728
- scitex/scholar/.legacy/metadata/urls/zotero_translators/K10plus ISBN.js +0 -386
- scitex/scholar/.legacy/metadata/urls/zotero_translators/KStudy.js +0 -632
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Kanopy.js +0 -358
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Khaama Press.js +0 -249
- scitex/scholar/.legacy/metadata/urls/zotero_translators/KitapYurdu.com.js +0 -376
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Kommersant.js +0 -174
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Korean National Library.js +0 -621
- scitex/scholar/.legacy/metadata/urls/zotero_translators/L'Annee Philologique.js +0 -267
- scitex/scholar/.legacy/metadata/urls/zotero_translators/LA Times.js +0 -239
- scitex/scholar/.legacy/metadata/urls/zotero_translators/LIBRIS ISBN.js +0 -103
- scitex/scholar/.legacy/metadata/urls/zotero_translators/LIVIVO.js +0 -260
- scitex/scholar/.legacy/metadata/urls/zotero_translators/LWN.net.js +0 -315
- scitex/scholar/.legacy/metadata/urls/zotero_translators/La Croix.js +0 -237
- scitex/scholar/.legacy/metadata/urls/zotero_translators/La Nacion (Argentina).js +0 -231
- scitex/scholar/.legacy/metadata/urls/zotero_translators/La Presse.js +0 -218
- scitex/scholar/.legacy/metadata/urls/zotero_translators/La Republica (Peru).js +0 -174
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Lagen.nu.js +0 -214
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Landesbibliographie Baden-Wurttemberg.js +0 -324
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Lapham's Quarterly.js +0 -1062
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Le Devoir.js +0 -167
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Le Figaro.js +0 -225
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Le Maitron.js +0 -484
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Le Monde.js +0 -258
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Le monde diplomatique.js +0 -200
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Legifrance.js +0 -641
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Legislative Insight.js +0 -406
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Lexis+.js +0 -264
- scitex/scholar/.legacy/metadata/urls/zotero_translators/LexisNexis.js +0 -505
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Libraries Tasmania.js +0 -778
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (Aleph).js +0 -385
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (Amicus).js +0 -254
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (Aquabrowser).js +0 -253
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (BiblioCommons).js +0 -249
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (Blacklight).js +0 -341
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (Capita Prism).js +0 -162
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (DRA).js +0 -203
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (Dynix).js +0 -315
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (Encore).js +0 -211
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (InnoPAC).js +0 -305
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (Koha).js +0 -225
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (Mango).js +0 -285
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (OPALS).js +0 -200
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (PICA).js +0 -2120
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (PICA2).js +0 -331
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (Pika).js +0 -488
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (Polaris).js +0 -183
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (Quolto).js +0 -320
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (RERO ILS).js +0 -754
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (SIRSI eLibrary).js +0 -407
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (SIRSI).js +0 -452
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (SLIMS).js +0 -146
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (TIND ILS).js +0 -773
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (TLCYouSeeMore).js +0 -132
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (TinREAD).js +0 -277
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (VTLS).js +0 -125
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (Visual Library 2021).js +0 -765
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (Voyager 7).js +0 -199
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Catalog (Voyager).js +0 -212
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Genesis.js +0 -337
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Library Hub Discover.js +0 -359
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Library of Congress Digital Collections.js +0 -869
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Library of Congress ISBN.js +0 -86
- scitex/scholar/.legacy/metadata/urls/zotero_translators/LingBuzz.js +0 -359
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Lippincott Williams and Wilkins.js +0 -341
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Literary Hub.js +0 -950
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Litres.js +0 -236
- scitex/scholar/.legacy/metadata/urls/zotero_translators/LiveJournal.js +0 -219
- scitex/scholar/.legacy/metadata/urls/zotero_translators/London Review of Books.js +0 -291
- scitex/scholar/.legacy/metadata/urls/zotero_translators/LookUs.js +0 -260
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Lulu.js +0 -264
- scitex/scholar/.legacy/metadata/urls/zotero_translators/MAB2.js +0 -373
- scitex/scholar/.legacy/metadata/urls/zotero_translators/MARC.js +0 -1080
- scitex/scholar/.legacy/metadata/urls/zotero_translators/MARCXML.js +0 -489
- scitex/scholar/.legacy/metadata/urls/zotero_translators/MCV.js +0 -258
- scitex/scholar/.legacy/metadata/urls/zotero_translators/MDPI Journals.js +0 -356
- scitex/scholar/.legacy/metadata/urls/zotero_translators/MEDLINEnbib.js +0 -1561
- scitex/scholar/.legacy/metadata/urls/zotero_translators/METS.js +0 -384
- scitex/scholar/.legacy/metadata/urls/zotero_translators/MIDAS Journals.js +0 -343
- scitex/scholar/.legacy/metadata/urls/zotero_translators/MIT Press Books.js +0 -637
- scitex/scholar/.legacy/metadata/urls/zotero_translators/MODS.js +0 -2545
- scitex/scholar/.legacy/metadata/urls/zotero_translators/MPG PuRe.js +0 -541
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Mailman.js +0 -136
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Mainichi Daily News.js +0 -189
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Mastodon.js +0 -198
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Matbugat.ru.js +0 -110
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Max Planck Institute for the History of Science Virtual Laboratory Library.js +0 -136
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Medium.js +0 -208
- scitex/scholar/.legacy/metadata/urls/zotero_translators/MetaLib.js +0 -126
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Microbiology Society Journals.js +0 -343
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Microsoft Academic.js +0 -424
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Mikromarc.js +0 -207
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Milli Kutuphane.js +0 -244
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Musee du Louvre.js +0 -265
- scitex/scholar/.legacy/metadata/urls/zotero_translators/NASA ADS.js +0 -889
- scitex/scholar/.legacy/metadata/urls/zotero_translators/NASA NTRS.js +0 -610
- scitex/scholar/.legacy/metadata/urls/zotero_translators/NCBI Nucleotide.js +0 -227
- scitex/scholar/.legacy/metadata/urls/zotero_translators/NPR.js +0 -341
- scitex/scholar/.legacy/metadata/urls/zotero_translators/NRC Research Press.js +0 -181
- scitex/scholar/.legacy/metadata/urls/zotero_translators/NRC.nl.js +0 -226
- scitex/scholar/.legacy/metadata/urls/zotero_translators/NTSB Accident Reports.js +0 -226
- scitex/scholar/.legacy/metadata/urls/zotero_translators/NYPL Menus.js +0 -275
- scitex/scholar/.legacy/metadata/urls/zotero_translators/NYPL Research Catalog.js +0 -458
- scitex/scholar/.legacy/metadata/urls/zotero_translators/NYTimes.com.js +0 -858
- scitex/scholar/.legacy/metadata/urls/zotero_translators/NZZ.ch.js +0 -272
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Nagoya University OPAC.js +0 -336
- scitex/scholar/.legacy/metadata/urls/zotero_translators/National Academies Press.js +0 -243
- scitex/scholar/.legacy/metadata/urls/zotero_translators/National Agriculture Library.js +0 -524
- scitex/scholar/.legacy/metadata/urls/zotero_translators/National Archives of Australia.js +0 -522
- scitex/scholar/.legacy/metadata/urls/zotero_translators/National Archives of South Africa.js +0 -122
- scitex/scholar/.legacy/metadata/urls/zotero_translators/National Bureau of Economic Research.js +0 -363
- scitex/scholar/.legacy/metadata/urls/zotero_translators/National Diet Library Catalogue.js +0 -333
- scitex/scholar/.legacy/metadata/urls/zotero_translators/National Gallery of Art - USA.js +0 -149
- scitex/scholar/.legacy/metadata/urls/zotero_translators/National Gallery of Australia.js +0 -252
- scitex/scholar/.legacy/metadata/urls/zotero_translators/National Library of Australia (new catalog).js +0 -223
- scitex/scholar/.legacy/metadata/urls/zotero_translators/National Library of Belarus.js +0 -171
- scitex/scholar/.legacy/metadata/urls/zotero_translators/National Library of Norway.js +0 -310
- scitex/scholar/.legacy/metadata/urls/zotero_translators/National Library of Poland ISBN.js +0 -140
- scitex/scholar/.legacy/metadata/urls/zotero_translators/National Post.js +0 -186
- scitex/scholar/.legacy/metadata/urls/zotero_translators/National Technical Reports Library.js +0 -276
- scitex/scholar/.legacy/metadata/urls/zotero_translators/National Transportation Library ROSA P.js +0 -562
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Nature Publishing Group.js +0 -3394
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Neural Information Processing Systems.js +0 -385
- scitex/scholar/.legacy/metadata/urls/zotero_translators/New Left Review.js +0 -245
- scitex/scholar/.legacy/metadata/urls/zotero_translators/New Zealand Herald.js +0 -282
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Newlines Magazine.js +0 -190
- scitex/scholar/.legacy/metadata/urls/zotero_translators/News Corp Australia.js +0 -251
- scitex/scholar/.legacy/metadata/urls/zotero_translators/NewsBank.js +0 -202
- scitex/scholar/.legacy/metadata/urls/zotero_translators/NewsnetTamedia.js +0 -509
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Noor Digital Library.js +0 -267
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Note HTML.js +0 -206
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Note Markdown.js +0 -1638
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Notre Dame Philosophical Reviews.js +0 -201
- scitex/scholar/.legacy/metadata/urls/zotero_translators/OAPEN.js +0 -331
- scitex/scholar/.legacy/metadata/urls/zotero_translators/OCLC WorldCat FirstSearch.js +0 -213
- scitex/scholar/.legacy/metadata/urls/zotero_translators/OECD.js +0 -216
- scitex/scholar/.legacy/metadata/urls/zotero_translators/ORCID.js +0 -104
- scitex/scholar/.legacy/metadata/urls/zotero_translators/OSF Preprints.js +0 -417
- scitex/scholar/.legacy/metadata/urls/zotero_translators/OSTI Energy Citations.js +0 -202
- scitex/scholar/.legacy/metadata/urls/zotero_translators/OVID Tagged.js +0 -1226
- scitex/scholar/.legacy/metadata/urls/zotero_translators/OZON.ru.js +0 -465
- scitex/scholar/.legacy/metadata/urls/zotero_translators/OhioLINK.js +0 -43
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Old Bailey Online.js +0 -315
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Open Conf.js +0 -172
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Open Knowledge Repository.js +0 -811
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Open WorldCat.js +0 -1401
- scitex/scholar/.legacy/metadata/urls/zotero_translators/OpenAlex JSON.js +0 -740
- scitex/scholar/.legacy/metadata/urls/zotero_translators/OpenAlex.js +0 -444
- scitex/scholar/.legacy/metadata/urls/zotero_translators/OpenEdition Books.js +0 -155
- scitex/scholar/.legacy/metadata/urls/zotero_translators/OpenEdition Journals.js +0 -432
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Optical Society of America.js +0 -562
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Optimization Online.js +0 -418
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Ovid.js +0 -302
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Oxford Dictionaries Premium.js +0 -194
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Oxford English Dictionary.js +0 -122
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Oxford Music and Art Online.js +0 -120
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Oxford Reference.js +0 -202
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Oxford University Press.js +0 -277
- scitex/scholar/.legacy/metadata/urls/zotero_translators/PC Gamer.js +0 -302
- scitex/scholar/.legacy/metadata/urls/zotero_translators/PC Games.js +0 -128
- scitex/scholar/.legacy/metadata/urls/zotero_translators/PEI Archival Information Network.js +0 -242
- scitex/scholar/.legacy/metadata/urls/zotero_translators/PEP Web.js +0 -165
- scitex/scholar/.legacy/metadata/urls/zotero_translators/PKP Catalog Systems.js +0 -1455
- scitex/scholar/.legacy/metadata/urls/zotero_translators/PLoS Journals.js +0 -284
- scitex/scholar/.legacy/metadata/urls/zotero_translators/PRC History Review.js +0 -298
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Pajhwok Afghan News.js +0 -198
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Papers Past.js +0 -297
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Paris Review.js +0 -227
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Pastebin.js +0 -199
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Patents - USPTO.js +0 -210
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Peeters.js +0 -587
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Perceiving Systems.js +0 -350
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Perlego.js +0 -416
- scitex/scholar/.legacy/metadata/urls/zotero_translators/PhilPapers.js +0 -249
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Philosopher's Imprint.js +0 -169
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Pleade.js +0 -329
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Polygon.js +0 -270
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Potsdamer Neueste Nachrichten.js +0 -188
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Preprints.org.js +0 -305
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Primo 2018.js +0 -126
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Primo Normalized XML.js +0 -987
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Primo.js +0 -322
- scitex/scholar/.legacy/metadata/urls/zotero_translators/ProMED.js +0 -66
- scitex/scholar/.legacy/metadata/urls/zotero_translators/ProQuest Ebook Central.js +0 -226
- scitex/scholar/.legacy/metadata/urls/zotero_translators/ProQuest PolicyFile.js +0 -115
- scitex/scholar/.legacy/metadata/urls/zotero_translators/ProQuest.js +0 -2210
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Probing the Past.js +0 -151
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Project Gutenberg.js +0 -191
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Project MUSE.js +0 -451
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Protein Data Bank.js +0 -445
- scitex/scholar/.legacy/metadata/urls/zotero_translators/PubFactory Journals.js +0 -712
- scitex/scholar/.legacy/metadata/urls/zotero_translators/PubMed Central.js +0 -577
- scitex/scholar/.legacy/metadata/urls/zotero_translators/PubMed XML.js +0 -1139
- scitex/scholar/.legacy/metadata/urls/zotero_translators/PubMed.js +0 -1317
- scitex/scholar/.legacy/metadata/urls/zotero_translators/PubPub.js +0 -530
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Public Record Office Victoria.js +0 -252
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Publications Office of the European Union.js +0 -540
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Publications du Quebec.js +0 -225
- scitex/scholar/.legacy/metadata/urls/zotero_translators/PyPI.js +0 -288
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Qatar Digital Library.js +0 -802
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Queensland State Archives.js +0 -303
- scitex/scholar/.legacy/metadata/urls/zotero_translators/R-Packages.js +0 -410
- scitex/scholar/.legacy/metadata/urls/zotero_translators/RAND.js +0 -283
- scitex/scholar/.legacy/metadata/urls/zotero_translators/RDF.js +0 -1777
- scitex/scholar/.legacy/metadata/urls/zotero_translators/REDALYC.js +0 -196
- scitex/scholar/.legacy/metadata/urls/zotero_translators/RIS.js +0 -7265
- scitex/scholar/.legacy/metadata/urls/zotero_translators/RSC Publishing.js +0 -250
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Radio Free Europe Radio Liberty.js +0 -706
- scitex/scholar/.legacy/metadata/urls/zotero_translators/RePEc - Econpapers.js +0 -725
- scitex/scholar/.legacy/metadata/urls/zotero_translators/RePEc - IDEAS.js +0 -337
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Rechtspraak.nl.js +0 -295
- scitex/scholar/.legacy/metadata/urls/zotero_translators/RefWorks Tagged.js +0 -1185
- scitex/scholar/.legacy/metadata/urls/zotero_translators/ReferBibIX.js +0 -463
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Regeringskansliet.js +0 -89
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Research Square.js +0 -335
- scitex/scholar/.legacy/metadata/urls/zotero_translators/ResearchGate.js +0 -394
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Retsinformation.js +0 -348
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Reuters.js +0 -255
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Rock, Paper, Shotgun.js +0 -304
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Roll Call.js +0 -173
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Russian State Library.js +0 -1517
- scitex/scholar/.legacy/metadata/urls/zotero_translators/SAE Papers.js +0 -241
- scitex/scholar/.legacy/metadata/urls/zotero_translators/SAGE Journals.js +0 -427
- scitex/scholar/.legacy/metadata/urls/zotero_translators/SAGE Knowledge.js +0 -505
- scitex/scholar/.legacy/metadata/urls/zotero_translators/SAILDART.js +0 -364
- scitex/scholar/.legacy/metadata/urls/zotero_translators/SALT Research Archives.js +0 -196
- scitex/scholar/.legacy/metadata/urls/zotero_translators/SFU IPinCH.js +0 -946
- scitex/scholar/.legacy/metadata/urls/zotero_translators/SIPRI.js +0 -256
- scitex/scholar/.legacy/metadata/urls/zotero_translators/SIRS Knowledge Source.js +0 -546
- scitex/scholar/.legacy/metadata/urls/zotero_translators/SLUB Dresden.js +0 -300
- scitex/scholar/.legacy/metadata/urls/zotero_translators/SORA.js +0 -340
- scitex/scholar/.legacy/metadata/urls/zotero_translators/SSOAR.js +0 -399
- scitex/scholar/.legacy/metadata/urls/zotero_translators/SSRN.js +0 -235
- scitex/scholar/.legacy/metadata/urls/zotero_translators/SVT Nyheter.js +0 -381
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Sacramento Bee.js +0 -274
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Safari Books Online.js +0 -391
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Scholars Portal Journals.js +0 -220
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Scholia.js +0 -189
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Schweizer Radio und Fernsehen SRF.js +0 -152
- scitex/scholar/.legacy/metadata/urls/zotero_translators/SciELO.js +0 -440
- scitex/scholar/.legacy/metadata/urls/zotero_translators/ScienceDirect.js +0 -1304
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Scopus.js +0 -418
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Semantic Scholar.js +0 -513
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Silverchair.js +0 -886
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Slate.js +0 -228
- scitex/scholar/.legacy/metadata/urls/zotero_translators/SlideShare.js +0 -112
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Springer Link.js +0 -696
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Stack Exchange.js +0 -134
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Standard Ebooks.js +0 -198
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Stanford Encyclopedia of Philosophy.js +0 -285
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Stanford University Press.js +0 -343
- scitex/scholar/.legacy/metadata/urls/zotero_translators/State Records Office of Western Australia.js +0 -439
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Stitcher.js +0 -141
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Store norske leksikon.js +0 -291
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Stuff.co.nz.js +0 -446
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Substack.js +0 -237
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Sud Ouest.js +0 -181
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Sueddeutsche.de.js +0 -205
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Summon 2.js +0 -117
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Superlib.js +0 -647
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Svenska Dagbladet.js +0 -274
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Sveriges radio.js +0 -416
- scitex/scholar/.legacy/metadata/urls/zotero_translators/TEI.js +0 -648
- scitex/scholar/.legacy/metadata/urls/zotero_translators/TV by the Numbers.js +0 -194
- scitex/scholar/.legacy/metadata/urls/zotero_translators/TVNZ.js +0 -165
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Tagesspiegel.js +0 -249
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Talis Aspire.js +0 -316
- scitex/scholar/.legacy/metadata/urls/zotero_translators/TalisPrism.js +0 -445
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Tatknigafund.js +0 -174
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Tatpressa.ru.js +0 -121
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Taylor & Francis eBooks.js +0 -334
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Taylor and Francis+NEJM.js +0 -813
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Tesis Doctorals en Xarxa.js +0 -233
- scitex/scholar/.legacy/metadata/urls/zotero_translators/The Art Newspaper.js +0 -268
- scitex/scholar/.legacy/metadata/urls/zotero_translators/The Atlantic.js +0 -535
- scitex/scholar/.legacy/metadata/urls/zotero_translators/The Boston Globe.js +0 -285
- scitex/scholar/.legacy/metadata/urls/zotero_translators/The Chronicle of Higher Education.js +0 -308
- scitex/scholar/.legacy/metadata/urls/zotero_translators/The Daily Beast.js +0 -183
- scitex/scholar/.legacy/metadata/urls/zotero_translators/The Economic Times - The Times of India.js +0 -305
- scitex/scholar/.legacy/metadata/urls/zotero_translators/The Economist.js +0 -207
- scitex/scholar/.legacy/metadata/urls/zotero_translators/The Free Dictionary.js +0 -58
- scitex/scholar/.legacy/metadata/urls/zotero_translators/The Globe and Mail.js +0 -241
- scitex/scholar/.legacy/metadata/urls/zotero_translators/The Guardian.js +0 -717
- scitex/scholar/.legacy/metadata/urls/zotero_translators/The Hamilton Spectator.js +0 -129
- scitex/scholar/.legacy/metadata/urls/zotero_translators/The Hindu.js +0 -318
- scitex/scholar/.legacy/metadata/urls/zotero_translators/The Independent.js +0 -184
- scitex/scholar/.legacy/metadata/urls/zotero_translators/The Intercept.js +0 -258
- scitex/scholar/.legacy/metadata/urls/zotero_translators/The Met.js +0 -300
- scitex/scholar/.legacy/metadata/urls/zotero_translators/The Microfinance Gateway.js +0 -174
- scitex/scholar/.legacy/metadata/urls/zotero_translators/The Nation.js +0 -188
- scitex/scholar/.legacy/metadata/urls/zotero_translators/The National Archives (UK).js +0 -242
- scitex/scholar/.legacy/metadata/urls/zotero_translators/The New Republic.js +0 -160
- scitex/scholar/.legacy/metadata/urls/zotero_translators/The New York Review of Books.js +0 -467
- scitex/scholar/.legacy/metadata/urls/zotero_translators/The New Yorker.js +0 -360
- scitex/scholar/.legacy/metadata/urls/zotero_translators/The Open Library.js +0 -220
- scitex/scholar/.legacy/metadata/urls/zotero_translators/The Straits Times.js +0 -528
- scitex/scholar/.legacy/metadata/urls/zotero_translators/The Telegraph.js +0 -337
- scitex/scholar/.legacy/metadata/urls/zotero_translators/The Times and Sunday Times.js +0 -180
- scitex/scholar/.legacy/metadata/urls/zotero_translators/The Times of Israel.js +0 -151
- scitex/scholar/.legacy/metadata/urls/zotero_translators/TheMarker.js +0 -108
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Theory of Computing.js +0 -488
- scitex/scholar/.legacy/metadata/urls/zotero_translators/ThesesFR.js +0 -298
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Thieme.js +0 -326
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Time.com.js +0 -557
- scitex/scholar/.legacy/metadata/urls/zotero_translators/TimesMachine.js +0 -222
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Tony Blair Institute for Global Change.js +0 -195
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Toronto Star.js +0 -331
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Transportation Research Board.js +0 -253
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Treesearch.js +0 -535
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Trove.js +0 -616
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Tumblr.js +0 -179
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Twitter.js +0 -413
- scitex/scholar/.legacy/metadata/urls/zotero_translators/UChicago VuFind.js +0 -907
- scitex/scholar/.legacy/metadata/urls/zotero_translators/UNZ Print Archive.js +0 -276
- scitex/scholar/.legacy/metadata/urls/zotero_translators/UPCommons.js +0 -227
- scitex/scholar/.legacy/metadata/urls/zotero_translators/US National Archives Research Catalog.js +0 -275
- scitex/scholar/.legacy/metadata/urls/zotero_translators/USENIX.js +0 -151
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Ubiquity Journals.js +0 -228
- scitex/scholar/.legacy/metadata/urls/zotero_translators/University Press Scholarship.js +0 -301
- scitex/scholar/.legacy/metadata/urls/zotero_translators/University of California Press Books.js +0 -403
- scitex/scholar/.legacy/metadata/urls/zotero_translators/University of Chicago Press Books.js +0 -378
- scitex/scholar/.legacy/metadata/urls/zotero_translators/University of Wisconsin-Madison Libraries Catalog.js +0 -298
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Unqualified Dublin Core RDF.js +0 -153
- scitex/scholar/.legacy/metadata/urls/zotero_translators/UpToDate References.js +0 -203
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Vanity Fair.js +0 -242
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Verniana-Jules Verne Studies.js +0 -190
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Verso Books.js +0 -311
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Vice.js +0 -445
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Victoria & Albert Museum.js +0 -277
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Vimeo.js +0 -188
- scitex/scholar/.legacy/metadata/urls/zotero_translators/VoxEU.js +0 -151
- scitex/scholar/.legacy/metadata/urls/zotero_translators/WHO.js +0 -458
- scitex/scholar/.legacy/metadata/urls/zotero_translators/WIPO.js +0 -189
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Wall Street Journal.js +0 -525
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Wanfang Data.js +0 -310
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Washington Monthly.js +0 -195
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Washington Post.js +0 -447
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Web of Science Nextgen.js +0 -715
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Web of Science Tagged.js +0 -1242
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Web of Science.js +0 -228
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Welt Online.js +0 -161
- scitex/scholar/.legacy/metadata/urls/zotero_translators/WestLaw UK.js +0 -190
- scitex/scholar/.legacy/metadata/urls/zotero_translators/WikiLeaks PlusD.js +0 -182
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Wikidata QuickStatements.js +0 -306
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Wikidata.js +0 -911
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Wikimedia Commons.js +0 -285
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Wikipedia Citation Templates.js +0 -432
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Wikipedia.js +0 -385
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Wikisource.js +0 -399
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Wikiwand.js +0 -122
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Wiktionary.js +0 -141
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Wildlife Biology in Practice.js +0 -172
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Wiley Online Library.js +0 -1412
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Wilson Center Digital Archive.js +0 -321
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Winnipeg Free Press.js +0 -204
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Wired.js +0 -249
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Womennews.js +0 -230
- scitex/scholar/.legacy/metadata/urls/zotero_translators/World Digital Library.js +0 -403
- scitex/scholar/.legacy/metadata/urls/zotero_translators/World History Connected.js +0 -185
- scitex/scholar/.legacy/metadata/urls/zotero_translators/World Shakespeare Bibliography Online.js +0 -595
- scitex/scholar/.legacy/metadata/urls/zotero_translators/WorldCat Discovery Service.js +0 -630
- scitex/scholar/.legacy/metadata/urls/zotero_translators/XML ContextObject.js +0 -274
- scitex/scholar/.legacy/metadata/urls/zotero_translators/YPSF.js +0 -224
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Yandex Books.js +0 -265
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Ynet.js +0 -171
- scitex/scholar/.legacy/metadata/urls/zotero_translators/YouTube.js +0 -209
- scitex/scholar/.legacy/metadata/urls/zotero_translators/ZIPonline.js +0 -267
- scitex/scholar/.legacy/metadata/urls/zotero_translators/ZOBODAT.js +0 -341
- scitex/scholar/.legacy/metadata/urls/zotero_translators/Zotero RDF.js +0 -583
- scitex/scholar/.legacy/metadata/urls/zotero_translators/ZoteroBib.js +0 -94
- scitex/scholar/.legacy/metadata/urls/zotero_translators/arXiv.org.js +0 -1099
- scitex/scholar/.legacy/metadata/urls/zotero_translators/artnet.js +0 -207
- scitex/scholar/.legacy/metadata/urls/zotero_translators/beck-online.js +0 -1339
- scitex/scholar/.legacy/metadata/urls/zotero_translators/clinicaltrials.gov.js +0 -331
- scitex/scholar/.legacy/metadata/urls/zotero_translators/dLibra.js +0 -367
- scitex/scholar/.legacy/metadata/urls/zotero_translators/dejure.org.js +0 -242
- scitex/scholar/.legacy/metadata/urls/zotero_translators/deleted.txt +0 -132
- scitex/scholar/.legacy/metadata/urls/zotero_translators/dhistory.js +0 -103
- scitex/scholar/.legacy/metadata/urls/zotero_translators/digibib.net.js +0 -245
- scitex/scholar/.legacy/metadata/urls/zotero_translators/eLibrary.ru.js +0 -867
- scitex/scholar/.legacy/metadata/urls/zotero_translators/eLife.js +0 -462
- scitex/scholar/.legacy/metadata/urls/zotero_translators/eMJA.js +0 -246
- scitex/scholar/.legacy/metadata/urls/zotero_translators/eMedicine.js +0 -123
- scitex/scholar/.legacy/metadata/urls/zotero_translators/ePrint IACR.js +0 -608
- scitex/scholar/.legacy/metadata/urls/zotero_translators/ebrary.js +0 -140
- scitex/scholar/.legacy/metadata/urls/zotero_translators/etatar.ru.js +0 -104
- scitex/scholar/.legacy/metadata/urls/zotero_translators/feb-web.ru.js +0 -167
- scitex/scholar/.legacy/metadata/urls/zotero_translators/fishpond.co.nz.js +0 -224
- scitex/scholar/.legacy/metadata/urls/zotero_translators/fr-online.de.js +0 -209
- scitex/scholar/.legacy/metadata/urls/zotero_translators/govinfo.js +0 -189
- scitex/scholar/.legacy/metadata/urls/zotero_translators/index.d.ts +0 -1646
- scitex/scholar/.legacy/metadata/urls/zotero_translators/informIT database.js +0 -248
- scitex/scholar/.legacy/metadata/urls/zotero_translators/io-port.js +0 -68
- scitex/scholar/.legacy/metadata/urls/zotero_translators/jsconfig.json +0 -10
- scitex/scholar/.legacy/metadata/urls/zotero_translators/jurion.js +0 -377
- scitex/scholar/.legacy/metadata/urls/zotero_translators/mEDRA.js +0 -597
- scitex/scholar/.legacy/metadata/urls/zotero_translators/magazines.russ.ru.js +0 -120
- scitex/scholar/.legacy/metadata/urls/zotero_translators/medes.js +0 -284
- scitex/scholar/.legacy/metadata/urls/zotero_translators/newshub.co.nz.js +0 -206
- scitex/scholar/.legacy/metadata/urls/zotero_translators/newspapers.com.js +0 -335
- scitex/scholar/.legacy/metadata/urls/zotero_translators/openJur.js +0 -161
- scitex/scholar/.legacy/metadata/urls/zotero_translators/package-lock.json +0 -2345
- scitex/scholar/.legacy/metadata/urls/zotero_translators/package.json +0 -24
- scitex/scholar/.legacy/metadata/urls/zotero_translators/reddit.js +0 -275
- scitex/scholar/.legacy/metadata/urls/zotero_translators/sbn.it.js +0 -186
- scitex/scholar/.legacy/metadata/urls/zotero_translators/scinapse.js +0 -273
- scitex/scholar/.legacy/metadata/urls/zotero_translators/semantics Visual Library.js +0 -643
- scitex/scholar/.legacy/metadata/urls/zotero_translators/taz.de.js +0 -200
- scitex/scholar/.legacy/metadata/urls/zotero_translators/unAPI.js +0 -481
- scitex/scholar/.legacy/metadata/urls/zotero_translators/wiso.js +0 -314
- scitex/scholar/.legacy/metadata/urls/zotero_translators/zbMATH.js +0 -278
- scitex/scholar/.legacy/metadata/urls/zotero_translators/zotero.org.js +0 -311
- scitex/scholar/.legacy/search/README.md +0 -205
- scitex/scholar/.legacy/search/_Embedder.py +0 -329
- scitex/scholar/.legacy/search/_SemanticSearch.py +0 -278
- scitex/scholar/.legacy/search/_SemanticSearchEngine.py +0 -452
- scitex/scholar/.legacy/search/_UnifiedSearcher.py +0 -1353
- scitex/scholar/.legacy/search/_VectorDatabase.py +0 -443
- scitex/scholar/.legacy/search/__init__.py +0 -25
- scitex/scholar/.legacy/storage/_EnhancedStorageManager.py +0 -617
- scitex/scholar/.legacy/storage/__init__.py +0 -19
- scitex/scholar/CLAUDE.md +0 -257
- scitex/scholar/TODO.md +0 -174
- scitex/scholar/_mcp_handlers.py +0 -685
- scitex/scholar/_mcp_tool_schemas.py +0 -339
- scitex/scholar/docs/backup/papers-orig.bib +0 -698
- scitex/scholar/docs/backup/papers.bib.zip +0 -0
- scitex/scholar/docs/to_claude/bin/elisp/check_parens.sh +0 -56
- scitex/scholar/docs/to_claude/bin/elisp/elisp-ci/README.md +0 -412
- scitex/scholar/docs/to_claude/bin/elisp/elisp-ci/elisp-ci +0 -622
- scitex/scholar/docs/to_claude/bin/elisp/elisp-ci/elisp-ci-simple +0 -105
- scitex/scholar/docs/to_claude/bin/elisp/find_incorrect_require_provide_statements.sh +0 -113
- scitex/scholar/docs/to_claude/bin/elisp/run_tests_elisp.sh +0 -532
- scitex/scholar/docs/to_claude/bin/elisp/run_tests_elisp_v02.sh +0 -555
- scitex/scholar/docs/to_claude/bin/elisp/sync_elisp_tdd.sh +0 -626
- scitex/scholar/docs/to_claude/bin/general/claude_emacs_server.sh +0 -192
- scitex/scholar/docs/to_claude/bin/general/create_github_release.sh +0 -36
- scitex/scholar/docs/to_claude/bin/general/find_errors.sh +0 -75
- scitex/scholar/docs/to_claude/bin/general/rename.sh +0 -145
- scitex/scholar/docs/to_claude/bin/general/render_mermaid.sh +0 -116
- scitex/scholar/docs/to_claude/bin/general/safe_rm.sh +0 -75
- scitex/scholar/docs/to_claude/bin/general/view_repo.sh +0 -4
- scitex/scholar/docs/to_claude/bin/general/wsl2-buzzer.sh +0 -73
- scitex/scholar/docs/to_claude/bin/python/black_all.sh +0 -41
- scitex/scholar/docs/to_claude/bin/python/run_tests_python_pip_package.sh +0 -291
- scitex/scholar/docs/to_claude/bin/safe_rm.sh +0 -3
- scitex/scholar/docs/to_claude/bin/slurm/README.md +0 -54
- scitex/scholar/docs/to_claude/bin/slurm/login.sh +0 -23
- scitex/scholar/docs/to_claude/bin/slurm/request.sh +0 -62
- scitex/scholar/docs/to_claude/bin/slurm/run.sh +0 -73
- scitex/scholar/docs/to_claude/examples/README.md +0 -9
- scitex/scholar/docs/to_claude/examples/example-elisp-project-emacs-hello-world/ELISP-TEST-REPORT-20250513-012234-48-PASSED-49-TOTAL-97-PERCENT.org +0 -105
- scitex/scholar/docs/to_claude/examples/example-elisp-project-emacs-hello-world/LATEST-ELISP-REPORT.org +0 -105
- scitex/scholar/docs/to_claude/examples/example-elisp-project-emacs-hello-world/README.md +0 -11
- scitex/scholar/docs/to_claude/examples/example-elisp-project-emacs-hello-world/run_tests.sh +0 -652
- scitex/scholar/docs/to_claude/examples/example-elisp-project-emacs-hello-world/tests/test-ehw-core/ELISP-TEST-REPORT-20250512-235622-0-SUCCESS-4-TOTAL-0-PERCENT.org +0 -25
- scitex/scholar/docs/to_claude/examples/example-elisp-project-emacs-hello-world/tests/test-ehw-friends/ELISP-TEST-REPORT-20250512-235622-0-SUCCESS-34-TOTAL-0-PERCENT.org +0 -66
- scitex/scholar/docs/to_claude/examples/example-elisp-project-emacs-hello-world/tests/test-ehw-prep/ELISP-TEST-REPORT-20250512-235622-0-SUCCESS-5-TOTAL-0-PERCENT.org +0 -26
- scitex/scholar/docs/to_claude/examples/example-elisp-project-emacs-hello-world/tests/test-ehw-utils/ELISP-TEST-REPORT-20250512-235622-0-SUCCESS-4-TOTAL-0-PERCENT.org +0 -25
- scitex/scholar/docs/to_claude/examples/example-python-project-scitex/.gitignore +0 -626
- scitex/scholar/docs/to_claude/examples/example-python-project-scitex/README.md +0 -155
- scitex/scholar/docs/to_claude/examples/example-python-project-scitex/config/MNIST.yaml +0 -24
- scitex/scholar/docs/to_claude/examples/example-python-project-scitex/config/PATH.yaml +0 -30
- scitex/scholar/docs/to_claude/examples/example-python-project-scitex/data/.gitkeep +0 -0
- scitex/scholar/docs/to_claude/examples/example-python-project-scitex/scripts/mnist/clf_svm.py +0 -124
- scitex/scholar/docs/to_claude/examples/example-python-project-scitex/scripts/mnist/download.py +0 -165
- scitex/scholar/docs/to_claude/examples/example-python-project-scitex/scripts/mnist/main.sh +0 -26
- scitex/scholar/docs/to_claude/examples/example-python-project-scitex/scripts/mnist/plot_conf_mat.py +0 -86
- scitex/scholar/docs/to_claude/examples/example-python-project-scitex/scripts/mnist/plot_digits.py +0 -118
- scitex/scholar/docs/to_claude/examples/example-python-project-scitex/scripts/mnist/plot_umap_space.py +0 -110
- scitex/scholar/docs/to_claude/guidelines/README.md +0 -9
- scitex/scholar/docs/to_claude/guidelines/USER_PHILOSOPHY/01_DEVELOPMENT_CYCLE.md +0 -47
- scitex/scholar/docs/to_claude/guidelines/USER_PHILOSOPHY/02_NAMING_CONVENSIONS.md +0 -91
- scitex/scholar/docs/to_claude/guidelines/USER_PHILOSOPHY/03_ARCHITECTUAL_AGREEMENT_PROCESS.md +0 -86
- scitex/scholar/docs/to_claude/guidelines/USER_PHILOSOPHY/04_ARCHITECTURE_PREDEFINED.md +0 -77
- scitex/scholar/docs/to_claude/guidelines/USER_PHILOSOPHY/05_PRIORITY_CONFIG.md +0 -22
- scitex/scholar/docs/to_claude/guidelines/USER_PHILOSOPHY/06_MULTIPLE_SPECIAL_AGENTS.md +0 -35
- scitex/scholar/docs/to_claude/guidelines/USER_PHILOSOPHY/07_DEBUGGING_TECHNIQUES.md +0 -153
- scitex/scholar/docs/to_claude/guidelines/command/IMPORTANT-rm.md +0 -69
- scitex/scholar/docs/to_claude/guidelines/command/IMPORTANT-tree.md +0 -162
- scitex/scholar/docs/to_claude/guidelines/elisp/IMPORTANT-ELISP-01-basic.md +0 -65
- scitex/scholar/docs/to_claude/guidelines/elisp/IMPORTANT-ELISP-02-project-structure.md +0 -97
- scitex/scholar/docs/to_claude/guidelines/elisp/IMPORTANT-ELISP-03-file-template.md +0 -70
- scitex/scholar/docs/to_claude/guidelines/elisp/IMPORTANT-ELISP-04-coding-style.md +0 -42
- scitex/scholar/docs/to_claude/guidelines/elisp/IMPORTANT-ELISP-05-testing-guide.md +0 -190
- scitex/scholar/docs/to_claude/guidelines/elisp/IMPORTANT-ELISP-99-example-project.md +0 -15
- scitex/scholar/docs/to_claude/guidelines/elisp/ci.md +0 -650
- scitex/scholar/docs/to_claude/guidelines/elisp/testing-with-docker.md +0 -243
- scitex/scholar/docs/to_claude/guidelines/programming_common/EXAMPLE-README-MODULE-ROOT.md +0 -32
- scitex/scholar/docs/to_claude/guidelines/programming_common/EXAMPLE-README-REPOSITORY-ROOT.md +0 -60
- scitex/scholar/docs/to_claude/guidelines/programming_common/IMPORTANT-art-of-readable-code.md +0 -1317
- scitex/scholar/docs/to_claude/guidelines/programming_common/IMPORTANT-art-of-testing.md +0 -799
- scitex/scholar/docs/to_claude/guidelines/programming_common/IMPORTANT-cleanliness.md +0 -18
- scitex/scholar/docs/to_claude/guidelines/programming_common/IMPORTANT-documentation-performance-claims.md +0 -163
- scitex/scholar/docs/to_claude/guidelines/programming_common/IMPORTANT-general.md +0 -156
- scitex/scholar/docs/to_claude/guidelines/programming_common/IMPORTANT-refactoring.md +0 -32
- scitex/scholar/docs/to_claude/guidelines/programming_common/IMPORTANT-regression-prevention.md +0 -14
- scitex/scholar/docs/to_claude/guidelines/programming_common/IMPORTANT-slurm.md +0 -73
- scitex/scholar/docs/to_claude/guidelines/programming_common/IMPORTANT-start-from-small.md +0 -30
- scitex/scholar/docs/to_claude/guidelines/programming_common/IMPORTANT-test-driven-workflow.md +0 -80
- scitex/scholar/docs/to_claude/guidelines/programming_common/IMPORTANT-version-control.md +0 -47
- scitex/scholar/docs/to_claude/guidelines/programming_common/clean-code.md +0 -305
- scitex/scholar/docs/to_claude/guidelines/programming_common/debugging-message.md +0 -52
- scitex/scholar/docs/to_claude/guidelines/programming_common/do-not-repeat-yourself.md +0 -27
- scitex/scholar/docs/to_claude/guidelines/programming_common/emacs-server.md +0 -39
- scitex/scholar/docs/to_claude/guidelines/programming_common/keep-it-simple-stupid.md +0 -19
- scitex/scholar/docs/to_claude/guidelines/programming_common/renaming-and-cleaning-workflow.md +0 -311
- scitex/scholar/docs/to_claude/guidelines/programming_common/screen.md +0 -32
- scitex/scholar/docs/to_claude/guidelines/project/IMPORTANT-CLAUDE_ID.md +0 -15
- scitex/scholar/docs/to_claude/guidelines/project/IMPORTANT-beyond-control.md +0 -14
- scitex/scholar/docs/to_claude/guidelines/project/IMPORTANT-bug-report.md +0 -43
- scitex/scholar/docs/to_claude/guidelines/project/IMPORTANT-cleanliness.md +0 -162
- scitex/scholar/docs/to_claude/guidelines/project/IMPORTANT-communication.md +0 -13
- scitex/scholar/docs/to_claude/guidelines/project/IMPORTANT-do-not-create-any-new-file-nor-directory-in-project-root.md +0 -9
- scitex/scholar/docs/to_claude/guidelines/project/IMPORTANT-documentation.md +0 -11
- scitex/scholar/docs/to_claude/guidelines/project/IMPORTANT-feature-request.md +0 -33
- scitex/scholar/docs/to_claude/guidelines/project/IMPORTANT-general-multi-agent-coordination.md +0 -311
- scitex/scholar/docs/to_claude/guidelines/project/IMPORTANT-multi-agent-protocol.md +0 -97
- scitex/scholar/docs/to_claude/guidelines/project/IMPORTANT-project-management-bulletin-board.md +0 -48
- scitex/scholar/docs/to_claude/guidelines/project/IMPORTANT-project-management-markdown.md +0 -156
- scitex/scholar/docs/to_claude/guidelines/project/IMPORTANT-project-management-org.org +0 -161
- scitex/scholar/docs/to_claude/guidelines/project/IMPORTANT-tools.md +0 -10
- scitex/scholar/docs/to_claude/guidelines/project/IMPORTANT-understand-message-in-filename.md +0 -12
- scitex/scholar/docs/to_claude/guidelines/project/general.md +0 -7
- scitex/scholar/docs/to_claude/guidelines/project/report.md +0 -50
- scitex/scholar/docs/to_claude/guidelines/project/timeline-gantt-chart.md +0 -49
- scitex/scholar/docs/to_claude/guidelines/python/CHECKLIST.md +0 -51
- scitex/scholar/docs/to_claude/guidelines/python/HOW-TO-DEBUG-with-MULTIPLE_AGENTS.md +0 -191
- scitex/scholar/docs/to_claude/guidelines/python/Machine-Learning.md +0 -15
- scitex/scholar/docs/to_claude/guidelines/python/NOT-FULL-PYTEST-BUT-PARTIAL-PYTEST.md +0 -21
- scitex/scholar/docs/to_claude/guidelines/python/django.md +0 -217
- scitex/scholar/docs/to_claude/guidelines/python/env.md +0 -10
- scitex/scholar/docs/to_claude/guidelines/python/general.md +0 -55
- scitex/scholar/docs/to_claude/guidelines/python/official/cipdb-README.md +0 -219
- scitex/scholar/docs/to_claude/guidelines/python/official/fastmcp-README.md +0 -442
- scitex/scholar/docs/to_claude/guidelines/python/official/fastmcp-TESTING.md +0 -146
- scitex/scholar/docs/to_claude/guidelines/python/official/icecream-README.md +0 -433
- scitex/scholar/docs/to_claude/guidelines/python/official/priority_config-README.md +0 -126
- scitex/scholar/docs/to_claude/guidelines/python/scitex/01-basic.md +0 -42
- scitex/scholar/docs/to_claude/guidelines/python/scitex/02-file-template.md +0 -132
- scitex/scholar/docs/to_claude/guidelines/python/scitex/03-configuration.md +0 -53
- scitex/scholar/docs/to_claude/guidelines/python/scitex/04-coding-style.md +0 -126
- scitex/scholar/docs/to_claude/guidelines/python/scitex/05-testing-guide.md +0 -56
- scitex/scholar/docs/to_claude/guidelines/python/scitex/06-examples-guide.md +0 -42
- scitex/scholar/docs/to_claude/guidelines/python/scitex/11-gen-module.md +0 -15
- scitex/scholar/docs/to_claude/guidelines/python/scitex/11-session-module.md +0 -24
- scitex/scholar/docs/to_claude/guidelines/python/scitex/12-io-module.md +0 -112
- scitex/scholar/docs/to_claude/guidelines/python/scitex/13-plt-module.md +0 -101
- scitex/scholar/docs/to_claude/guidelines/python/scitex/14-dsp-module.md +0 -78
- scitex/scholar/docs/to_claude/guidelines/python/scitex/15-pd-module.md +0 -24
- scitex/scholar/docs/to_claude/guidelines/python/scitex/16-stats-module.md +0 -79
- scitex/scholar/docs/to_claude/guidelines/python/scitex/17-other-modules.md +0 -23
- scitex/scholar/docs/to_claude/guidelines/python/scitex/17-str-module.md +0 -24
- scitex/scholar/docs/to_claude/guidelines/python/scitex/18-directory-structure-for-scientific-work.md +0 -48
- scitex/scholar/docs/to_claude/guidelines/python/scitex/19-directory-structure-for-pip-package.md +0 -234
- scitex/scholar/docs/to_claude/guidelines/python/scitex/99-example-project.md +0 -19
- scitex/scholar/docs/to_claude/guidelines/python/zen_of_python.md +0 -82
- scitex/scholar/docs/to_claude/guidelines/science/IMPORTANT-general.md +0 -16
- scitex/scholar/docs/to_claude/guidelines/science/IMPORTANT-scientific-attitude.md +0 -25
- scitex/scholar/docs/to_claude/guidelines/science/scientific-writing-abstract.md +0 -93
- scitex/scholar/docs/to_claude/guidelines/science/scientific-writing-discussion.md +0 -116
- scitex/scholar/docs/to_claude/guidelines/science/scientific-writing-general-1.md +0 -157
- scitex/scholar/docs/to_claude/guidelines/science/scientific-writing-general-2.md +0 -83
- scitex/scholar/docs/to_claude/guidelines/science/scientific-writing-introduction.md +0 -123
- scitex/scholar/docs/to_claude/guidelines/science/scientific-writing-methods.md +0 -88
- scitex/scholar/docs/to_claude/guidelines/shell/IMPORTANT-general.md +0 -196
- scitex/scholar/examples/SUGGESTIONS.md +0 -865
- scitex/scholar/examples/dev.py +0 -38
- scitex/scholar/library/neurovista/info/bibtex/seizure_prediction_enriched.bib +0 -1092
- scitex/stats/_mcp_handlers.py +0 -1191
- scitex/stats/_mcp_tool_schemas.py +0 -384
- scitex/template/.legacy/_clone_project.py +0 -267
- scitex/template/_mcp_handlers.py +0 -259
- scitex/template/_mcp_tool_schemas.py +0 -112
- scitex/writer/.legacy/Writer_v01-refactored.py +0 -189
- scitex/writer/.legacy/_compile.py +0 -342
- scitex/writer/_compile_async.py +0 -126
- scitex/writer/_validate_tree_structures.py +0 -197
- scitex/writer/dataclasses/config/_WriterConfig.py +0 -175
- scitex/writer/dataclasses/contents/_ManuscriptContents.py +0 -236
- scitex/writer/dataclasses/core/_Document.py +0 -146
- scitex/writer/dataclasses/core/_DocumentSection.py +0 -546
- scitex/writer/dataclasses/results/_CompilationResult.py +0 -165
- scitex/writer/dataclasses/results/_LaTeXIssue.py +0 -102
- scitex/writer/dataclasses/tree/MINIMUM_FILES.md +0 -121
- scitex/writer/tests/__init__.py +0 -3
- scitex/writer/tests/test_diff_between.py +0 -451
- scitex/writer/tests/test_document_section.py +0 -311
- scitex/writer/tests/test_document_workflow.py +0 -393
- scitex/writer/tests/test_writer.py +0 -361
- scitex/writer/tests/test_writer_integration.py +0 -303
- scitex-2.13.0.dist-info/METADATA +0 -1231
- scitex-2.13.0.dist-info/RECORD +0 -3402
- scitex-2.13.0.dist-info/entry_points.txt +0 -11
- /scitex/scholar/docs/{SUMMARY.md → 00_SUMMARY.md} +0 -0
- /scitex/scholar/docs/{STORAGE_ARCHITECTURE.md → 01_STORAGE_ARCHITECTURE.md} +0 -0
- /scitex/scholar/docs/{PIPELINE_ORGANIZATION.md → 02_PIPELINE_ORGANIZATION.md} +0 -0
- /scitex/scholar/docs/{PIPELINE_IMPLEMENTATION_PLAN.md → 03_PIPELINE_IMPLEMENTATION_PLAN.md} +0 -0
- /scitex/scholar/docs/{PIPELINE_IMPLEMENTATION_COMPLETE.md → 04_PIPELINE_IMPLEMENTATION_COMPLETE.md} +0 -0
- /scitex/scholar/docs/{DETAILS_FOR_DEVELOPERS.md → 05_DETAILS_FOR_DEVELOPERS.md} +0 -0
- /scitex/scholar/docs/{IMPACT_FACTOR_CITATION_INTEGRATION.md → 06_IMPACT_FACTOR_CITATION_INTEGRATION.md} +0 -0
- /scitex/writer/{dataclasses → _dataclasses}/__init__.py +0 -0
- /scitex/writer/{dataclasses → _dataclasses}/config/_CONSTANTS.py +0 -0
- /scitex/writer/{dataclasses → _dataclasses}/config/__init__.py +0 -0
- /scitex/writer/{dataclasses → _dataclasses}/contents/_RevisionContents.py +0 -0
- /scitex/writer/{dataclasses → _dataclasses}/contents/_SupplementaryContents.py +0 -0
- /scitex/writer/{dataclasses → _dataclasses}/contents/__init__.py +0 -0
- /scitex/writer/{dataclasses → _dataclasses}/core/__init__.py +0 -0
- /scitex/writer/{dataclasses → _dataclasses}/results/_SaveSectionsResponse.py +0 -0
- /scitex/writer/{dataclasses → _dataclasses}/results/_SectionReadResponse.py +0 -0
- /scitex/writer/{dataclasses → _dataclasses}/results/__init__.py +0 -0
- /scitex/writer/{dataclasses → _dataclasses}/tree/_ConfigTree.py +0 -0
- /scitex/writer/{dataclasses → _dataclasses}/tree/_ManuscriptTree.py +0 -0
- /scitex/writer/{dataclasses → _dataclasses}/tree/_RevisionTree.py +0 -0
- /scitex/writer/{dataclasses → _dataclasses}/tree/_ScriptsTree.py +0 -0
- /scitex/writer/{dataclasses → _dataclasses}/tree/_SharedTree.py +0 -0
- /scitex/writer/{dataclasses → _dataclasses}/tree/_SupplementaryTree.py +0 -0
- /scitex/writer/{dataclasses → _dataclasses}/tree/__init__.py +0 -0
- {scitex-2.13.0.dist-info → scitex-2.15.1.dist-info}/WHEEL +0 -0
- {scitex-2.13.0.dist-info → scitex-2.15.1.dist-info}/licenses/LICENSE +0 -0
scitex/scholar/core/Scholar.py
CHANGED
|
@@ -1,16 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
#
|
|
3
|
-
#
|
|
4
|
-
# File: /home/ywatanabe/proj/scitex_repo/src/scitex/scholar/core/Scholar.py
|
|
5
|
-
# ----------------------------------------
|
|
6
|
-
from __future__ import annotations
|
|
7
|
-
import os
|
|
8
|
-
|
|
9
|
-
__FILE__ = "./src/scitex/scholar/core/Scholar.py"
|
|
10
|
-
__DIR__ = os.path.dirname(__FILE__)
|
|
11
|
-
# ----------------------------------------
|
|
12
|
-
|
|
13
|
-
__FILE__ = __file__
|
|
2
|
+
# Timestamp: "2026-01-24 (ywatanabe)"
|
|
3
|
+
# File: /home/ywatanabe/proj/scitex-python/src/scitex/scholar/core/Scholar.py
|
|
14
4
|
|
|
15
5
|
"""
|
|
16
6
|
Unified Scholar class for scientific literature management.
|
|
@@ -22,47 +12,42 @@ This is the main entry point for all scholar functionality, providing:
|
|
|
22
12
|
- Progressive disclosure of advanced features
|
|
23
13
|
"""
|
|
24
14
|
|
|
25
|
-
import
|
|
26
|
-
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
27
17
|
from pathlib import Path
|
|
28
|
-
from typing import
|
|
29
|
-
from typing import Dict
|
|
30
|
-
from typing import List
|
|
31
|
-
from typing import Optional
|
|
32
|
-
from typing import Union
|
|
33
|
-
from copy import deepcopy
|
|
34
|
-
from scitex import logging
|
|
35
|
-
import shutil
|
|
18
|
+
from typing import Optional, Union
|
|
36
19
|
|
|
37
|
-
|
|
38
|
-
from scitex.logging import ScholarError
|
|
20
|
+
from scitex import logging
|
|
39
21
|
from scitex.scholar.config import ScholarConfig
|
|
40
22
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
23
|
+
from ._mixins import (
|
|
24
|
+
EnricherMixin,
|
|
25
|
+
LibraryHandlerMixin,
|
|
26
|
+
LoaderMixin,
|
|
27
|
+
PDFDownloadMixin,
|
|
28
|
+
PipelineMixin,
|
|
29
|
+
ProjectHandlerMixin,
|
|
30
|
+
SaverMixin,
|
|
31
|
+
SearchMixin,
|
|
32
|
+
ServiceMixin,
|
|
33
|
+
URLFindingMixin,
|
|
50
34
|
)
|
|
51
|
-
from scitex.scholar.auth.core.AuthenticationGateway import (
|
|
52
|
-
AuthenticationGateway,
|
|
53
|
-
)
|
|
54
|
-
from scitex.scholar.url_finder.ScholarURLFinder import ScholarURLFinder
|
|
55
|
-
|
|
56
|
-
import asyncio
|
|
57
|
-
import nest_asyncio
|
|
58
|
-
from scitex.scholar.impact_factor.ImpactFactorEngine import ImpactFactorEngine
|
|
59
|
-
|
|
60
|
-
from .Papers import Papers
|
|
61
35
|
|
|
62
36
|
logger = logging.getLogger(__name__)
|
|
63
37
|
|
|
64
38
|
|
|
65
|
-
class Scholar
|
|
39
|
+
class Scholar(
|
|
40
|
+
EnricherMixin,
|
|
41
|
+
URLFindingMixin,
|
|
42
|
+
PDFDownloadMixin,
|
|
43
|
+
LoaderMixin,
|
|
44
|
+
SearchMixin,
|
|
45
|
+
SaverMixin,
|
|
46
|
+
ProjectHandlerMixin,
|
|
47
|
+
LibraryHandlerMixin,
|
|
48
|
+
PipelineMixin,
|
|
49
|
+
ServiceMixin,
|
|
50
|
+
):
|
|
66
51
|
"""
|
|
67
52
|
Main interface for SciTeX Scholar - scientific literature management made simple.
|
|
68
53
|
|
|
@@ -107,8 +92,7 @@ class Scholar:
|
|
|
107
92
|
project_description: Optional[str] = None,
|
|
108
93
|
browser_mode: Optional[str] = None,
|
|
109
94
|
):
|
|
110
|
-
"""
|
|
111
|
-
Initialize Scholar with configuration.
|
|
95
|
+
"""Initialize Scholar with configuration.
|
|
112
96
|
|
|
113
97
|
Args:
|
|
114
98
|
config: Can be:
|
|
@@ -119,30 +103,16 @@ class Scholar:
|
|
|
119
103
|
project_description: Optional description for the project
|
|
120
104
|
browser_mode: Browser mode ('stealth', 'interactive', 'manual')
|
|
121
105
|
"""
|
|
122
|
-
|
|
123
106
|
self.config = self._init_config(config)
|
|
124
|
-
|
|
125
|
-
# Store browser mode for later use
|
|
126
107
|
self.browser_mode = browser_mode or "stealth"
|
|
127
108
|
|
|
128
|
-
# Set project and workspace
|
|
129
109
|
self.project = self.config.resolve("project", project, "default")
|
|
130
110
|
self.workspace_dir = self.config.path_manager.get_workspace_dir()
|
|
131
111
|
|
|
132
|
-
# Auto-create project directory if it doesn't exist
|
|
133
112
|
if project:
|
|
134
113
|
self._ensure_project_exists(project, project_description)
|
|
135
114
|
|
|
136
|
-
|
|
137
|
-
# Use mangled names for private properties
|
|
138
|
-
self._Scholar__scholar_engine = None # Replaces DOIResolver and LibraryEnricher
|
|
139
|
-
self._Scholar__auth_manager = None
|
|
140
|
-
self._Scholar__browser_manager = None
|
|
141
|
-
self._Scholar__library_manager = None
|
|
142
|
-
self._Scholar__library = None # ScholarLibrary for high-level operations
|
|
143
|
-
|
|
144
|
-
# Show user-friendly initialization message with library location
|
|
145
|
-
library_path = self.config.get_library_project_dir()
|
|
115
|
+
library_path = self.config.get_library_project_dir(self.project)
|
|
146
116
|
if project:
|
|
147
117
|
project_path = library_path / project
|
|
148
118
|
logger.info(
|
|
@@ -151,1694 +121,100 @@ class Scholar:
|
|
|
151
121
|
else:
|
|
152
122
|
logger.info(f"{self.name}: Scholar initialized (library: {library_path})")
|
|
153
123
|
|
|
154
|
-
# ----------------------------------------
|
|
155
|
-
# Enrichers
|
|
156
|
-
# ----------------------------------------
|
|
157
|
-
async def enrich_papers_async(self, papers: Papers) -> Papers:
|
|
158
|
-
"""Async version of enrich_papers for use in async contexts.
|
|
159
|
-
|
|
160
|
-
Args:
|
|
161
|
-
papers: Papers collection to enrich.
|
|
162
|
-
|
|
163
|
-
Returns:
|
|
164
|
-
Enriched Papers collection
|
|
165
|
-
"""
|
|
166
|
-
enriched_list = []
|
|
167
|
-
|
|
168
|
-
for paper in papers:
|
|
169
|
-
try:
|
|
170
|
-
# Use ScholarEngine to search and enrich
|
|
171
|
-
results = await self._scholar_engine.search_async(
|
|
172
|
-
title=paper.metadata.basic.title,
|
|
173
|
-
year=paper.metadata.basic.year,
|
|
174
|
-
authors=(
|
|
175
|
-
paper.metadata.basic.authors[0]
|
|
176
|
-
if paper.metadata.basic.authors
|
|
177
|
-
else None
|
|
178
|
-
),
|
|
179
|
-
)
|
|
180
|
-
|
|
181
|
-
# Create a copy to avoid modifying original
|
|
182
|
-
enriched_paper = self._merge_enrichment_data(paper, results)
|
|
183
|
-
enriched_list.append(enriched_paper)
|
|
184
|
-
title = paper.metadata.basic.title or "No title"
|
|
185
|
-
logger.info(f"{self.name}: Enriched: {title[:50]}...")
|
|
186
|
-
|
|
187
|
-
except Exception as e:
|
|
188
|
-
title = paper.metadata.basic.title or "No title"
|
|
189
|
-
logger.warning(
|
|
190
|
-
f"{self.name}: Failed to enrich paper '{title[:50]}...': {e}"
|
|
191
|
-
)
|
|
192
|
-
enriched_list.append(paper) # Keep original if enrichment fails
|
|
193
|
-
|
|
194
|
-
enriched_papers = Papers(enriched_list, project=self.project)
|
|
195
|
-
|
|
196
|
-
# Add impact factors as post-processing step
|
|
197
|
-
if self.config.resolve("enrich_impact_factors", None, True):
|
|
198
|
-
enriched_papers = self._enrich_impact_factors(enriched_papers)
|
|
199
|
-
|
|
200
|
-
return enriched_papers
|
|
201
|
-
|
|
202
|
-
def enrich_papers(
|
|
203
|
-
self, papers: Optional[Papers] = None
|
|
204
|
-
) -> Union[Papers, Dict[str, int]]:
|
|
205
|
-
"""Enrich papers with metadata from multiple sources.
|
|
206
|
-
|
|
207
|
-
Args:
|
|
208
|
-
papers: Papers collection to enrich. If None, enriches all papers in current project.
|
|
209
|
-
|
|
210
|
-
Returns:
|
|
211
|
-
- If papers provided: Returns enriched Papers collection
|
|
212
|
-
- If no papers: Returns dict with enrichment statistics for project
|
|
213
|
-
"""
|
|
214
|
-
|
|
215
|
-
# If no papers provided, enrich entire project
|
|
216
|
-
if papers is None:
|
|
217
|
-
return self._enrich_current_project()
|
|
218
|
-
|
|
219
|
-
# Enrich the provided papers collection
|
|
220
|
-
enriched_list = []
|
|
221
|
-
|
|
222
|
-
nest_asyncio.apply() # Allow nested event loops
|
|
223
|
-
|
|
224
|
-
for paper in papers:
|
|
225
|
-
try:
|
|
226
|
-
# Use ScholarEngine to search and enrich
|
|
227
|
-
results = asyncio.run(
|
|
228
|
-
self._scholar_engine.search_async(
|
|
229
|
-
title=paper.metadata.basic.title,
|
|
230
|
-
year=paper.metadata.basic.year,
|
|
231
|
-
authors=(
|
|
232
|
-
paper.metadata.basic.authors[0]
|
|
233
|
-
if paper.metadata.basic.authors
|
|
234
|
-
else None
|
|
235
|
-
),
|
|
236
|
-
)
|
|
237
|
-
)
|
|
238
|
-
|
|
239
|
-
# Create a copy to avoid modifying original
|
|
240
|
-
enriched_paper = self._merge_enrichment_data(paper, results)
|
|
241
|
-
enriched_list.append(enriched_paper)
|
|
242
|
-
title = paper.metadata.basic.title or "No title"
|
|
243
|
-
logger.info(f"{self.name}: Enriched: {title[:50]}...")
|
|
244
|
-
|
|
245
|
-
except Exception as e:
|
|
246
|
-
title = paper.metadata.basic.title or "No title"
|
|
247
|
-
logger.warning(
|
|
248
|
-
f"{self.name}: Failed to enrich paper '{title[:50]}...': {e}"
|
|
249
|
-
)
|
|
250
|
-
enriched_list.append(paper) # Keep original if enrichment fails
|
|
251
|
-
|
|
252
|
-
enriched_papers = Papers(enriched_list, project=self.project)
|
|
253
|
-
|
|
254
|
-
# Add impact factors as post-processing step
|
|
255
|
-
if self.config.resolve("enrich_impact_factors", None, True):
|
|
256
|
-
enriched_papers = self._enrich_impact_factors(enriched_papers)
|
|
257
|
-
|
|
258
|
-
return enriched_papers
|
|
259
|
-
|
|
260
|
-
def _enrich_impact_factors(self, papers: "Papers") -> "Papers":
|
|
261
|
-
"""Add journal impact factors to papers.
|
|
262
|
-
|
|
263
|
-
Args:
|
|
264
|
-
papers: Papers collection to enrich with impact factors
|
|
265
|
-
|
|
266
|
-
Returns:
|
|
267
|
-
Papers collection with impact factors added where available
|
|
268
|
-
"""
|
|
269
|
-
try:
|
|
270
|
-
# Try JCR database first (fast)
|
|
271
|
-
jcr_engine = ImpactFactorEngine()
|
|
272
|
-
papers = jcr_engine.enrich_papers(papers)
|
|
273
|
-
return papers
|
|
274
|
-
except Exception as e:
|
|
275
|
-
logger.debug(
|
|
276
|
-
f"{self.name}: JCR engine unavailable: {e}, falling back to calculation method"
|
|
277
|
-
)
|
|
278
|
-
|
|
279
|
-
return papers
|
|
280
|
-
|
|
281
|
-
def _merge_enrichment_data(self, paper: "Paper", results: Dict) -> "Paper":
|
|
282
|
-
"""Merge enrichment results into paper object.
|
|
283
|
-
|
|
284
|
-
Creates a new Paper object with merged data to avoid modifying the original.
|
|
285
|
-
"""
|
|
286
|
-
# Import here to avoid circular dependency
|
|
287
|
-
|
|
288
|
-
enriched = deepcopy(paper)
|
|
289
|
-
|
|
290
|
-
# Results from ScholarEngine is already combined metadata, not individual engine results
|
|
291
|
-
if not results:
|
|
292
|
-
return enriched
|
|
293
|
-
|
|
294
|
-
# Extract from the combined metadata structure
|
|
295
|
-
# ID section
|
|
296
|
-
if "id" in results:
|
|
297
|
-
if results["id"].get("doi") and not enriched.metadata.id.doi:
|
|
298
|
-
enriched.metadata.set_doi(results["id"]["doi"])
|
|
299
|
-
if results["id"].get("pmid") and not enriched.metadata.id.pmid:
|
|
300
|
-
enriched.metadata.id.pmid = results["id"]["pmid"]
|
|
301
|
-
if results["id"].get("arxiv_id") and not enriched.metadata.id.arxiv_id:
|
|
302
|
-
enriched.metadata.id.arxiv_id = results["id"]["arxiv_id"]
|
|
303
|
-
# Note: corpus_id, semantic_id, ieee_id are in results but not in Paper dataclass
|
|
304
|
-
|
|
305
|
-
# Basic metadata section
|
|
306
|
-
if "basic" in results:
|
|
307
|
-
# Always update abstract if found (key enrichment goal)
|
|
308
|
-
if results["basic"].get("abstract"):
|
|
309
|
-
enriched.metadata.basic.abstract = results["basic"]["abstract"]
|
|
310
|
-
|
|
311
|
-
# Update title if more complete
|
|
312
|
-
if results["basic"].get("title"):
|
|
313
|
-
new_title = results["basic"]["title"]
|
|
314
|
-
current_title = enriched.metadata.basic.title or ""
|
|
315
|
-
if not current_title or len(new_title) > len(current_title):
|
|
316
|
-
enriched.metadata.basic.title = new_title
|
|
317
|
-
|
|
318
|
-
# Update authors if found
|
|
319
|
-
if results["basic"].get("authors") and not enriched.metadata.basic.authors:
|
|
320
|
-
enriched.metadata.basic.authors = results["basic"]["authors"]
|
|
321
|
-
|
|
322
|
-
# Update year if found
|
|
323
|
-
if results["basic"].get("year") and not enriched.metadata.basic.year:
|
|
324
|
-
enriched.metadata.basic.year = results["basic"]["year"]
|
|
325
|
-
|
|
326
|
-
# Update keywords if found
|
|
327
|
-
if (
|
|
328
|
-
results["basic"].get("keywords")
|
|
329
|
-
and not enriched.metadata.basic.keywords
|
|
330
|
-
):
|
|
331
|
-
enriched.metadata.basic.keywords = results["basic"]["keywords"]
|
|
332
|
-
|
|
333
|
-
# Publication metadata
|
|
334
|
-
if "publication" in results:
|
|
335
|
-
if (
|
|
336
|
-
results["publication"].get("journal")
|
|
337
|
-
and not enriched.metadata.publication.journal
|
|
338
|
-
):
|
|
339
|
-
enriched.metadata.publication.journal = results["publication"][
|
|
340
|
-
"journal"
|
|
341
|
-
]
|
|
342
|
-
if (
|
|
343
|
-
results["publication"].get("publisher")
|
|
344
|
-
and not enriched.metadata.publication.publisher
|
|
345
|
-
):
|
|
346
|
-
enriched.metadata.publication.publisher = results["publication"][
|
|
347
|
-
"publisher"
|
|
348
|
-
]
|
|
349
|
-
if (
|
|
350
|
-
results["publication"].get("volume")
|
|
351
|
-
and not enriched.metadata.publication.volume
|
|
352
|
-
):
|
|
353
|
-
enriched.metadata.publication.volume = results["publication"]["volume"]
|
|
354
|
-
if (
|
|
355
|
-
results["publication"].get("issue")
|
|
356
|
-
and not enriched.metadata.publication.issue
|
|
357
|
-
):
|
|
358
|
-
enriched.metadata.publication.issue = results["publication"]["issue"]
|
|
359
|
-
if (
|
|
360
|
-
results["publication"].get("pages")
|
|
361
|
-
and not enriched.metadata.publication.pages
|
|
362
|
-
):
|
|
363
|
-
enriched.metadata.publication.pages = results["publication"]["pages"]
|
|
364
|
-
|
|
365
|
-
# Citation metadata
|
|
366
|
-
if "citation_count" in results:
|
|
367
|
-
# Try both "count" and "total" fields
|
|
368
|
-
count = results["citation_count"].get("count") or results[
|
|
369
|
-
"citation_count"
|
|
370
|
-
].get("total")
|
|
371
|
-
if count:
|
|
372
|
-
# Always take the maximum citation count
|
|
373
|
-
current_count = enriched.metadata.citation_count.total or 0
|
|
374
|
-
if not current_count or count > current_count:
|
|
375
|
-
enriched.metadata.citation_count.total = count
|
|
376
|
-
# Note: influential_citation_count is in results but not in Paper dataclass
|
|
377
|
-
|
|
378
|
-
# URL metadata
|
|
379
|
-
if "url" in results:
|
|
380
|
-
if results["url"].get("pdf"):
|
|
381
|
-
# Check if this PDF is not already in the list
|
|
382
|
-
pdf_url = results["url"]["pdf"]
|
|
383
|
-
if not any(p.get("url") == pdf_url for p in enriched.metadata.url.pdfs):
|
|
384
|
-
enriched.metadata.url.pdfs.append(
|
|
385
|
-
{"url": pdf_url, "source": "enrichment"}
|
|
386
|
-
)
|
|
387
|
-
if results["url"].get("url") and not enriched.metadata.url.publisher:
|
|
388
|
-
enriched.metadata.url.publisher = results["url"]["url"]
|
|
389
|
-
|
|
390
|
-
# Note: Metrics section (journal_impact_factor, h_index) not stored in Paper dataclass
|
|
391
|
-
|
|
392
|
-
return enriched
|
|
393
|
-
|
|
394
|
-
def _enrich_current_project(self) -> Dict[str, int]:
|
|
395
|
-
"""Enrich all papers in the current project.
|
|
396
|
-
|
|
397
|
-
Returns:
|
|
398
|
-
Dictionary with enrichment statistics
|
|
399
|
-
"""
|
|
400
|
-
if not self.project:
|
|
401
|
-
raise ValueError(
|
|
402
|
-
"No project specified. Use Scholar(project='name') or provide papers to enrich()."
|
|
403
|
-
)
|
|
404
|
-
|
|
405
|
-
# Load papers from project library
|
|
406
|
-
papers = self.load_project(self.project)
|
|
407
|
-
logger.info(
|
|
408
|
-
f"{self.name}: Enriching {len(papers)} papers in project '{self.project}'"
|
|
409
|
-
)
|
|
410
|
-
|
|
411
|
-
# Enrich the papers
|
|
412
|
-
enriched_papers = self.enrich_papers(papers)
|
|
413
|
-
|
|
414
|
-
# Count successes
|
|
415
|
-
enriched_count = sum(
|
|
416
|
-
1
|
|
417
|
-
for i, p in enumerate(enriched_papers)
|
|
418
|
-
if p.abstract and not papers[i].abstract # Check if abstract was added
|
|
419
|
-
)
|
|
420
|
-
|
|
421
|
-
# Save enriched papers back to library
|
|
422
|
-
saved_ids = self.save_papers_to_library(enriched_papers)
|
|
423
|
-
|
|
424
|
-
return {
|
|
425
|
-
"enriched": enriched_count,
|
|
426
|
-
"failed": len(papers) - enriched_count,
|
|
427
|
-
"total": len(papers),
|
|
428
|
-
"saved": len(saved_ids),
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
# ----------------------------------------
|
|
432
|
-
# URL Finding (Orchestration)
|
|
433
|
-
# ----------------------------------------
|
|
434
|
-
async def _find_urls_for_doi_async(self, doi: str, context) -> Dict[str, Any]:
|
|
435
|
-
"""Find all URLs for a DOI (orchestration layer).
|
|
436
|
-
|
|
437
|
-
Workflow:
|
|
438
|
-
DOI → Publisher URL → PDF URLs → OpenURL (fallback)
|
|
439
|
-
|
|
440
|
-
Args:
|
|
441
|
-
doi: DOI string
|
|
442
|
-
context: Authenticated browser context
|
|
443
|
-
|
|
444
|
-
Returns:
|
|
445
|
-
Dictionary with URL information: {
|
|
446
|
-
"url_doi": "https://doi.org/...",
|
|
447
|
-
"url_publisher": "https://publisher.com/...",
|
|
448
|
-
"urls_pdf": [{"url": "...", "source": "zotero_translator"}],
|
|
449
|
-
"url_openurl_resolved": "..." (if fallback used)
|
|
450
|
-
}
|
|
451
|
-
"""
|
|
452
|
-
from scitex.scholar.auth.gateway import (
|
|
453
|
-
normalize_doi_as_http,
|
|
454
|
-
resolve_publisher_url_by_navigating_to_doi_page,
|
|
455
|
-
OpenURLResolver,
|
|
456
|
-
)
|
|
457
|
-
|
|
458
|
-
# Initialize result
|
|
459
|
-
urls = {"url_doi": normalize_doi_as_http(doi)}
|
|
460
|
-
|
|
461
|
-
# Step 1: Resolve publisher URL
|
|
462
|
-
page = await context.new_page()
|
|
463
|
-
try:
|
|
464
|
-
url_publisher = await resolve_publisher_url_by_navigating_to_doi_page(
|
|
465
|
-
doi, page
|
|
466
|
-
)
|
|
467
|
-
urls["url_publisher"] = url_publisher
|
|
468
|
-
finally:
|
|
469
|
-
await page.close()
|
|
470
|
-
|
|
471
|
-
# Step 2: Find PDF URLs from publisher URL
|
|
472
|
-
url_finder = ScholarURLFinder(context, config=self.config)
|
|
473
|
-
urls_pdf = []
|
|
474
|
-
|
|
475
|
-
if url_publisher:
|
|
476
|
-
urls_pdf = await url_finder.find_pdf_urls(url_publisher)
|
|
477
|
-
|
|
478
|
-
# Step 3: Try OpenURL fallback if no PDFs found
|
|
479
|
-
if not urls_pdf:
|
|
480
|
-
openurl_resolver = OpenURLResolver(config=self.config)
|
|
481
|
-
page = await context.new_page()
|
|
482
|
-
try:
|
|
483
|
-
url_openurl_resolved = await openurl_resolver.resolve_doi(doi, page)
|
|
484
|
-
urls["url_openurl_resolved"] = url_openurl_resolved
|
|
485
|
-
|
|
486
|
-
if url_openurl_resolved and url_openurl_resolved != "skipped":
|
|
487
|
-
urls_pdf = await url_finder.find_pdf_urls(url_openurl_resolved)
|
|
488
|
-
finally:
|
|
489
|
-
await page.close()
|
|
490
|
-
|
|
491
|
-
# Deduplicate and store
|
|
492
|
-
urls["urls_pdf"] = self._deduplicate_pdf_urls(urls_pdf) if urls_pdf else []
|
|
493
|
-
|
|
494
|
-
return urls
|
|
495
|
-
|
|
496
|
-
def _deduplicate_pdf_urls(self, urls_pdf: List[Dict]) -> List[Dict]:
|
|
497
|
-
"""Remove duplicate PDF URLs.
|
|
498
|
-
|
|
499
|
-
Args:
|
|
500
|
-
urls_pdf: List of PDF URL dicts
|
|
501
|
-
|
|
502
|
-
Returns:
|
|
503
|
-
Deduplicated list of PDF URL dicts
|
|
504
|
-
"""
|
|
505
|
-
seen = set()
|
|
506
|
-
unique = []
|
|
507
|
-
for pdf in urls_pdf:
|
|
508
|
-
url = pdf.get("url") if isinstance(pdf, dict) else pdf
|
|
509
|
-
if url not in seen:
|
|
510
|
-
seen.add(url)
|
|
511
|
-
unique.append(pdf)
|
|
512
|
-
return unique
|
|
513
|
-
|
|
514
|
-
# ----------------------------------------
|
|
515
|
-
# PDF Downloaders
|
|
516
|
-
# ----------------------------------------
|
|
517
|
-
async def download_pdfs_from_dois_async(
|
|
518
|
-
self,
|
|
519
|
-
dois: List[str],
|
|
520
|
-
output_dir: Optional[Path] = None,
|
|
521
|
-
max_concurrent: int = 1,
|
|
522
|
-
) -> Dict[str, int]:
|
|
523
|
-
"""Download PDFs for given DOIs using ScholarPDFDownloader.
|
|
524
|
-
|
|
525
|
-
Args:
|
|
526
|
-
dois: List of DOI strings
|
|
527
|
-
output_dir: Output directory (not used - downloads to library MASTER)
|
|
528
|
-
max_concurrent: Maximum concurrent downloads (default: 1 for sequential)
|
|
529
|
-
|
|
530
|
-
Returns:
|
|
531
|
-
Dictionary with download statistics
|
|
532
|
-
"""
|
|
533
|
-
if not dois:
|
|
534
|
-
return {"downloaded": 0, "failed": 0, "errors": 0}
|
|
535
|
-
|
|
536
|
-
# Get authenticated browser context
|
|
537
|
-
(
|
|
538
|
-
browser,
|
|
539
|
-
context,
|
|
540
|
-
) = await self._browser_manager.get_authenticated_browser_and_context_async()
|
|
541
|
-
|
|
542
|
-
try:
|
|
543
|
-
# Initialize PDF downloader with browser context
|
|
544
|
-
pdf_downloader = ScholarPDFDownloader(
|
|
545
|
-
context=context,
|
|
546
|
-
config=self.config,
|
|
547
|
-
)
|
|
548
|
-
|
|
549
|
-
# Use download_from_dois from ScholarPDFDownloader
|
|
550
|
-
# This handles parallel downloads with semaphore control
|
|
551
|
-
logger.info(
|
|
552
|
-
f"{self.name}: Starting PDF download for {len(dois)} DOIs (max_concurrent={max_concurrent})"
|
|
553
|
-
)
|
|
554
|
-
|
|
555
|
-
results = await pdf_downloader.download_from_dois(
|
|
556
|
-
dois=dois,
|
|
557
|
-
output_dir=str(output_dir) if output_dir else "/tmp/",
|
|
558
|
-
max_concurrent=max_concurrent,
|
|
559
|
-
)
|
|
560
|
-
|
|
561
|
-
# Process results and organize in library
|
|
562
|
-
stats = {"downloaded": 0, "failed": 0, "errors": 0}
|
|
563
|
-
library_dir = self.config.get_library_project_dir()
|
|
564
|
-
master_dir = library_dir / "MASTER"
|
|
565
|
-
master_dir.mkdir(parents=True, exist_ok=True)
|
|
566
|
-
|
|
567
|
-
for doi, downloaded_paths in zip(dois, results):
|
|
568
|
-
try:
|
|
569
|
-
if downloaded_paths and len(downloaded_paths) > 0:
|
|
570
|
-
# PDF was downloaded successfully
|
|
571
|
-
# Take the first downloaded PDF (if multiple)
|
|
572
|
-
temp_pdf_path = downloaded_paths[0]
|
|
573
|
-
|
|
574
|
-
# Generate paper ID and create storage
|
|
575
|
-
paper_id = self.config.path_manager._generate_paper_id(doi=doi)
|
|
576
|
-
storage_path = master_dir / paper_id
|
|
577
|
-
storage_path.mkdir(parents=True, exist_ok=True)
|
|
578
|
-
|
|
579
|
-
# Move PDF to MASTER library
|
|
580
|
-
pdf_filename = (
|
|
581
|
-
f"DOI_{doi.replace('/', '_').replace(':', '_')}.pdf"
|
|
582
|
-
)
|
|
583
|
-
master_pdf_path = storage_path / pdf_filename
|
|
584
|
-
shutil.move(str(temp_pdf_path), str(master_pdf_path))
|
|
585
|
-
|
|
586
|
-
# Create/update metadata
|
|
587
|
-
metadata_file = storage_path / "metadata.json"
|
|
588
|
-
if metadata_file.exists():
|
|
589
|
-
with open(metadata_file, "r") as f:
|
|
590
|
-
metadata = json.load(f)
|
|
591
|
-
else:
|
|
592
|
-
metadata = {
|
|
593
|
-
"doi": doi,
|
|
594
|
-
"scitex_id": paper_id,
|
|
595
|
-
"created_at": datetime.now().isoformat(),
|
|
596
|
-
"created_by": "SciTeX Scholar",
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
# Update metadata with PDF info
|
|
600
|
-
metadata["pdf_path"] = str(
|
|
601
|
-
master_pdf_path.relative_to(library_dir)
|
|
602
|
-
)
|
|
603
|
-
metadata["pdf_downloaded_at"] = datetime.now().isoformat()
|
|
604
|
-
metadata["pdf_size_bytes"] = master_pdf_path.stat().st_size
|
|
605
|
-
metadata["updated_at"] = datetime.now().isoformat()
|
|
606
|
-
|
|
607
|
-
with open(metadata_file, "w") as f:
|
|
608
|
-
json.dump(metadata, f, indent=2, ensure_ascii=False)
|
|
609
|
-
|
|
610
|
-
# Update symlink using LibraryManager
|
|
611
|
-
if self.project not in ["master", "MASTER"]:
|
|
612
|
-
self._library_manager.update_symlink(
|
|
613
|
-
master_storage_path=storage_path,
|
|
614
|
-
project=self.project,
|
|
615
|
-
)
|
|
616
|
-
|
|
617
|
-
logger.success(
|
|
618
|
-
f"{self.name}: Downloaded and organized PDF for {doi}: {master_pdf_path}"
|
|
619
|
-
)
|
|
620
|
-
stats["downloaded"] += 1
|
|
621
|
-
else:
|
|
622
|
-
logger.warning(f"{self.name}: No PDF downloaded for DOI: {doi}")
|
|
623
|
-
stats["failed"] += 1
|
|
624
|
-
|
|
625
|
-
except Exception as e:
|
|
626
|
-
logger.error(f"{self.name}: Failed to organize PDF for {doi}: {e}")
|
|
627
|
-
stats["errors"] += 1
|
|
628
|
-
stats["failed"] += 1
|
|
629
|
-
|
|
630
|
-
return stats
|
|
631
|
-
|
|
632
|
-
finally:
|
|
633
|
-
# Always close browser
|
|
634
|
-
await self._browser_manager.close()
|
|
635
|
-
|
|
636
|
-
async def _download_pdfs_sequential(
|
|
637
|
-
self, dois: List[str], output_dir: Optional[Path] = None
|
|
638
|
-
) -> Dict[str, int]:
|
|
639
|
-
"""Sequential PDF download with authentication gateway."""
|
|
640
|
-
results = {"downloaded": 0, "failed": 0, "errors": 0}
|
|
641
|
-
|
|
642
|
-
# Get authenticated browser context
|
|
643
|
-
(
|
|
644
|
-
browser,
|
|
645
|
-
context,
|
|
646
|
-
) = await self._browser_manager.get_authenticated_browser_and_context_async()
|
|
647
|
-
|
|
648
|
-
# Initialize authentication gateway (NEW)
|
|
649
|
-
auth_gateway = AuthenticationGateway(
|
|
650
|
-
auth_manager=self._auth_manager,
|
|
651
|
-
browser_manager=self._browser_manager,
|
|
652
|
-
config=self.config,
|
|
653
|
-
)
|
|
654
|
-
|
|
655
|
-
# Use simple downloader for sequential downloads
|
|
656
|
-
pdf_downloader = ScholarPDFDownloader(
|
|
657
|
-
context=context,
|
|
658
|
-
config=self.config,
|
|
659
|
-
)
|
|
660
|
-
|
|
661
|
-
library_dir = self.config.get_library_project_dir()
|
|
662
|
-
master_dir = library_dir / "MASTER"
|
|
663
|
-
project_dir = library_dir / self.project
|
|
664
|
-
master_dir.mkdir(parents=True, exist_ok=True)
|
|
665
|
-
project_dir.mkdir(parents=True, exist_ok=True)
|
|
666
|
-
|
|
667
|
-
for doi in dois:
|
|
668
|
-
try:
|
|
669
|
-
logger.info(f"{self.name}: Processing DOI: {doi}")
|
|
670
|
-
|
|
671
|
-
# NEW: Prepare authentication context BEFORE URL finding
|
|
672
|
-
# This establishes publisher-specific cookies if needed
|
|
673
|
-
_url_context = await auth_gateway.prepare_context_async(
|
|
674
|
-
doi=doi, context=context
|
|
675
|
-
)
|
|
676
|
-
|
|
677
|
-
# Step 1: Find URLs for the DOI (orchestration)
|
|
678
|
-
urls = await self._find_urls_for_doi_async(doi, context)
|
|
679
|
-
|
|
680
|
-
# Step 2: Get PDF URLs
|
|
681
|
-
pdf_urls = urls.get("urls_pdf", [])
|
|
682
|
-
|
|
683
|
-
if not pdf_urls:
|
|
684
|
-
logger.warning(f"{self.name}: No PDF URLs found for DOI: {doi}")
|
|
685
|
-
results["failed"] += 1
|
|
686
|
-
continue
|
|
687
|
-
|
|
688
|
-
# Step 3: Try to download from each PDF URL
|
|
689
|
-
downloaded_path = None
|
|
690
|
-
for pdf_entry in pdf_urls:
|
|
691
|
-
# Handle both dict and string formats
|
|
692
|
-
pdf_url = (
|
|
693
|
-
pdf_entry.get("url")
|
|
694
|
-
if isinstance(pdf_entry, dict)
|
|
695
|
-
else pdf_entry
|
|
696
|
-
)
|
|
697
|
-
|
|
698
|
-
if not pdf_url:
|
|
699
|
-
continue
|
|
700
|
-
|
|
701
|
-
# Download to temp location first
|
|
702
|
-
temp_output = (
|
|
703
|
-
Path("/tmp") / f"{doi.replace('/', '_').replace(':', '_')}.pdf"
|
|
704
|
-
)
|
|
705
|
-
|
|
706
|
-
# Download PDF using simple downloader
|
|
707
|
-
result = await pdf_downloader.download_from_url(
|
|
708
|
-
pdf_url=pdf_url, output_path=temp_output
|
|
709
|
-
)
|
|
710
|
-
|
|
711
|
-
if result and result.exists():
|
|
712
|
-
downloaded_path = result
|
|
713
|
-
break
|
|
714
|
-
|
|
715
|
-
if downloaded_path:
|
|
716
|
-
# Step 4: Store PDF in MASTER library with proper organization
|
|
717
|
-
|
|
718
|
-
# Generate unique ID from DOI using PathManager
|
|
719
|
-
paper_id = self.config.path_manager._generate_paper_id(doi=doi)
|
|
720
|
-
|
|
721
|
-
# Create MASTER storage directory
|
|
722
|
-
storage_path = master_dir / paper_id
|
|
723
|
-
storage_path.mkdir(parents=True, exist_ok=True)
|
|
724
|
-
|
|
725
|
-
# Try to get paper metadata to generate readable name
|
|
726
|
-
readable_name = None
|
|
727
|
-
temp_paper = None
|
|
728
|
-
try:
|
|
729
|
-
# Try to load paper from DOI to get metadata
|
|
730
|
-
from scitex.scholar.core.Paper import Paper
|
|
731
|
-
from scitex.scholar.core.Papers import Papers
|
|
732
|
-
|
|
733
|
-
temp_paper = Paper()
|
|
734
|
-
temp_paper.metadata.id.doi = doi
|
|
735
|
-
# Try to enrich to get author/year/journal using async method
|
|
736
|
-
temp_papers = Papers([temp_paper])
|
|
737
|
-
enriched = await self.enrich_papers_async(temp_papers)
|
|
738
|
-
if enriched and len(enriched) > 0:
|
|
739
|
-
temp_paper = enriched[0]
|
|
740
|
-
|
|
741
|
-
# Generate readable name from metadata
|
|
742
|
-
first_author = "Unknown"
|
|
743
|
-
authors = temp_paper.metadata.basic.authors
|
|
744
|
-
if authors and len(authors) > 0:
|
|
745
|
-
author_parts = authors[0].split()
|
|
746
|
-
if len(author_parts) > 1:
|
|
747
|
-
first_author = author_parts[-1] # Last name
|
|
748
|
-
else:
|
|
749
|
-
first_author = author_parts[0]
|
|
750
|
-
|
|
751
|
-
year = temp_paper.metadata.basic.year
|
|
752
|
-
year_str = str(year) if year else "Unknown"
|
|
753
|
-
|
|
754
|
-
journal_clean = "Unknown"
|
|
755
|
-
journal = temp_paper.metadata.publication.journal
|
|
756
|
-
if journal:
|
|
757
|
-
# Clean journal name - remove special chars, keep alphanumeric
|
|
758
|
-
journal_clean = "".join(
|
|
759
|
-
c for c in journal if c.isalnum() or c in " "
|
|
760
|
-
).replace(" ", "")
|
|
761
|
-
if not journal_clean:
|
|
762
|
-
journal_clean = "Unknown"
|
|
763
|
-
|
|
764
|
-
# Format: Author-Year-Journal
|
|
765
|
-
readable_name = f"{first_author}-{year_str}-{journal_clean}"
|
|
766
|
-
except:
|
|
767
|
-
pass
|
|
768
|
-
|
|
769
|
-
# Fallback to DOI if metadata extraction failed
|
|
770
|
-
if not readable_name:
|
|
771
|
-
readable_name = f"DOI_{doi.replace('/', '_').replace(':', '_')}"
|
|
772
|
-
|
|
773
|
-
# Copy PDF to MASTER storage with ORIGINAL filename to track how downloaded
|
|
774
|
-
# The PDF filename preserves the DOI format for tracking
|
|
775
|
-
pdf_filename = f"DOI_{doi.replace('/', '_').replace(':', '_')}.pdf"
|
|
776
|
-
master_pdf_path = storage_path / pdf_filename
|
|
777
|
-
shutil.copy2(downloaded_path, master_pdf_path)
|
|
778
|
-
|
|
779
|
-
# Load existing metadata or create minimal new metadata
|
|
780
|
-
metadata_file = storage_path / "metadata.json"
|
|
781
|
-
if metadata_file.exists():
|
|
782
|
-
# Load existing rich metadata - DO NOT OVERWRITE IT
|
|
783
|
-
with open(metadata_file, "r") as f:
|
|
784
|
-
metadata = json.load(f)
|
|
785
|
-
logger.debug(
|
|
786
|
-
f"{self.name}: Loaded existing metadata for {paper_id}"
|
|
787
|
-
)
|
|
788
|
-
else:
|
|
789
|
-
# Create new minimal metadata only if none exists
|
|
790
|
-
metadata = {
|
|
791
|
-
"doi": doi,
|
|
792
|
-
"scitex_id": paper_id,
|
|
793
|
-
"created_at": datetime.now().isoformat(),
|
|
794
|
-
"created_by": "SciTeX Scholar",
|
|
795
|
-
}
|
|
796
|
-
|
|
797
|
-
# Add enriched paper metadata for new papers only
|
|
798
|
-
if temp_paper:
|
|
799
|
-
# Use Pydantic to_dict() for Paper
|
|
800
|
-
paper_dict = temp_paper.to_dict()
|
|
801
|
-
# Merge paper metadata
|
|
802
|
-
for key, value in paper_dict.items():
|
|
803
|
-
if value is not None and key not in [
|
|
804
|
-
"doi",
|
|
805
|
-
"scitex_id",
|
|
806
|
-
]:
|
|
807
|
-
metadata[key] = value
|
|
808
|
-
|
|
809
|
-
# Add PDF information
|
|
810
|
-
metadata["pdf_path"] = str(master_pdf_path.relative_to(library_dir))
|
|
811
|
-
metadata["pdf_downloaded_at"] = datetime.now().isoformat()
|
|
812
|
-
metadata["pdf_size_bytes"] = master_pdf_path.stat().st_size
|
|
813
|
-
metadata["updated_at"] = datetime.now().isoformat()
|
|
814
|
-
|
|
815
|
-
# Save updated metadata
|
|
816
|
-
with open(metadata_file, "w") as f:
|
|
817
|
-
json.dump(metadata, f, indent=2, ensure_ascii=False)
|
|
818
|
-
|
|
819
|
-
# Update symlink using LibraryManager
|
|
820
|
-
if self.project not in ["master", "MASTER"]:
|
|
821
|
-
self._library_manager.update_symlink(
|
|
822
|
-
master_storage_path=storage_path,
|
|
823
|
-
project=self.project,
|
|
824
|
-
)
|
|
825
|
-
|
|
826
|
-
# Clean up temp file
|
|
827
|
-
downloaded_path.unlink()
|
|
828
|
-
|
|
829
|
-
logger.success(
|
|
830
|
-
f"{self.name}: Downloaded PDF for {doi}: MASTER/{paper_id}/{pdf_filename}"
|
|
831
|
-
)
|
|
832
|
-
results["downloaded"] += 1
|
|
833
|
-
else:
|
|
834
|
-
logger.warning(
|
|
835
|
-
f"{self.name}: Failed to download any PDF for DOI: {doi}"
|
|
836
|
-
)
|
|
837
|
-
results["failed"] += 1
|
|
838
|
-
|
|
839
|
-
except Exception as e:
|
|
840
|
-
logger.error(f"{self.name}: Failed to process {doi}: {e}")
|
|
841
|
-
results["errors"] += 1
|
|
842
|
-
results["failed"] += 1
|
|
843
|
-
|
|
844
|
-
await self._browser_manager.close()
|
|
845
|
-
logger.info(f"{self.name}: PDF download complete: {results}")
|
|
846
|
-
return results
|
|
847
|
-
|
|
848
|
-
def download_pdfs_from_dois(
|
|
849
|
-
self, dois: List[str], output_dir: Optional[Path] = None
|
|
850
|
-
) -> Dict[str, int]:
|
|
851
|
-
"""Download PDFs for given DOIs.
|
|
852
|
-
|
|
853
|
-
Args:
|
|
854
|
-
dois: List of DOI strings
|
|
855
|
-
output_dir: Output directory (uses config default if None)
|
|
856
|
-
|
|
857
|
-
Returns:
|
|
858
|
-
Dictionary with download statistics
|
|
859
|
-
"""
|
|
860
|
-
import asyncio
|
|
861
|
-
|
|
862
|
-
return asyncio.run(self.download_pdfs_from_dois_async(dois, output_dir))
|
|
863
|
-
|
|
864
|
-
def download_pdfs_from_bibtex(
|
|
865
|
-
self,
|
|
866
|
-
bibtex_input: Union[str, Path, Papers],
|
|
867
|
-
output_dir: Optional[Path] = None,
|
|
868
|
-
) -> Dict[str, int]:
|
|
869
|
-
"""Download PDFs from BibTeX file or Papers collection.
|
|
870
|
-
|
|
871
|
-
Args:
|
|
872
|
-
bibtex_input: BibTeX file path, content string, or Papers collection
|
|
873
|
-
output_dir: Output directory (uses config default if None)
|
|
874
|
-
|
|
875
|
-
Returns:
|
|
876
|
-
Dictionary with download statistics
|
|
877
|
-
"""
|
|
878
|
-
# Load papers if bibtex_input is not already Papers
|
|
879
|
-
if isinstance(bibtex_input, Papers):
|
|
880
|
-
papers = bibtex_input
|
|
881
|
-
else:
|
|
882
|
-
papers = self.load_bibtex(bibtex_input)
|
|
883
|
-
|
|
884
|
-
# Extract DOIs from papers
|
|
885
|
-
dois = [paper.metadata.id.doi for paper in papers if paper.metadata.id.doi]
|
|
886
|
-
|
|
887
|
-
if not dois:
|
|
888
|
-
logger.warning(f"{self.name}: No papers with DOIs found in BibTeX input")
|
|
889
|
-
return {"downloaded": 0, "failed": 0, "errors": 0}
|
|
890
|
-
|
|
891
|
-
logger.info(
|
|
892
|
-
f"{self.name}: Found {len(dois)} papers with DOIs out of {len(papers)} total papers"
|
|
893
|
-
)
|
|
894
|
-
|
|
895
|
-
# Download PDFs using DOI method
|
|
896
|
-
return self.download_pdfs_from_dois(dois, output_dir)
|
|
897
|
-
|
|
898
|
-
# ----------------------------------------
|
|
899
|
-
# Loaders
|
|
900
|
-
# ----------------------------------------
|
|
901
|
-
def load_project(self, project: Optional[str] = None) -> Papers:
|
|
902
|
-
"""Load papers from a project using library manager service.
|
|
903
|
-
|
|
904
|
-
Args:
|
|
905
|
-
project: Project name (uses self.project if None)
|
|
906
|
-
|
|
907
|
-
Returns:
|
|
908
|
-
Papers collection from the project
|
|
909
|
-
"""
|
|
910
|
-
project_name = project or self.project
|
|
911
|
-
if not project_name:
|
|
912
|
-
raise ValueError("No project specified")
|
|
913
|
-
|
|
914
|
-
# Load papers from library by reading symlinks in project directory
|
|
915
|
-
from ..core.Papers import Papers
|
|
916
|
-
from ..core.Paper import Paper
|
|
917
|
-
import json
|
|
918
|
-
|
|
919
|
-
logger.info(f"{self.name}: Loading papers from project: {project_name}")
|
|
920
|
-
|
|
921
|
-
library_dir = self.config.get_library_project_dir()
|
|
922
|
-
project_dir = library_dir / project_name
|
|
923
|
-
|
|
924
|
-
if not project_dir.exists():
|
|
925
|
-
logger.warning(
|
|
926
|
-
f"{self.name}: Project directory does not exist: {project_dir}"
|
|
927
|
-
)
|
|
928
|
-
return Papers([], project=project_name)
|
|
929
|
-
|
|
930
|
-
papers = []
|
|
931
|
-
for item in project_dir.iterdir():
|
|
932
|
-
# Skip info directory and metadata files
|
|
933
|
-
if item.name in ["info", "project_metadata.json", "README.md"]:
|
|
934
|
-
continue
|
|
935
|
-
|
|
936
|
-
# Follow symlink to MASTER directory
|
|
937
|
-
if item.is_symlink():
|
|
938
|
-
master_path = item.resolve()
|
|
939
|
-
if master_path.exists():
|
|
940
|
-
# Load metadata.json from MASTER directory
|
|
941
|
-
metadata_file = master_path / "metadata.json"
|
|
942
|
-
if metadata_file.exists():
|
|
943
|
-
try:
|
|
944
|
-
with open(metadata_file, "r") as f:
|
|
945
|
-
metadata = json.load(f)
|
|
946
|
-
|
|
947
|
-
# Create Paper object using from_dict class method
|
|
948
|
-
paper = Paper.from_dict(metadata)
|
|
949
|
-
|
|
950
|
-
papers.append(paper)
|
|
951
|
-
except Exception as e:
|
|
952
|
-
logger.warning(
|
|
953
|
-
f"{self.name}: Failed to load metadata from {metadata_file}: {e}"
|
|
954
|
-
)
|
|
955
|
-
|
|
956
|
-
logger.info(
|
|
957
|
-
f"{self.name}: Loaded {len(papers)} papers from project: {project_name}"
|
|
958
|
-
)
|
|
959
|
-
return Papers(papers, project=project_name)
|
|
960
|
-
|
|
961
|
-
def load_bibtex(self, bibtex_input: Union[str, Path]) -> Papers:
|
|
962
|
-
"""Load Papers collection from BibTeX file or content.
|
|
963
|
-
|
|
964
|
-
Args:
|
|
965
|
-
bibtex_input: BibTeX file path or content string
|
|
966
|
-
|
|
967
|
-
Returns:
|
|
968
|
-
Papers collection
|
|
969
|
-
"""
|
|
970
|
-
# Use the internal library to load papers
|
|
971
|
-
papers = self._library.papers_from_bibtex(bibtex_input)
|
|
972
|
-
|
|
973
|
-
# Convert to Papers collection
|
|
974
|
-
from .Papers import Papers
|
|
975
|
-
|
|
976
|
-
papers_collection = Papers(papers, config=self.config, project=self.project)
|
|
977
|
-
papers_collection.library = self._library # Attach library for save operations
|
|
978
|
-
|
|
979
|
-
return papers_collection
|
|
980
124
|
|
|
981
|
-
# ----------------------------------------
|
|
982
|
-
# Searchers
|
|
983
|
-
# ----------------------------------------
|
|
984
|
-
def search_library(self, query: str, project: Optional[str] = None) -> Papers:
|
|
985
|
-
"""
|
|
986
|
-
Search papers in local library.
|
|
987
|
-
|
|
988
|
-
For new literature search (not in library), use AI2 Scholar QA:
|
|
989
|
-
https://scholarqa.allen.ai/chat/ then process with:
|
|
990
|
-
papers = scholar.load_bibtex('file.bib') followed by scholar.enrich(papers)
|
|
991
|
-
|
|
992
|
-
Args:
|
|
993
|
-
query: Search query
|
|
994
|
-
project: Project filter (uses self.project if None)
|
|
995
|
-
|
|
996
|
-
Returns:
|
|
997
|
-
Papers collection matching the query
|
|
998
|
-
"""
|
|
999
|
-
# For now, return empty Papers until search is implemented
|
|
1000
|
-
from ..core.Papers import Papers
|
|
1001
|
-
|
|
1002
|
-
logger.info(f"{self.name}: Searching library for: {query}")
|
|
1003
|
-
return Papers([], project=project or self.project)
|
|
1004
|
-
|
|
1005
|
-
def search_across_projects(
|
|
1006
|
-
self, query: str, projects: Optional[List[str]] = None
|
|
1007
|
-
) -> Papers:
|
|
1008
|
-
"""Search for papers across multiple projects or the entire library.
|
|
1009
|
-
|
|
1010
|
-
Args:
|
|
1011
|
-
query: Search query
|
|
1012
|
-
projects: List of project names to search (None for all)
|
|
1013
|
-
|
|
1014
|
-
Returns:
|
|
1015
|
-
Papers collection with search results
|
|
1016
|
-
"""
|
|
1017
|
-
if projects is None:
|
|
1018
|
-
# Search all projects
|
|
1019
|
-
all_projects = [p["name"] for p in self.list_projects()]
|
|
1020
|
-
else:
|
|
1021
|
-
all_projects = projects
|
|
1022
|
-
|
|
1023
|
-
all_papers = []
|
|
1024
|
-
for project in all_projects:
|
|
1025
|
-
try:
|
|
1026
|
-
project_papers = Papers.from_project(project, self.config)
|
|
1027
|
-
# Simple text search implementation
|
|
1028
|
-
matching_papers = [
|
|
1029
|
-
p
|
|
1030
|
-
for p in project_papers._papers
|
|
1031
|
-
if query.lower() in (p.title or "").lower()
|
|
1032
|
-
or query.lower() in (p.abstract or "").lower()
|
|
1033
|
-
or any(
|
|
1034
|
-
query.lower() in (author or "").lower()
|
|
1035
|
-
for author in (p.authors or [])
|
|
1036
|
-
)
|
|
1037
|
-
]
|
|
1038
|
-
all_papers.extend(matching_papers)
|
|
1039
|
-
except Exception as e:
|
|
1040
|
-
logger.debug(f"{self.name}: Failed to search project {project}: {e}")
|
|
1041
|
-
|
|
1042
|
-
return Papers(all_papers, config=self.config, project="search_results")
|
|
1043
|
-
|
|
1044
|
-
# ----------------------------------------
|
|
1045
|
-
# Savers
|
|
1046
|
-
# ----------------------------------------
|
|
1047
|
-
def save_papers_to_library(self, papers: Papers) -> List[str]:
|
|
1048
|
-
"""Save papers collection to library.
|
|
1049
|
-
|
|
1050
|
-
Args:
|
|
1051
|
-
papers: Papers collection to save
|
|
1052
|
-
|
|
1053
|
-
Returns:
|
|
1054
|
-
List of paper IDs saved
|
|
1055
|
-
"""
|
|
1056
|
-
saved_ids = []
|
|
1057
|
-
for paper in papers:
|
|
1058
|
-
try:
|
|
1059
|
-
paper_id = self._library.save_paper(paper)
|
|
1060
|
-
saved_ids.append(paper_id)
|
|
1061
|
-
except Exception as e:
|
|
1062
|
-
logger.warning(f"{self.name}: Failed to save paper: {e}")
|
|
1063
|
-
|
|
1064
|
-
logger.info(
|
|
1065
|
-
f"{self.name}: Saved {len(saved_ids)}/{len(papers)} papers to library"
|
|
1066
|
-
)
|
|
1067
|
-
return saved_ids
|
|
1068
|
-
|
|
1069
|
-
def save_papers_as_bibtex(
|
|
1070
|
-
self, papers: Papers, output_path: Optional[Union[str, Path]] = None
|
|
1071
|
-
) -> str:
|
|
1072
|
-
"""Save papers to BibTeX format with enrichment metadata.
|
|
1073
|
-
|
|
1074
|
-
Args:
|
|
1075
|
-
papers: Papers collection to save
|
|
1076
|
-
output_path: Optional path to save the BibTeX file
|
|
1077
|
-
|
|
1078
|
-
Returns:
|
|
1079
|
-
BibTeX content as string with enrichment metadata included
|
|
1080
|
-
"""
|
|
1081
|
-
from ..storage.BibTeXHandler import BibTeXHandler
|
|
1082
|
-
|
|
1083
|
-
bibtex_handler = BibTeXHandler(project=self.project, config=self.config)
|
|
1084
|
-
return bibtex_handler.papers_to_bibtex(papers, output_path)
|
|
1085
|
-
|
|
1086
|
-
# ----------------------------------------
|
|
1087
|
-
# Project Handlers
|
|
1088
|
-
# ----------------------------------------
|
|
1089
|
-
def _ensure_project_exists(
|
|
1090
|
-
self, project: str, description: Optional[str] = None
|
|
1091
|
-
) -> Path:
|
|
1092
|
-
"""Ensure project directory exists, create if needed (PRIVATE).
|
|
1093
|
-
|
|
1094
|
-
Args:
|
|
1095
|
-
project: Project name
|
|
1096
|
-
description: Optional project description
|
|
1097
|
-
|
|
1098
|
-
Returns:
|
|
1099
|
-
Path to the project directory
|
|
1100
|
-
"""
|
|
1101
|
-
project_dir = self.config.get_library_project_dir() / project
|
|
1102
|
-
info_dir = project_dir / "info"
|
|
1103
|
-
|
|
1104
|
-
# Create project and info directories
|
|
1105
|
-
if not project_dir.exists():
|
|
1106
|
-
project_dir.mkdir(parents=True, exist_ok=True)
|
|
1107
|
-
logger.info(f"{self.name}: Auto-created project directory: {project}")
|
|
1108
|
-
|
|
1109
|
-
# Ensure info directory exists
|
|
1110
|
-
info_dir.mkdir(parents=True, exist_ok=True)
|
|
1111
|
-
|
|
1112
|
-
# Create/move metadata file to info directory
|
|
1113
|
-
old_metadata_file = project_dir / "project_metadata.json" # Old location
|
|
1114
|
-
metadata_file = info_dir / "project_metadata.json" # New location
|
|
1115
|
-
|
|
1116
|
-
# Move existing metadata file if it exists in old location
|
|
1117
|
-
if old_metadata_file.exists() and not metadata_file.exists():
|
|
1118
|
-
shutil.move(str(old_metadata_file), str(metadata_file))
|
|
1119
|
-
logger.info(f"{self.name}: Moved project metadata to info directory")
|
|
1120
|
-
|
|
1121
|
-
# Create metadata file if it doesn't exist
|
|
1122
|
-
if not metadata_file.exists():
|
|
1123
|
-
metadata = {
|
|
1124
|
-
"name": project,
|
|
1125
|
-
"description": description or f"Papers for {project} project",
|
|
1126
|
-
"created": datetime.now().isoformat(),
|
|
1127
|
-
"created_by": "SciTeX Scholar",
|
|
1128
|
-
"auto_created": True,
|
|
1129
|
-
}
|
|
1130
|
-
|
|
1131
|
-
with open(metadata_file, "w") as f:
|
|
1132
|
-
json.dump(metadata, f, indent=2)
|
|
1133
|
-
|
|
1134
|
-
logger.info(
|
|
1135
|
-
f"{self.name}: Created project metadata in info directory: {project}"
|
|
1136
|
-
)
|
|
1137
|
-
|
|
1138
|
-
return project_dir
|
|
1139
|
-
|
|
1140
|
-
def _create_project_metadata(
|
|
1141
|
-
self, project: str, description: Optional[str] = None
|
|
1142
|
-
) -> Path:
|
|
1143
|
-
"""Create project directory and metadata (PRIVATE).
|
|
1144
|
-
|
|
1145
|
-
DEPRECATED: Use _ensure_project_exists instead.
|
|
1146
|
-
|
|
1147
|
-
Args:
|
|
1148
|
-
project: Project name
|
|
1149
|
-
description: Optional project description
|
|
1150
|
-
|
|
1151
|
-
Returns:
|
|
1152
|
-
Path to the created project directory
|
|
1153
|
-
"""
|
|
1154
|
-
# Just use the new method that puts metadata in info directory
|
|
1155
|
-
return self._ensure_project_exists(project, description)
|
|
1156
|
-
|
|
1157
|
-
def list_projects(self) -> List[Dict[str, Any]]:
|
|
1158
|
-
"""List all projects in the Scholar library.
|
|
1159
|
-
|
|
1160
|
-
Returns:
|
|
1161
|
-
List of project information dictionaries
|
|
1162
|
-
"""
|
|
1163
|
-
library_dir = self.config.get_library_project_dir()
|
|
1164
|
-
projects = []
|
|
1165
|
-
|
|
1166
|
-
for item in library_dir.iterdir():
|
|
1167
|
-
if item.is_dir() and item.name != "MASTER":
|
|
1168
|
-
project_info = {
|
|
1169
|
-
"name": item.name,
|
|
1170
|
-
"path": str(item),
|
|
1171
|
-
"papers_count": len(list(item.glob("*"))),
|
|
1172
|
-
"created": None,
|
|
1173
|
-
"description": None,
|
|
1174
|
-
}
|
|
1175
|
-
|
|
1176
|
-
# Load metadata if exists
|
|
1177
|
-
metadata_file = item / "project_metadata.json"
|
|
1178
|
-
if metadata_file.exists():
|
|
1179
|
-
try:
|
|
1180
|
-
with open(metadata_file, "r") as f:
|
|
1181
|
-
metadata = json.load(f)
|
|
1182
|
-
project_info.update(metadata)
|
|
1183
|
-
except Exception as e:
|
|
1184
|
-
logger.debug(f"Failed to load metadata for {item.name}: {e}")
|
|
1185
|
-
|
|
1186
|
-
projects.append(project_info)
|
|
1187
|
-
|
|
1188
|
-
return sorted(projects, key=lambda x: x["name"])
|
|
1189
|
-
|
|
1190
|
-
# ----------------------------------------
|
|
1191
|
-
# Library Handlers
|
|
1192
|
-
# ----------------------------------------
|
|
1193
|
-
def get_library_statistics(self) -> Dict[str, Any]:
|
|
1194
|
-
"""Get comprehensive statistics for the entire Scholar library.
|
|
1195
|
-
|
|
1196
|
-
Returns:
|
|
1197
|
-
Dictionary with library-wide statistics
|
|
1198
|
-
"""
|
|
1199
|
-
master_dir = self.config.get_library_master_dir()
|
|
1200
|
-
projects = self.list_projects()
|
|
1201
|
-
|
|
1202
|
-
stats = {
|
|
1203
|
-
"total_projects": len(projects),
|
|
1204
|
-
"total_papers": (
|
|
1205
|
-
len(list(master_dir.glob("*"))) if master_dir.exists() else 0
|
|
1206
|
-
),
|
|
1207
|
-
"projects": projects,
|
|
1208
|
-
"library_path": str(self.config.get_library_project_dir()),
|
|
1209
|
-
"master_path": str(master_dir),
|
|
1210
|
-
}
|
|
1211
|
-
|
|
1212
|
-
# Calculate storage usage
|
|
1213
|
-
if master_dir.exists():
|
|
1214
|
-
total_size = sum(
|
|
1215
|
-
f.stat().st_size for f in master_dir.rglob("*") if f.is_file()
|
|
1216
|
-
)
|
|
1217
|
-
stats["storage_mb"] = total_size / (1024 * 1024)
|
|
1218
|
-
else:
|
|
1219
|
-
stats["storage_mb"] = 0
|
|
1220
|
-
|
|
1221
|
-
return stats
|
|
1222
|
-
|
|
1223
|
-
def backup_library(self, backup_path: Union[str, Path]) -> Dict[str, Any]:
|
|
1224
|
-
"""Create a backup of the Scholar library.
|
|
1225
|
-
|
|
1226
|
-
Args:
|
|
1227
|
-
backup_path: Path for the backup
|
|
1228
|
-
|
|
1229
|
-
Returns:
|
|
1230
|
-
Dictionary with backup information
|
|
1231
|
-
"""
|
|
1232
|
-
backup_path = Path(backup_path)
|
|
1233
|
-
library_path = self.config.get_library_project_dir()
|
|
1234
|
-
|
|
1235
|
-
if not library_path.exists():
|
|
1236
|
-
raise ScholarError("Library directory does not exist")
|
|
1237
|
-
|
|
1238
|
-
# Create timestamped backup
|
|
1239
|
-
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
1240
|
-
backup_dir = backup_path / f"scholar_library_backup_{timestamp}"
|
|
1241
|
-
|
|
1242
|
-
logger.info(f"{self.name}: Creating library backup at {backup_dir}")
|
|
1243
|
-
shutil.copytree(library_path, backup_dir)
|
|
1244
|
-
|
|
1245
|
-
# Create backup metadata
|
|
1246
|
-
backup_info = {
|
|
1247
|
-
"timestamp": timestamp,
|
|
1248
|
-
"source": str(library_path),
|
|
1249
|
-
"backup": str(backup_dir),
|
|
1250
|
-
"size_mb": sum(
|
|
1251
|
-
f.stat().st_size for f in backup_dir.rglob("*") if f.is_file()
|
|
1252
|
-
)
|
|
1253
|
-
/ (1024 * 1024),
|
|
1254
|
-
}
|
|
1255
|
-
|
|
1256
|
-
metadata_file = backup_dir / "backup_metadata.json"
|
|
1257
|
-
with open(metadata_file, "w") as f:
|
|
1258
|
-
json.dump(backup_info, f, indent=2)
|
|
1259
|
-
|
|
1260
|
-
logger.info(
|
|
1261
|
-
f"{self.name}: Library backup completed: {backup_info['size_mb']:.2f} MB"
|
|
1262
|
-
)
|
|
1263
|
-
return backup_info
|
|
1264
|
-
|
|
1265
|
-
# =========================================================================
|
|
1266
|
-
# PIPELINE METHODS (Phase 2)
|
|
1267
|
-
# =========================================================================
|
|
1268
|
-
|
|
1269
|
-
async def process_paper_async(
|
|
1270
|
-
self,
|
|
1271
|
-
title: Optional[str] = None,
|
|
1272
|
-
doi: Optional[str] = None,
|
|
1273
|
-
project: Optional[str] = None,
|
|
1274
|
-
) -> "Paper":
|
|
1275
|
-
"""
|
|
1276
|
-
Complete sequential pipeline for processing a single paper.
|
|
1277
|
-
|
|
1278
|
-
Accepts either title OR doi. Uses storage-first approach:
|
|
1279
|
-
each stage checks storage before processing.
|
|
1280
|
-
|
|
1281
|
-
Workflow:
|
|
1282
|
-
Stage 0: Resolve DOI from title (if needed)
|
|
1283
|
-
Stage 1: Load or create Paper from storage
|
|
1284
|
-
Stage 2: Find PDF URLs → save to storage
|
|
1285
|
-
Stage 3: Download PDF → save to storage
|
|
1286
|
-
Stage 4: Update project symlinks
|
|
1287
|
-
|
|
1288
|
-
Args:
|
|
1289
|
-
title: Paper title (will resolve DOI using engine)
|
|
1290
|
-
doi: DOI of the paper (preferred if available)
|
|
1291
|
-
project: Project name (uses self.project if None)
|
|
1292
|
-
|
|
1293
|
-
Returns:
|
|
1294
|
-
Fully processed Paper object
|
|
1295
|
-
|
|
1296
|
-
Examples:
|
|
1297
|
-
# With DOI (direct)
|
|
1298
|
-
paper = await scholar.process_paper_async(doi="10.1038/s41598-017-02626-y")
|
|
1299
|
-
|
|
1300
|
-
# With title (resolves DOI first)
|
|
1301
|
-
paper = await scholar.process_paper_async(
|
|
1302
|
-
title="Attention Is All You Need"
|
|
1303
|
-
)
|
|
1304
|
-
"""
|
|
1305
|
-
from scitex.scholar.core.Paper import Paper
|
|
1306
|
-
|
|
1307
|
-
# Validate input
|
|
1308
|
-
if not title and not doi:
|
|
1309
|
-
raise ValueError("Must provide either title or doi")
|
|
1310
|
-
|
|
1311
|
-
project = project or self.project
|
|
1312
|
-
|
|
1313
|
-
logger.info(f"{'=' * 60}")
|
|
1314
|
-
logger.info(f"Processing paper")
|
|
1315
|
-
if title:
|
|
1316
|
-
logger.info(f"Title: {title[:50]}...")
|
|
1317
|
-
if doi:
|
|
1318
|
-
logger.info(f"DOI: {doi}")
|
|
1319
|
-
logger.info(f"{'=' * 60}")
|
|
1320
|
-
|
|
1321
|
-
# Stage 0: Resolve DOI from title (if needed)
|
|
1322
|
-
if not doi and title:
|
|
1323
|
-
logger.info(f"Stage 0: Resolving DOI from title...")
|
|
1324
|
-
|
|
1325
|
-
# Use ScholarEngine to search and get DOI
|
|
1326
|
-
results = await self._scholar_engine.search_async(title=title)
|
|
1327
|
-
|
|
1328
|
-
if results and results.get("id", {}).get("doi"):
|
|
1329
|
-
doi = results["id"]["doi"]
|
|
1330
|
-
logger.success(f"Resolved DOI: {doi}")
|
|
1331
|
-
else:
|
|
1332
|
-
logger.error(f"Could not resolve DOI from title: {title}")
|
|
1333
|
-
raise ValueError(f"Could not resolve DOI from title: {title}")
|
|
1334
|
-
|
|
1335
|
-
# Generate paper ID from DOI
|
|
1336
|
-
paper_id = self.config.path_manager._generate_paper_id(doi=doi)
|
|
1337
|
-
storage_path = self.config.get_library_master_dir() / paper_id
|
|
1338
|
-
|
|
1339
|
-
logger.info(f"Paper ID: {paper_id}")
|
|
1340
|
-
logger.info(f"Storage: {storage_path}")
|
|
1341
|
-
|
|
1342
|
-
# Stage 1: Load or create Paper from storage
|
|
1343
|
-
logger.info(f"\nStage 1: Loading/creating metadata...")
|
|
1344
|
-
if self._library_manager.has_metadata(paper_id):
|
|
1345
|
-
# Load existing from storage
|
|
1346
|
-
paper = self._library_manager.load_paper_from_id(paper_id)
|
|
1347
|
-
logger.info(f"Loaded existing metadata from storage")
|
|
1348
|
-
else:
|
|
1349
|
-
# Create new Paper
|
|
1350
|
-
paper = Paper()
|
|
1351
|
-
paper.metadata.set_doi(doi)
|
|
1352
|
-
paper.container.scitex_id = paper_id
|
|
1353
|
-
|
|
1354
|
-
# If we have title, save it
|
|
1355
|
-
if title:
|
|
1356
|
-
paper.metadata.basic.title = title
|
|
1357
|
-
|
|
1358
|
-
# Create storage and save
|
|
1359
|
-
self._library_manager.save_paper_incremental(paper_id, paper)
|
|
1360
|
-
logger.success(f"Created new paper entry in storage")
|
|
1361
|
-
|
|
1362
|
-
# Stage 2: Check/find URLs
|
|
1363
|
-
logger.info(f"\nStage 2: Checking/finding PDF URLs...")
|
|
1364
|
-
if not self._library_manager.has_urls(paper_id):
|
|
1365
|
-
logger.info(f"Finding PDF URLs for DOI: {doi}")
|
|
1366
|
-
(
|
|
1367
|
-
browser,
|
|
1368
|
-
context,
|
|
1369
|
-
) = await self._browser_manager.get_authenticated_browser_and_context_async()
|
|
1370
|
-
try:
|
|
1371
|
-
url_finder = ScholarURLFinder(context, config=self.config)
|
|
1372
|
-
urls = await url_finder.find_pdf_urls(doi)
|
|
1373
|
-
|
|
1374
|
-
paper.metadata.url.pdfs = urls
|
|
1375
|
-
self._library_manager.save_paper_incremental(paper_id, paper)
|
|
1376
|
-
logger.success(f"Found {len(urls)} PDF URLs, saved to storage")
|
|
1377
|
-
finally:
|
|
1378
|
-
await self._browser_manager.close()
|
|
1379
|
-
else:
|
|
1380
|
-
logger.info(
|
|
1381
|
-
f"PDF URLs already in storage ({len(paper.metadata.url.pdfs)} URLs)"
|
|
1382
|
-
)
|
|
1383
|
-
|
|
1384
|
-
# Stage 3: Check/download PDF
|
|
1385
|
-
logger.info(f"\nStage 3: Checking/downloading PDF...")
|
|
1386
|
-
if not self._library_manager.has_pdf(paper_id):
|
|
1387
|
-
logger.info(f"Downloading PDF...")
|
|
1388
|
-
if paper.metadata.url.pdfs:
|
|
1389
|
-
(
|
|
1390
|
-
browser,
|
|
1391
|
-
context,
|
|
1392
|
-
) = await self._browser_manager.get_authenticated_browser_and_context_async()
|
|
1393
|
-
try:
|
|
1394
|
-
downloader = ScholarPDFDownloader(context, config=self.config)
|
|
1395
|
-
|
|
1396
|
-
pdf_url = (
|
|
1397
|
-
paper.metadata.url.pdfs[0]["url"]
|
|
1398
|
-
if isinstance(paper.metadata.url.pdfs[0], dict)
|
|
1399
|
-
else paper.metadata.url.pdfs[0]
|
|
1400
|
-
)
|
|
1401
|
-
temp_path = storage_path / "main.pdf"
|
|
1402
|
-
|
|
1403
|
-
result = await downloader.download_from_url(
|
|
1404
|
-
pdf_url, temp_path, doi=doi
|
|
1405
|
-
)
|
|
1406
|
-
if result and result.exists():
|
|
1407
|
-
paper.metadata.path.pdfs.append(str(result))
|
|
1408
|
-
self._library_manager.save_paper_incremental(paper_id, paper)
|
|
1409
|
-
logger.success(f"{self.name}: Downloaded PDF, saved to storage")
|
|
1410
|
-
else:
|
|
1411
|
-
logger.warning(f"{self.name}: Failed to download PDF")
|
|
1412
|
-
finally:
|
|
1413
|
-
await self._browser_manager.close()
|
|
1414
|
-
else:
|
|
1415
|
-
logger.warning(f"{self.name}: No PDF URLs available for download")
|
|
1416
|
-
else:
|
|
1417
|
-
logger.info(f"{self.name}: PDF already in storage")
|
|
1418
|
-
|
|
1419
|
-
# Stage 4: Update project symlinks
|
|
1420
|
-
if project and project not in ["master", "MASTER"]:
|
|
1421
|
-
logger.info(f"{self.name}: \nStage 4: Updating project symlinks...")
|
|
1422
|
-
self._library_manager.update_symlink(
|
|
1423
|
-
master_storage_path=storage_path,
|
|
1424
|
-
project=project,
|
|
1425
|
-
)
|
|
1426
|
-
logger.success(f"{self.name}: Updated symlink in project: {project}")
|
|
1427
|
-
|
|
1428
|
-
logger.info(f"\n{'=' * 60}")
|
|
1429
|
-
logger.success(f"{self.name}: Paper processing complete")
|
|
1430
|
-
logger.info(f"{'=' * 60}\n")
|
|
1431
|
-
|
|
1432
|
-
return paper
|
|
1433
|
-
|
|
1434
|
-
def process_paper(
|
|
1435
|
-
self,
|
|
1436
|
-
title: Optional[str] = None,
|
|
1437
|
-
doi: Optional[str] = None,
|
|
1438
|
-
project: Optional[str] = None,
|
|
1439
|
-
) -> "Paper":
|
|
1440
|
-
"""
|
|
1441
|
-
Synchronous wrapper for process_paper_async.
|
|
1442
|
-
|
|
1443
|
-
See process_paper_async() for full documentation.
|
|
1444
|
-
"""
|
|
1445
|
-
return asyncio.run(
|
|
1446
|
-
self.process_paper_async(title=title, doi=doi, project=project)
|
|
1447
|
-
)
|
|
1448
|
-
|
|
1449
|
-
# =========================================================================
|
|
1450
|
-
# PIPELINE METHODS (Phase 3) - Parallel Papers Processing
|
|
1451
|
-
# =========================================================================
|
|
1452
|
-
|
|
1453
|
-
async def process_papers_async(
|
|
1454
|
-
self,
|
|
1455
|
-
papers: Union["Papers", List[str]],
|
|
1456
|
-
project: Optional[str] = None,
|
|
1457
|
-
max_concurrent: int = 3,
|
|
1458
|
-
) -> "Papers":
|
|
1459
|
-
"""
|
|
1460
|
-
Process multiple papers with controlled parallelism.
|
|
1461
|
-
|
|
1462
|
-
Each paper goes through complete sequential pipeline.
|
|
1463
|
-
Semaphore controls how many papers process concurrently.
|
|
1464
|
-
|
|
1465
|
-
Architecture:
|
|
1466
|
-
- Parallel papers (max_concurrent at a time)
|
|
1467
|
-
- Sequential stages per paper
|
|
1468
|
-
- Storage checks before each stage
|
|
1469
|
-
|
|
1470
|
-
Args:
|
|
1471
|
-
papers: Papers collection or list of DOIs
|
|
1472
|
-
project: Project name (uses self.project if None)
|
|
1473
|
-
max_concurrent: Maximum concurrent papers (default: 3)
|
|
1474
|
-
Set to 1 for purely sequential processing
|
|
1475
|
-
|
|
1476
|
-
Returns:
|
|
1477
|
-
Papers collection with processed papers
|
|
1478
|
-
|
|
1479
|
-
Examples:
|
|
1480
|
-
# Process Papers collection (parallel)
|
|
1481
|
-
papers = scholar.load_bibtex("papers.bib")
|
|
1482
|
-
processed = await scholar.process_papers_async(papers, max_concurrent=3)
|
|
1483
|
-
|
|
1484
|
-
# Process DOI list (sequential)
|
|
1485
|
-
dois = ["10.1038/...", "10.1016/...", "10.1109/..."]
|
|
1486
|
-
processed = await scholar.process_papers_async(dois, max_concurrent=1)
|
|
1487
|
-
"""
|
|
1488
|
-
from scitex.scholar.core.Papers import Papers
|
|
1489
|
-
|
|
1490
|
-
project = project or self.project
|
|
1491
|
-
|
|
1492
|
-
# Convert input to Papers collection
|
|
1493
|
-
if isinstance(papers, list):
|
|
1494
|
-
# List of DOI strings
|
|
1495
|
-
papers_list = []
|
|
1496
|
-
for doi in papers:
|
|
1497
|
-
from scitex.scholar.core.Paper import Paper
|
|
1498
|
-
|
|
1499
|
-
p = Paper()
|
|
1500
|
-
p.metadata.set_doi(doi)
|
|
1501
|
-
papers_list.append(p)
|
|
1502
|
-
papers = Papers(papers_list, project=project, config=self.config)
|
|
1503
|
-
|
|
1504
|
-
total = len(papers)
|
|
1505
|
-
logger.info(f"{self.name}: \n{'=' * 60}")
|
|
1506
|
-
logger.info(
|
|
1507
|
-
f"{self.name}: Processing {total} papers (max_concurrent={max_concurrent})"
|
|
1508
|
-
)
|
|
1509
|
-
logger.info(f"{self.name}: Project: {project}")
|
|
1510
|
-
logger.info(f"{self.name}: {'=' * 60}\n")
|
|
1511
|
-
|
|
1512
|
-
# Use semaphore for controlled parallelism
|
|
1513
|
-
semaphore = asyncio.Semaphore(max_concurrent)
|
|
1514
|
-
|
|
1515
|
-
async def process_with_semaphore(paper, index):
|
|
1516
|
-
"""Process one paper with semaphore control."""
|
|
1517
|
-
async with semaphore:
|
|
1518
|
-
logger.info(f"{self.name}: \n[{index}/{total}] Starting paper...")
|
|
1519
|
-
try:
|
|
1520
|
-
result = await self.process_paper_async(
|
|
1521
|
-
title=paper.metadata.basic.title,
|
|
1522
|
-
doi=paper.metadata.id.doi,
|
|
1523
|
-
project=project,
|
|
1524
|
-
)
|
|
1525
|
-
logger.success(f"{self.name}: [{index}/{total}] Completed")
|
|
1526
|
-
return result
|
|
1527
|
-
except Exception as e:
|
|
1528
|
-
logger.error(f"{self.name}: [{index}/{total}] Failed: {e}")
|
|
1529
|
-
return None
|
|
1530
|
-
|
|
1531
|
-
# Create tasks for all papers
|
|
1532
|
-
tasks = [process_with_semaphore(paper, i + 1) for i, paper in enumerate(papers)]
|
|
1533
|
-
|
|
1534
|
-
# Process with controlled parallelism
|
|
1535
|
-
results = await asyncio.gather(*tasks, return_exceptions=True)
|
|
1536
|
-
|
|
1537
|
-
# Filter successful results
|
|
1538
|
-
processed_papers = []
|
|
1539
|
-
errors = 0
|
|
1540
|
-
for i, result in enumerate(results):
|
|
1541
|
-
if isinstance(result, Exception):
|
|
1542
|
-
logger.error(f"{self.name}: Paper {i + 1} raised exception: {result}")
|
|
1543
|
-
errors += 1
|
|
1544
|
-
elif result is not None:
|
|
1545
|
-
processed_papers.append(result)
|
|
1546
|
-
|
|
1547
|
-
# Summary
|
|
1548
|
-
logger.info(f"{self.name}: \n{'=' * 60}")
|
|
1549
|
-
logger.info(f"{self.name}: Batch Processing Complete")
|
|
1550
|
-
logger.info(f"{self.name}: Total: {total}")
|
|
1551
|
-
logger.info(f"{self.name}: Successful: {len(processed_papers)}")
|
|
1552
|
-
logger.info(f"{self.name}: Failed: {total - len(processed_papers)}")
|
|
1553
|
-
logger.info(f"{self.name}: Errors: {errors}")
|
|
1554
|
-
logger.info(f"{self.name}: {'=' * 60}\n")
|
|
1555
|
-
|
|
1556
|
-
return Papers(processed_papers, project=project, config=self.config)
|
|
1557
|
-
|
|
1558
|
-
def process_papers(
|
|
1559
|
-
self,
|
|
1560
|
-
papers: Union["Papers", List[str]],
|
|
1561
|
-
project: Optional[str] = None,
|
|
1562
|
-
max_concurrent: int = 3,
|
|
1563
|
-
) -> "Papers":
|
|
1564
|
-
"""
|
|
1565
|
-
Synchronous wrapper for process_papers_async.
|
|
1566
|
-
|
|
1567
|
-
See process_papers_async() for full documentation.
|
|
1568
|
-
"""
|
|
1569
|
-
return asyncio.run(
|
|
1570
|
-
self.process_papers_async(
|
|
1571
|
-
papers=papers,
|
|
1572
|
-
project=project,
|
|
1573
|
-
max_concurrent=max_concurrent,
|
|
1574
|
-
)
|
|
1575
|
-
)
|
|
1576
|
-
|
|
1577
|
-
# =========================================================================
|
|
1578
|
-
# INTERNAL SERVICES (PRIVATE - users should not access these directly)
|
|
1579
|
-
# =========================================================================
|
|
1580
|
-
def _init_config(self, config):
|
|
1581
|
-
# Handle different config input types
|
|
1582
|
-
if config is None:
|
|
1583
|
-
return ScholarConfig.load() # Auto-detect config
|
|
1584
|
-
elif isinstance(config, (str, Path)):
|
|
1585
|
-
return ScholarConfig.from_yaml(config)
|
|
1586
|
-
elif isinstance(config, ScholarConfig):
|
|
1587
|
-
return config
|
|
1588
|
-
else:
|
|
1589
|
-
raise TypeError(f"Invalid config type: {type(config)}")
|
|
1590
|
-
|
|
1591
|
-
@property
|
|
1592
|
-
def _scholar_engine(self) -> ScholarEngine:
|
|
1593
|
-
"""Get Scholar engine for search and enrichment (PRIVATE)."""
|
|
1594
|
-
if not hasattr(self, "__scholar_engine") or self.__scholar_engine is None:
|
|
1595
|
-
self.__scholar_engine = ScholarEngine(config=self.config)
|
|
1596
|
-
return self.__scholar_engine
|
|
1597
|
-
|
|
1598
|
-
@property
|
|
1599
|
-
def _auth_manager(self) -> ScholarAuthManager:
|
|
1600
|
-
"""Get authentication manager service (PRIVATE)."""
|
|
1601
|
-
if not hasattr(self, "__auth_manager") or self.__auth_manager is None:
|
|
1602
|
-
self.__auth_manager = ScholarAuthManager()
|
|
1603
|
-
return self.__auth_manager
|
|
1604
|
-
|
|
1605
|
-
@property
|
|
1606
|
-
def _browser_manager(self) -> ScholarBrowserManager:
|
|
1607
|
-
"""Get browser manager service (PRIVATE)."""
|
|
1608
|
-
if not hasattr(self, "__browser_manager") or self.__browser_manager is None:
|
|
1609
|
-
self.__browser_manager = ScholarBrowserManager(
|
|
1610
|
-
auth_manager=self._auth_manager,
|
|
1611
|
-
chrome_profile_name="system",
|
|
1612
|
-
browser_mode=self.browser_mode,
|
|
1613
|
-
)
|
|
1614
|
-
return self.__browser_manager
|
|
1615
|
-
|
|
1616
|
-
@property
|
|
1617
|
-
def _library_manager(self) -> LibraryManager:
|
|
1618
|
-
"""Get library manager service - low-level operations (PRIVATE)."""
|
|
1619
|
-
if not hasattr(self, "__library_manager") or self.__library_manager is None:
|
|
1620
|
-
self.__library_manager = LibraryManager(
|
|
1621
|
-
project=self.project, config=self.config
|
|
1622
|
-
)
|
|
1623
|
-
return self.__library_manager
|
|
1624
|
-
|
|
1625
|
-
@property
|
|
1626
|
-
def _library(self) -> ScholarLibrary:
|
|
1627
|
-
"""Get Scholar library service - high-level operations (PRIVATE)."""
|
|
1628
|
-
if not hasattr(self, "__library") or self.__library is None:
|
|
1629
|
-
self.__library = ScholarLibrary(project=self.project, config=self.config)
|
|
1630
|
-
return self.__library
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
# Export all classes and functions
|
|
1634
125
|
__all__ = ["Scholar"]
|
|
1635
126
|
|
|
127
|
+
|
|
1636
128
|
if __name__ == "__main__":
|
|
1637
|
-
from
|
|
1638
|
-
from
|
|
129
|
+
from .Paper import Paper
|
|
130
|
+
from .Papers import Papers
|
|
1639
131
|
|
|
1640
132
|
def main():
|
|
1641
133
|
"""Demonstrate Scholar class usage - Clean API Demo."""
|
|
1642
134
|
print("\n" + "=" * 60)
|
|
1643
|
-
print("
|
|
135
|
+
print("Scholar Module Demo - Clean API")
|
|
1644
136
|
print("=" * 60 + "\n")
|
|
1645
137
|
|
|
1646
|
-
# ----------------------------------------
|
|
1647
138
|
# 1. Initialize Scholar
|
|
1648
|
-
|
|
1649
|
-
print("1️⃣ Initialize Scholar")
|
|
139
|
+
print("1. Initialize Scholar")
|
|
1650
140
|
print("-" * 60)
|
|
1651
141
|
scholar = Scholar(
|
|
1652
142
|
project="demo_project",
|
|
1653
143
|
project_description="Demo project for testing Scholar API",
|
|
1654
144
|
)
|
|
1655
|
-
print(
|
|
145
|
+
print("Scholar initialized")
|
|
1656
146
|
print(f" Project: {scholar.project}")
|
|
1657
|
-
print(f" Workspace: {scholar.get_workspace_dir()}")
|
|
1658
147
|
print()
|
|
1659
148
|
|
|
1660
|
-
#
|
|
149
|
+
# 2. Project Management
|
|
1661
150
|
print("2. Project Management:")
|
|
1662
151
|
try:
|
|
1663
|
-
# Create a new project
|
|
1664
152
|
project_dir = scholar._create_project_metadata(
|
|
1665
153
|
"neural_networks_2024",
|
|
1666
154
|
description="Collection of neural network papers from 2024",
|
|
1667
155
|
)
|
|
1668
|
-
print(
|
|
1669
|
-
print(f"
|
|
156
|
+
print(" Created project: neural_networks_2024")
|
|
157
|
+
print(f" Project directory: {project_dir}")
|
|
1670
158
|
|
|
1671
|
-
# List all projects
|
|
1672
159
|
projects = scholar.list_projects()
|
|
1673
|
-
print(f"
|
|
1674
|
-
for
|
|
1675
|
-
print(
|
|
1676
|
-
f" - {project['name']}: {project.get('description', 'No description')}"
|
|
1677
|
-
)
|
|
160
|
+
print(f" Total projects in library: {len(projects)}")
|
|
161
|
+
for proj in projects[:3]:
|
|
162
|
+
print(f" - {proj['name']}: {proj.get('description', 'No desc')}")
|
|
1678
163
|
if len(projects) > 3:
|
|
1679
164
|
print(f" ... and {len(projects) - 3} more")
|
|
1680
165
|
|
|
1681
166
|
except Exception as e:
|
|
1682
|
-
print(f"
|
|
167
|
+
print(f" Project management demo skipped: {e}")
|
|
1683
168
|
print()
|
|
1684
169
|
|
|
1685
|
-
#
|
|
170
|
+
# 3. Library Statistics
|
|
1686
171
|
print("3. Library Statistics:")
|
|
1687
172
|
try:
|
|
1688
173
|
stats = scholar.get_library_statistics()
|
|
1689
|
-
print(f"
|
|
1690
|
-
print(f"
|
|
1691
|
-
print(f"
|
|
1692
|
-
print(f"
|
|
174
|
+
print(f" Total projects: {stats['total_projects']}")
|
|
175
|
+
print(f" Total papers: {stats['total_papers']}")
|
|
176
|
+
print(f" Storage usage: {stats['storage_mb']:.2f} MB")
|
|
177
|
+
print(f" Library path: {stats['library_path']}")
|
|
1693
178
|
|
|
1694
179
|
except Exception as e:
|
|
1695
|
-
print(f"
|
|
180
|
+
print(f" Library statistics demo skipped: {e}")
|
|
1696
181
|
print()
|
|
1697
182
|
|
|
1698
|
-
#
|
|
183
|
+
# 4. Working with Papers
|
|
1699
184
|
print("4. Working with Papers:")
|
|
1700
|
-
|
|
1701
|
-
# Create some sample papers with Pydantic structure
|
|
1702
185
|
p1 = Paper()
|
|
1703
186
|
p1.metadata.basic.title = "Vision Transformer: An Image Is Worth 16x16 Words"
|
|
1704
187
|
p1.metadata.basic.authors = ["Dosovitskiy, Alexey", "Beyer, Lucas"]
|
|
1705
188
|
p1.metadata.basic.year = 2021
|
|
1706
|
-
p1.metadata.basic.keywords = [
|
|
1707
|
-
"vision transformer",
|
|
1708
|
-
"computer vision",
|
|
1709
|
-
"attention",
|
|
1710
|
-
]
|
|
1711
189
|
p1.metadata.publication.journal = "ICLR"
|
|
1712
190
|
p1.metadata.set_doi("10.48550/arXiv.2010.11929")
|
|
1713
|
-
p1.container.projects = ["neural_networks_2024"]
|
|
1714
191
|
|
|
1715
|
-
|
|
1716
|
-
p2.metadata.basic.title = "Scaling Laws for Neural Language Models"
|
|
1717
|
-
p2.metadata.basic.authors = ["Kaplan, Jared", "McCandlish, Sam"]
|
|
1718
|
-
p2.metadata.basic.year = 2020
|
|
1719
|
-
p2.metadata.basic.keywords = ["scaling laws", "language models", "GPT"]
|
|
1720
|
-
p2.metadata.publication.journal = "arXiv preprint"
|
|
1721
|
-
p2.metadata.set_doi("10.48550/arXiv.2001.08361")
|
|
1722
|
-
p2.container.projects = ["neural_networks_2024"]
|
|
1723
|
-
|
|
1724
|
-
sample_papers = [p1, p2]
|
|
1725
|
-
|
|
1726
|
-
# Create Papers collection
|
|
192
|
+
sample_papers = [p1]
|
|
1727
193
|
papers = Papers(
|
|
1728
194
|
sample_papers,
|
|
1729
195
|
project="neural_networks_2024",
|
|
1730
196
|
config=scholar.config,
|
|
1731
197
|
)
|
|
1732
|
-
print(f"
|
|
1733
|
-
|
|
1734
|
-
# Use Scholar to work with the collection
|
|
1735
|
-
# Switch project by creating new instance (cleaner pattern)
|
|
1736
|
-
scholar = Scholar(project="neural_networks_2024")
|
|
1737
|
-
print(f" 🎯 Set Scholar project to: {scholar.project}")
|
|
1738
|
-
print()
|
|
1739
|
-
|
|
1740
|
-
# Demonstrate DOI resolution workflow
|
|
1741
|
-
print("5. Scholar Workflow Integration:")
|
|
1742
|
-
try:
|
|
1743
|
-
# Create a sample BibTeX content for demonstration
|
|
1744
|
-
sample_bibtex = """
|
|
1745
|
-
@article{sample2024,
|
|
1746
|
-
title = {Sample Paper for Demo},
|
|
1747
|
-
author = {Demo, Author},
|
|
1748
|
-
year = {2024},
|
|
1749
|
-
journal = {Demo Journal}
|
|
1750
|
-
}
|
|
1751
|
-
"""
|
|
1752
|
-
|
|
1753
|
-
# Demonstrate BibTeX loading
|
|
1754
|
-
papers_from_bibtex = scholar.load_bibtex(sample_bibtex.strip())
|
|
1755
|
-
print(f" 📄 Loaded {len(papers_from_bibtex)} papers from BibTeX")
|
|
1756
|
-
|
|
1757
|
-
# Demonstrate project loading
|
|
1758
|
-
if scholar.project:
|
|
1759
|
-
try:
|
|
1760
|
-
project_papers = scholar.load_project()
|
|
1761
|
-
print(
|
|
1762
|
-
f" 📂 Loaded {len(project_papers)} papers from current project"
|
|
1763
|
-
)
|
|
1764
|
-
except:
|
|
1765
|
-
print(f" 📂 Current project is empty or doesn't exist yet")
|
|
1766
|
-
|
|
1767
|
-
except Exception as e:
|
|
1768
|
-
print(f" ⚠️ Workflow demo partially skipped: {e}")
|
|
1769
|
-
print()
|
|
1770
|
-
|
|
1771
|
-
# Demonstrate search capabilities
|
|
1772
|
-
print("6. Search Capabilities:")
|
|
1773
|
-
try:
|
|
1774
|
-
# Search across projects
|
|
1775
|
-
search_results = scholar.search_across_projects("transformer")
|
|
1776
|
-
print(
|
|
1777
|
-
f" 🔍 Search for 'transformer': {len(search_results)} results across all projects"
|
|
1778
|
-
)
|
|
1779
|
-
|
|
1780
|
-
# Search in current library (existing papers)
|
|
1781
|
-
library_search = scholar.search_library("vision")
|
|
1782
|
-
print(f" 🔍 Library search for 'vision': {len(library_search)} results")
|
|
1783
|
-
|
|
1784
|
-
except Exception as e:
|
|
1785
|
-
print(f" ⚠️ Search demo skipped: {e}")
|
|
1786
|
-
print()
|
|
1787
|
-
|
|
1788
|
-
# Demonstrate configuration access
|
|
1789
|
-
print("7. Configuration Management:")
|
|
1790
|
-
print(f" ⚙️ Scholar directory: {scholar.config.paths.scholar_dir}")
|
|
1791
|
-
print(f" ⚙️ Library directory: {scholar.config.get_library_project_dir()}")
|
|
1792
|
-
print(
|
|
1793
|
-
f" ⚙️ Debug mode: {scholar.config.resolve('debug_mode', default=False)}"
|
|
1794
|
-
)
|
|
198
|
+
print(f" Created collection with {len(papers)} papers")
|
|
1795
199
|
print()
|
|
1796
200
|
|
|
1797
|
-
#
|
|
1798
|
-
print("
|
|
1799
|
-
print(f"
|
|
1800
|
-
print(f"
|
|
1801
|
-
print(f" 🔧 Browser Manager: {type(scholar._browser_manager).__name__}")
|
|
1802
|
-
print(f" 🔧 Library Manager: {type(scholar._library_manager).__name__}")
|
|
201
|
+
# 5. Configuration
|
|
202
|
+
print("5. Configuration Management:")
|
|
203
|
+
print(f" Scholar directory: {scholar.config.paths.scholar_dir}")
|
|
204
|
+
print(f" Library directory: {scholar.config.get_library_project_dir()}")
|
|
1803
205
|
print()
|
|
1804
206
|
|
|
1805
|
-
#
|
|
1806
|
-
print("
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
# Create a temporary backup location
|
|
1812
|
-
backup_dir = Path(tempfile.mkdtemp()) / "scholar_backup"
|
|
1813
|
-
backup_info = scholar.backup_library(backup_dir)
|
|
1814
|
-
print(f" 💾 Library backup created:")
|
|
1815
|
-
print(f" 📁 Location: {backup_info['backup']}")
|
|
1816
|
-
print(f" 📊 Size: {backup_info['size_mb']:.2f} MB")
|
|
1817
|
-
print(f" 🕐 Timestamp: {backup_info['timestamp']}")
|
|
1818
|
-
|
|
1819
|
-
# Clean up
|
|
1820
|
-
import shutil
|
|
1821
|
-
|
|
1822
|
-
shutil.rmtree(backup_dir, ignore_errors=True)
|
|
1823
|
-
|
|
1824
|
-
except Exception as e:
|
|
1825
|
-
print(f" ⚠️ Backup demo skipped: {e}")
|
|
207
|
+
# 6. Service Components
|
|
208
|
+
print("6. Service Components (Internal):")
|
|
209
|
+
print(f" Scholar Engine: {type(scholar._scholar_engine).__name__}")
|
|
210
|
+
print(f" Auth Manager: {type(scholar._auth_manager).__name__}")
|
|
211
|
+
print(f" Browser Manager: {type(scholar._browser_manager).__name__}")
|
|
212
|
+
print(f" Library Manager: {type(scholar._library_manager).__name__}")
|
|
1826
213
|
print()
|
|
1827
214
|
|
|
1828
|
-
print("Scholar
|
|
1829
|
-
print()
|
|
1830
|
-
print("💡 Key Scholar Capabilities:")
|
|
1831
|
-
print(" • Global library management and statistics")
|
|
1832
|
-
print(" • Project creation and organization")
|
|
1833
|
-
print(" • Cross-project search and analysis")
|
|
1834
|
-
print(" • Integration with Paper and Papers classes")
|
|
1835
|
-
print(" • DOI resolution and metadata enrichment")
|
|
1836
|
-
print(" • PDF download and browser automation")
|
|
1837
|
-
print(" • Backup and maintenance operations")
|
|
1838
|
-
print()
|
|
215
|
+
print("Scholar demo completed!")
|
|
1839
216
|
|
|
1840
217
|
main()
|
|
1841
218
|
|
|
1842
|
-
# python -m scitex.scholar.core.Scholar
|
|
1843
219
|
|
|
1844
220
|
# EOF
|