Latest commit

History

33 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Job Lead Scout

Job Lead Scout is a FastAPI web application that retrieves job listings from Adzuna using user-provided keywords and locations. It normalizes and stores the results in SQLite, prevents duplicate listings, and displays job leads through a paginated web dashboard.

Users can organize leads by status, export all or filtered results to CSV, archive leads, and permanently delete archived records. The project builds on the manual workflow of my earlier Job Tracker project by automating job-lead discovery.

MVP Features

  • ☑ Retrieve job listings from the Adzuna API
  • ☑ Store essential job-lead information in SQLite
  • ☑ Prevent duplicate listings from being saved
  • ☑ Search using user-provided keywords and locations
  • ☑ Display leads through a paginated web dashboard
  • ☑ Filter leads by status
  • ☑ Update leads as new, saved, applied, or archived
  • ☑ Export all or status-filtered leads to CSV
  • ☑ Permanently delete archived leads with confirmation
  • ☑ Protect active leads from permanent deletion

Technology

  • Python 3.13+
  • FastAPI
  • SQLite
  • Jinja2
  • HTML and CSS
  • JavaScript
  • HTTPX
  • pytest
  • uv

Requirements

Before running the application, you will need:

  • Python 3.13 or newer
  • The uv package manager
  • An Adzuna developer account with an application ID and API key

Setup

Clone the repository:

git clone https://github.com/BerryFarm97/JobLeadScout.git
cd JobLeadScout

Install the project dependencies:

uv sync

Copy .env.example to a new file named .env, then add your Adzuna credentials:

ADZUNA_APP_ID=your_application_idADZUNA_APP_KEY=your_api_key

The .env file and local SQLite databases are excluded from version control.

Running the Application

Start the development server:

uv run fastapi dev

Open the dashboard at:

http://127.0.0.1:8000

FastAPI’s interactive API documentation is available at:

http://127.0.0.1:8000/docs

The SQLite database and required table are created automatically when the application starts.

Using Job Lead Scout

  1. Enter job-search keywords and a location.
  2. Select Refresh Jobs to retrieve current listings from Adzuna.
  3. Review the imported leads on the dashboard.
  4. Change a lead’s status to new, saved, applied, or archived.
  5. Filter the dashboard using the status tabs.
  6. Export all visible categories or the currently filtered status to CSV.
  7. Permanently delete an archived lead using its trash button.

Archived leads must be deleted intentionally through a confirmation prompt. The API also prevents non-archived leads from being permanently deleted.

API Endpoints

MethodEndpointPurpose
GET/Display the web dashboard
GET/healthCheck application health
GET/job-leadsReturn all stored job leads
POST/job-leads/refreshRetrieve and import listings from Adzuna
PATCH/job-leads/{job_lead_id}/statusUpdate a lead’s status
DELETE/job-leads/{job_lead_id}Permanently delete an archived lead
GET/job-leads/exportDownload all or status-filtered leads as CSV

Testing

Run the complete automated test suite:

uv run pytest -v

The current suite contains 40 tests covering database operations, Adzuna normalization and importing, API behavior, pagination, status updates, CSV generation, filtered exports, dashboard totals, and protected deletion.

Possible Future Enhancements

  • ☐ Classify listings as remote, local, hybrid, outside the preferred area, or unknown
  • ☐ Add explainable match estimates using a user-defined skills profile
  • ☐ Add configurable search preferences
  • ☐ Deploy the application with persistent database storage

Dashboard

Job Lead Scout dashboard

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Latest commit

History

33 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Job Lead Scout

Job Lead Scout is a FastAPI web application that retrieves job listings from Adzuna using user-provided keywords and locations. It normalizes and stores the results in SQLite, prevents duplicate listings, and displays job leads through a paginated web dashboard.

Users can organize leads by status, export all or filtered results to CSV, archive leads, and permanently delete archived records. The project builds on the manual workflow of my earlier Job Tracker project by automating job-lead discovery.

MVP Features

  • ☑ Retrieve job listings from the Adzuna API
  • ☑ Store essential job-lead information in SQLite
  • ☑ Prevent duplicate listings from being saved
  • ☑ Search using user-provided keywords and locations
  • ☑ Display leads through a paginated web dashboard
  • ☑ Filter leads by status
  • ☑ Update leads as new, saved, applied, or archived
  • ☑ Export all or status-filtered leads to CSV
  • ☑ Permanently delete archived leads with confirmation
  • ☑ Protect active leads from permanent deletion

Technology

  • Python 3.13+
  • FastAPI
  • SQLite
  • Jinja2
  • HTML and CSS
  • JavaScript
  • HTTPX
  • pytest
  • uv

Requirements

Before running the application, you will need:

  • Python 3.13 or newer
  • The uv package manager
  • An Adzuna developer account with an application ID and API key

Setup

Clone the repository:

git clone https://github.com/BerryFarm97/JobLeadScout.git
cd JobLeadScout

Install the project dependencies:

uv sync

Copy .env.example to a new file named .env, then add your Adzuna credentials:

ADZUNA_APP_ID=your_application_idADZUNA_APP_KEY=your_api_key

The .env file and local SQLite databases are excluded from version control.

Running the Application

Start the development server:

uv run fastapi dev

Open the dashboard at:

http://127.0.0.1:8000

FastAPI’s interactive API documentation is available at:

http://127.0.0.1:8000/docs

The SQLite database and required table are created automatically when the application starts.

Using Job Lead Scout

  1. Enter job-search keywords and a location.
  2. Select Refresh Jobs to retrieve current listings from Adzuna.
  3. Review the imported leads on the dashboard.
  4. Change a lead’s status to new, saved, applied, or archived.
  5. Filter the dashboard using the status tabs.
  6. Export all visible categories or the currently filtered status to CSV.
  7. Permanently delete an archived lead using its trash button.

Archived leads must be deleted intentionally through a confirmation prompt. The API also prevents non-archived leads from being permanently deleted.

API Endpoints

MethodEndpointPurpose
GET/Display the web dashboard
GET/healthCheck application health
GET/job-leadsReturn all stored job leads
POST/job-leads/refreshRetrieve and import listings from Adzuna
PATCH/job-leads/{job_lead_id}/statusUpdate a lead’s status
DELETE/job-leads/{job_lead_id}Permanently delete an archived lead
GET/job-leads/exportDownload all or status-filtered leads as CSV

Testing

Run the complete automated test suite:

uv run pytest -v

The current suite contains 40 tests covering database operations, Adzuna normalization and importing, API behavior, pagination, status updates, CSV generation, filtered exports, dashboard totals, and protected deletion.

Possible Future Enhancements

  • ☐ Classify listings as remote, local, hybrid, outside the preferred area, or unknown
  • ☐ Add explainable match estimates using a user-defined skills profile
  • ☐ Add configurable search preferences
  • ☐ Deploy the application with persistent database storage

Dashboard

Job Lead Scout dashboard

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

33 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Job Lead Scout

Job Lead Scout is a FastAPI web application that retrieves job listings from Adzuna using user-provided keywords and locations. It normalizes and stores the results in SQLite, prevents duplicate listings, and displays job leads through a paginated web dashboard.

Users can organize leads by status, export all or filtered results to CSV, archive leads, and permanently delete archived records. The project builds on the manual workflow of my earlier Job Tracker project by automating job-lead discovery.

MVP Features

  • ☑ Retrieve job listings from the Adzuna API
  • ☑ Store essential job-lead information in SQLite
  • ☑ Prevent duplicate listings from being saved
  • ☑ Search using user-provided keywords and locations
  • ☑ Display leads through a paginated web dashboard
  • ☑ Filter leads by status
  • ☑ Update leads as new, saved, applied, or archived
  • ☑ Export all or status-filtered leads to CSV
  • ☑ Permanently delete archived leads with confirmation
  • ☑ Protect active leads from permanent deletion

Technology

  • Python 3.13+
  • FastAPI
  • SQLite
  • Jinja2
  • HTML and CSS
  • JavaScript
  • HTTPX
  • pytest
  • uv

Requirements

Before running the application, you will need:

  • Python 3.13 or newer
  • The uv package manager
  • An Adzuna developer account with an application ID and API key

Setup

Clone the repository:

git clone https://github.com/BerryFarm97/JobLeadScout.git
cd JobLeadScout

Install the project dependencies:

uv sync

Copy .env.example to a new file named .env, then add your Adzuna credentials:

ADZUNA_APP_ID=your_application_idADZUNA_APP_KEY=your_api_key

The .env file and local SQLite databases are excluded from version control.

Running the Application

Start the development server:

uv run fastapi dev

Open the dashboard at:

http://127.0.0.1:8000

FastAPI’s interactive API documentation is available at:

http://127.0.0.1:8000/docs

The SQLite database and required table are created automatically when the application starts.

Using Job Lead Scout

  1. Enter job-search keywords and a location.
  2. Select Refresh Jobs to retrieve current listings from Adzuna.
  3. Review the imported leads on the dashboard.
  4. Change a lead’s status to new, saved, applied, or archived.
  5. Filter the dashboard using the status tabs.
  6. Export all visible categories or the currently filtered status to CSV.
  7. Permanently delete an archived lead using its trash button.

Archived leads must be deleted intentionally through a confirmation prompt. The API also prevents non-archived leads from being permanently deleted.

API Endpoints

MethodEndpointPurpose
GET/Display the web dashboard
GET/healthCheck application health
GET/job-leadsReturn all stored job leads
POST/job-leads/refreshRetrieve and import listings from Adzuna
PATCH/job-leads/{job_lead_id}/statusUpdate a lead’s status
DELETE/job-leads/{job_lead_id}Permanently delete an archived lead
GET/job-leads/exportDownload all or status-filtered leads as CSV

Testing

Run the complete automated test suite:

uv run pytest -v

The current suite contains 40 tests covering database operations, Adzuna normalization and importing, API behavior, pagination, status updates, CSV generation, filtered exports, dashboard totals, and protected deletion.

Possible Future Enhancements

  • ☐ Classify listings as remote, local, hybrid, outside the preferred area, or unknown
  • ☐ Add explainable match estimates using a user-defined skills profile
  • ☐ Add configurable search preferences
  • ☐ Deploy the application with persistent database storage

Dashboard

Job Lead Scout dashboard

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

33 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Job Lead Scout

Job Lead Scout is a FastAPI web application that retrieves job listings from Adzuna using user-provided keywords and locations. It normalizes and stores the results in SQLite, prevents duplicate listings, and displays job leads through a paginated web dashboard.

Users can organize leads by status, export all or filtered results to CSV, archive leads, and permanently delete archived records. The project builds on the manual workflow of my earlier Job Tracker project by automating job-lead discovery.

MVP Features

  • ☑ Retrieve job listings from the Adzuna API
  • ☑ Store essential job-lead information in SQLite
  • ☑ Prevent duplicate listings from being saved
  • ☑ Search using user-provided keywords and locations
  • ☑ Display leads through a paginated web dashboard
  • ☑ Filter leads by status
  • ☑ Update leads as new, saved, applied, or archived
  • ☑ Export all or status-filtered leads to CSV
  • ☑ Permanently delete archived leads with confirmation
  • ☑ Protect active leads from permanent deletion

Technology

  • Python 3.13+
  • FastAPI
  • SQLite
  • Jinja2
  • HTML and CSS
  • JavaScript
  • HTTPX
  • pytest
  • uv

Requirements

Before running the application, you will need:

  • Python 3.13 or newer
  • The uv package manager
  • An Adzuna developer account with an application ID and API key

Setup

Clone the repository:

git clone https://github.com/BerryFarm97/JobLeadScout.git
cd JobLeadScout

Install the project dependencies:

uv sync

Copy .env.example to a new file named .env, then add your Adzuna credentials:

ADZUNA_APP_ID=your_application_idADZUNA_APP_KEY=your_api_key

The .env file and local SQLite databases are excluded from version control.

Running the Application

Start the development server:

uv run fastapi dev

Open the dashboard at:

http://127.0.0.1:8000

FastAPI’s interactive API documentation is available at:

http://127.0.0.1:8000/docs

The SQLite database and required table are created automatically when the application starts.

Using Job Lead Scout

  1. Enter job-search keywords and a location.
  2. Select Refresh Jobs to retrieve current listings from Adzuna.
  3. Review the imported leads on the dashboard.
  4. Change a lead’s status to new, saved, applied, or archived.
  5. Filter the dashboard using the status tabs.
  6. Export all visible categories or the currently filtered status to CSV.
  7. Permanently delete an archived lead using its trash button.

Archived leads must be deleted intentionally through a confirmation prompt. The API also prevents non-archived leads from being permanently deleted.

API Endpoints

MethodEndpointPurpose
GET/Display the web dashboard
GET/healthCheck application health
GET/job-leadsReturn all stored job leads
POST/job-leads/refreshRetrieve and import listings from Adzuna
PATCH/job-leads/{job_lead_id}/statusUpdate a lead’s status
DELETE/job-leads/{job_lead_id}Permanently delete an archived lead
GET/job-leads/exportDownload all or status-filtered leads as CSV

Testing

Run the complete automated test suite:

uv run pytest -v

The current suite contains 40 tests covering database operations, Adzuna normalization and importing, API behavior, pagination, status updates, CSV generation, filtered exports, dashboard totals, and protected deletion.

Possible Future Enhancements

  • ☐ Classify listings as remote, local, hybrid, outside the preferred area, or unknown
  • ☐ Add explainable match estimates using a user-defined skills profile
  • ☐ Add configurable search preferences
  • ☐ Deploy the application with persistent database storage

Dashboard

Job Lead Scout dashboard

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Latest commit

History

33 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Job Lead Scout

Job Lead Scout is a FastAPI web application that retrieves job listings from Adzuna using user-provided keywords and locations. It normalizes and stores the results in SQLite, prevents duplicate listings, and displays job leads through a paginated web dashboard.

Users can organize leads by status, export all or filtered results to CSV, archive leads, and permanently delete archived records. The project builds on the manual workflow of my earlier Job Tracker project by automating job-lead discovery.

MVP Features

  • ☑ Retrieve job listings from the Adzuna API
  • ☑ Store essential job-lead information in SQLite
  • ☑ Prevent duplicate listings from being saved
  • ☑ Search using user-provided keywords and locations
  • ☑ Display leads through a paginated web dashboard
  • ☑ Filter leads by status
  • ☑ Update leads as new, saved, applied, or archived
  • ☑ Export all or status-filtered leads to CSV
  • ☑ Permanently delete archived leads with confirmation
  • ☑ Protect active leads from permanent deletion

Technology

  • Python 3.13+
  • FastAPI
  • SQLite
  • Jinja2
  • HTML and CSS
  • JavaScript
  • HTTPX
  • pytest
  • uv

Requirements

Before running the application, you will need:

  • Python 3.13 or newer
  • The uv package manager
  • An Adzuna developer account with an application ID and API key

Setup

Clone the repository:

git clone https://github.com/BerryFarm97/JobLeadScout.git
cd JobLeadScout

Install the project dependencies:

uv sync

Copy .env.example to a new file named .env, then add your Adzuna credentials:

ADZUNA_APP_ID=your_application_idADZUNA_APP_KEY=your_api_key

The .env file and local SQLite databases are excluded from version control.

Running the Application

Start the development server:

uv run fastapi dev

Open the dashboard at:

http://127.0.0.1:8000

FastAPI’s interactive API documentation is available at:

http://127.0.0.1:8000/docs

The SQLite database and required table are created automatically when the application starts.

Using Job Lead Scout

  1. Enter job-search keywords and a location.
  2. Select Refresh Jobs to retrieve current listings from Adzuna.
  3. Review the imported leads on the dashboard.
  4. Change a lead’s status to new, saved, applied, or archived.
  5. Filter the dashboard using the status tabs.
  6. Export all visible categories or the currently filtered status to CSV.
  7. Permanently delete an archived lead using its trash button.

Archived leads must be deleted intentionally through a confirmation prompt. The API also prevents non-archived leads from being permanently deleted.

API Endpoints

MethodEndpointPurpose
GET/Display the web dashboard
GET/healthCheck application health
GET/job-leadsReturn all stored job leads
POST/job-leads/refreshRetrieve and import listings from Adzuna
PATCH/job-leads/{job_lead_id}/statusUpdate a lead’s status
DELETE/job-leads/{job_lead_id}Permanently delete an archived lead
GET/job-leads/exportDownload all or status-filtered leads as CSV

Testing

Run the complete automated test suite:

uv run pytest -v

The current suite contains 40 tests covering database operations, Adzuna normalization and importing, API behavior, pagination, status updates, CSV generation, filtered exports, dashboard totals, and protected deletion.

Possible Future Enhancements

  • ☐ Classify listings as remote, local, hybrid, outside the preferred area, or unknown
  • ☐ Add explainable match estimates using a user-defined skills profile
  • ☐ Add configurable search preferences
  • ☐ Deploy the application with persistent database storage

Dashboard

Job Lead Scout dashboard

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

33 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Job Lead Scout

Job Lead Scout is a FastAPI web application that retrieves job listings from Adzuna using user-provided keywords and locations. It normalizes and stores the results in SQLite, prevents duplicate listings, and displays job leads through a paginated web dashboard.

Users can organize leads by status, export all or filtered results to CSV, archive leads, and permanently delete archived records. The project builds on the manual workflow of my earlier Job Tracker project by automating job-lead discovery.

MVP Features

  • ☑ Retrieve job listings from the Adzuna API
  • ☑ Store essential job-lead information in SQLite
  • ☑ Prevent duplicate listings from being saved
  • ☑ Search using user-provided keywords and locations
  • ☑ Display leads through a paginated web dashboard
  • ☑ Filter leads by status
  • ☑ Update leads as new, saved, applied, or archived
  • ☑ Export all or status-filtered leads to CSV
  • ☑ Permanently delete archived leads with confirmation
  • ☑ Protect active leads from permanent deletion

Technology

  • Python 3.13+
  • FastAPI
  • SQLite
  • Jinja2
  • HTML and CSS
  • JavaScript
  • HTTPX
  • pytest
  • uv

Requirements

Before running the application, you will need:

  • Python 3.13 or newer
  • The uv package manager
  • An Adzuna developer account with an application ID and API key

Setup

Clone the repository:

git clone https://github.com/BerryFarm97/JobLeadScout.git
cd JobLeadScout

Install the project dependencies:

uv sync

Copy .env.example to a new file named .env, then add your Adzuna credentials:

ADZUNA_APP_ID=your_application_idADZUNA_APP_KEY=your_api_key

The .env file and local SQLite databases are excluded from version control.

Running the Application

Start the development server:

uv run fastapi dev

Open the dashboard at:

http://127.0.0.1:8000

FastAPI’s interactive API documentation is available at:

http://127.0.0.1:8000/docs

The SQLite database and required table are created automatically when the application starts.

Using Job Lead Scout

  1. Enter job-search keywords and a location.
  2. Select Refresh Jobs to retrieve current listings from Adzuna.
  3. Review the imported leads on the dashboard.
  4. Change a lead’s status to new, saved, applied, or archived.
  5. Filter the dashboard using the status tabs.
  6. Export all visible categories or the currently filtered status to CSV.
  7. Permanently delete an archived lead using its trash button.

Archived leads must be deleted intentionally through a confirmation prompt. The API also prevents non-archived leads from being permanently deleted.

API Endpoints

MethodEndpointPurpose
GET/Display the web dashboard
GET/healthCheck application health
GET/job-leadsReturn all stored job leads
POST/job-leads/refreshRetrieve and import listings from Adzuna
PATCH/job-leads/{job_lead_id}/statusUpdate a lead’s status
DELETE/job-leads/{job_lead_id}Permanently delete an archived lead
GET/job-leads/exportDownload all or status-filtered leads as CSV

Testing

Run the complete automated test suite:

uv run pytest -v

The current suite contains 40 tests covering database operations, Adzuna normalization and importing, API behavior, pagination, status updates, CSV generation, filtered exports, dashboard totals, and protected deletion.

Possible Future Enhancements

  • ☐ Classify listings as remote, local, hybrid, outside the preferred area, or unknown
  • ☐ Add explainable match estimates using a user-defined skills profile
  • ☐ Add configurable search preferences
  • ☐ Deploy the application with persistent database storage

Dashboard

Job Lead Scout dashboard

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

33 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Job Lead Scout

Job Lead Scout is a FastAPI web application that retrieves job listings from Adzuna using user-provided keywords and locations. It normalizes and stores the results in SQLite, prevents duplicate listings, and displays job leads through a paginated web dashboard.

Users can organize leads by status, export all or filtered results to CSV, archive leads, and permanently delete archived records. The project builds on the manual workflow of my earlier Job Tracker project by automating job-lead discovery.

MVP Features

  • ☑ Retrieve job listings from the Adzuna API
  • ☑ Store essential job-lead information in SQLite
  • ☑ Prevent duplicate listings from being saved
  • ☑ Search using user-provided keywords and locations
  • ☑ Display leads through a paginated web dashboard
  • ☑ Filter leads by status
  • ☑ Update leads as new, saved, applied, or archived
  • ☑ Export all or status-filtered leads to CSV
  • ☑ Permanently delete archived leads with confirmation
  • ☑ Protect active leads from permanent deletion

Technology

  • Python 3.13+
  • FastAPI
  • SQLite
  • Jinja2
  • HTML and CSS
  • JavaScript
  • HTTPX
  • pytest
  • uv

Requirements

Before running the application, you will need:

  • Python 3.13 or newer
  • The uv package manager
  • An Adzuna developer account with an application ID and API key

Setup

Clone the repository:

git clone https://github.com/BerryFarm97/JobLeadScout.git
cd JobLeadScout

Install the project dependencies:

uv sync

Copy .env.example to a new file named .env, then add your Adzuna credentials:

ADZUNA_APP_ID=your_application_idADZUNA_APP_KEY=your_api_key

The .env file and local SQLite databases are excluded from version control.

Running the Application

Start the development server:

uv run fastapi dev

Open the dashboard at:

http://127.0.0.1:8000

FastAPI’s interactive API documentation is available at:

http://127.0.0.1:8000/docs

The SQLite database and required table are created automatically when the application starts.

Using Job Lead Scout

  1. Enter job-search keywords and a location.
  2. Select Refresh Jobs to retrieve current listings from Adzuna.
  3. Review the imported leads on the dashboard.
  4. Change a lead’s status to new, saved, applied, or archived.
  5. Filter the dashboard using the status tabs.
  6. Export all visible categories or the currently filtered status to CSV.
  7. Permanently delete an archived lead using its trash button.

Archived leads must be deleted intentionally through a confirmation prompt. The API also prevents non-archived leads from being permanently deleted.

API Endpoints

MethodEndpointPurpose
GET/Display the web dashboard
GET/healthCheck application health
GET/job-leadsReturn all stored job leads
POST/job-leads/refreshRetrieve and import listings from Adzuna
PATCH/job-leads/{job_lead_id}/statusUpdate a lead’s status
DELETE/job-leads/{job_lead_id}Permanently delete an archived lead
GET/job-leads/exportDownload all or status-filtered leads as CSV

Testing

Run the complete automated test suite:

uv run pytest -v

The current suite contains 40 tests covering database operations, Adzuna normalization and importing, API behavior, pagination, status updates, CSV generation, filtered exports, dashboard totals, and protected deletion.

Possible Future Enhancements

  • ☐ Classify listings as remote, local, hybrid, outside the preferred area, or unknown
  • ☐ Add explainable match estimates using a user-defined skills profile
  • ☐ Add configurable search preferences
  • ☐ Deploy the application with persistent database storage

Dashboard

Job Lead Scout dashboard

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Latest commit

History

33 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Job Lead Scout

Job Lead Scout is a FastAPI web application that retrieves job listings from Adzuna using user-provided keywords and locations. It normalizes and stores the results in SQLite, prevents duplicate listings, and displays job leads through a paginated web dashboard.

Users can organize leads by status, export all or filtered results to CSV, archive leads, and permanently delete archived records. The project builds on the manual workflow of my earlier Job Tracker project by automating job-lead discovery.

MVP Features

  • ☑ Retrieve job listings from the Adzuna API
  • ☑ Store essential job-lead information in SQLite
  • ☑ Prevent duplicate listings from being saved
  • ☑ Search using user-provided keywords and locations
  • ☑ Display leads through a paginated web dashboard
  • ☑ Filter leads by status
  • ☑ Update leads as new, saved, applied, or archived
  • ☑ Export all or status-filtered leads to CSV
  • ☑ Permanently delete archived leads with confirmation
  • ☑ Protect active leads from permanent deletion

Technology

  • Python 3.13+
  • FastAPI
  • SQLite
  • Jinja2
  • HTML and CSS
  • JavaScript
  • HTTPX
  • pytest
  • uv

Requirements

Before running the application, you will need:

  • Python 3.13 or newer
  • The uv package manager
  • An Adzuna developer account with an application ID and API key

Setup

Clone the repository:

git clone https://github.com/BerryFarm97/JobLeadScout.git
cd JobLeadScout

Install the project dependencies:

uv sync

Copy .env.example to a new file named .env, then add your Adzuna credentials:

ADZUNA_APP_ID=your_application_idADZUNA_APP_KEY=your_api_key

The .env file and local SQLite databases are excluded from version control.

Running the Application

Start the development server:

uv run fastapi dev

Open the dashboard at:

http://127.0.0.1:8000

FastAPI’s interactive API documentation is available at:

http://127.0.0.1:8000/docs

The SQLite database and required table are created automatically when the application starts.

Using Job Lead Scout

  1. Enter job-search keywords and a location.
  2. Select Refresh Jobs to retrieve current listings from Adzuna.
  3. Review the imported leads on the dashboard.
  4. Change a lead’s status to new, saved, applied, or archived.
  5. Filter the dashboard using the status tabs.
  6. Export all visible categories or the currently filtered status to CSV.
  7. Permanently delete an archived lead using its trash button.

Archived leads must be deleted intentionally through a confirmation prompt. The API also prevents non-archived leads from being permanently deleted.

API Endpoints

MethodEndpointPurpose
GET/Display the web dashboard
GET/healthCheck application health
GET/job-leadsReturn all stored job leads
POST/job-leads/refreshRetrieve and import listings from Adzuna
PATCH/job-leads/{job_lead_id}/statusUpdate a lead’s status
DELETE/job-leads/{job_lead_id}Permanently delete an archived lead
GET/job-leads/exportDownload all or status-filtered leads as CSV

Testing

Run the complete automated test suite:

uv run pytest -v

The current suite contains 40 tests covering database operations, Adzuna normalization and importing, API behavior, pagination, status updates, CSV generation, filtered exports, dashboard totals, and protected deletion.

Possible Future Enhancements

  • ☐ Classify listings as remote, local, hybrid, outside the preferred area, or unknown
  • ☐ Add explainable match estimates using a user-defined skills profile
  • ☐ Add configurable search preferences
  • ☐ Deploy the application with persistent database storage

Dashboard

Job Lead Scout dashboard

Releases

Packages

Contributors

Languages