file saved as name

This commit is contained in:
DaKheera47 2026-01-08 23:54:06 +00:00
parent 585e5e19e0
commit b914026d8b
5 changed files with 37 additions and 13 deletions

View File

@ -419,17 +419,18 @@ async function main(): Promise<void> {
try { try {
response = await fetchPage(pageNo, authSession, { searchKeyword }); response = await fetchPage(pageNo, authSession, { searchKeyword });
} catch (error) { } catch (error) {
if (error instanceof UkVisaJobsAuthError) { if (!credentials) {
if (!credentials) { if (error instanceof UkVisaJobsAuthError) {
throw new Error('UKVisaJobs auth expired. Set UKVISAJOBS_EMAIL and UKVISAJOBS_PASSWORD to refresh.'); throw new Error('UKVisaJobs auth expired. Set UKVISAJOBS_EMAIL and UKVISAJOBS_PASSWORD to refresh.');
} }
console.log(' Auth expired. Refreshing tokens...');
authSession = await loginWithBrowser(credentials.email, credentials.password);
await saveCachedAuthSession(authSession);
response = await fetchPage(pageNo, authSession, { searchKeyword });
} else {
throw error; throw error;
} }
const reason = error instanceof UkVisaJobsAuthError ? 'Auth expired.' : 'Fetch failed.';
console.log(` ${reason} Refreshing tokens and retrying...`);
authSession = await loginWithBrowser(credentials.email, credentials.password);
await saveCachedAuthSession(authSession);
response = await fetchPage(pageNo, authSession, { searchKeyword });
} }
if (response.status !== 1) { if (response.status !== 1) {

View File

@ -207,7 +207,7 @@ export const JobCard: React.FC<JobCardProps> = ({
<Button asChild variant="outline" size="sm"> <Button asChild variant="outline" size="sm">
<a <a
href={pdfHref} href={pdfHref}
download={`resume_${safeFilenamePart(job.employer)}_${safeFilenamePart(job.title)}.pdf`} download={`Shaheer_Sarfaraz_${safeFilenamePart(job.employer)}.pdf`}
> >
<Download className="mr-2 h-4 w-4" /> <Download className="mr-2 h-4 w-4" />
Download Download

View File

@ -323,7 +323,7 @@ export const JobTable: React.FC<JobTableProps> = ({
<DropdownMenuItem asChild> <DropdownMenuItem asChild>
<a <a
href={pdfHref} href={pdfHref}
download={`resume_${safeFilenamePart(job.employer)}_${safeFilenamePart(job.title)}.pdf`} download={`Shaheer_Sarfaraz_${safeFilenamePart(job.employer)}.pdf`}
> >
<Download className="mr-2 h-4 w-4" /> <Download className="mr-2 h-4 w-4" />
Download PDF Download PDF

View File

@ -176,6 +176,8 @@ const formatDateTime = (dateStr: string | null) => {
} }
}; };
const safeFilenamePart = (value: string) => value.replace(/[^a-z0-9]/gi, "_");
const dateValue = (value: string | null) => { const dateValue = (value: string | null) => {
if (!value) return null; if (!value) return null;
const parsed = Date.parse(value); const parsed = Date.parse(value);
@ -962,7 +964,10 @@ export const OrchestratorPage: React.FC = () => {
</DropdownMenuItem> </DropdownMenuItem>
)} )}
<DropdownMenuItem asChild> <DropdownMenuItem asChild>
<a href={selectedPdfHref} download={`resume_${selectedJob.id}.pdf`}> <a
href={selectedPdfHref}
download={`Shaheer_Sarfaraz_${safeFilenamePart(selectedJob.employer)}.pdf`}
>
<FileText className="mr-2 h-4 w-4" /> <FileText className="mr-2 h-4 w-4" />
Download PDF Download PDF
</a> </a>

View File

@ -56,8 +56,8 @@ export async function scoreJobSuitability(
if (!content) { if (!content) {
throw new Error('No content in response'); throw new Error('No content in response');
} }
const parsed = JSON.parse(content); const parsed = parseJsonFromContent(content);
return { return {
score: Math.min(100, Math.max(0, parsed.score || 0)), score: Math.min(100, Math.max(0, parsed.score || 0)),
reason: parsed.reason || 'No explanation provided', reason: parsed.reason || 'No explanation provided',
@ -68,6 +68,24 @@ export async function scoreJobSuitability(
} }
} }
function parseJsonFromContent(content: string): { score?: number; reason?: string } {
const trimmed = content.trim();
const withoutFences = trimmed.replace(/```(?:json)?\s*|```/gi, '').trim();
const candidate = withoutFences;
try {
return JSON.parse(candidate);
} catch {
const firstBrace = candidate.indexOf('{');
const lastBrace = candidate.lastIndexOf('}');
if (firstBrace !== -1 && lastBrace !== -1 && lastBrace > firstBrace) {
const sliced = candidate.slice(firstBrace, lastBrace + 1);
return JSON.parse(sliced);
}
throw new Error('Unable to parse JSON from model response');
}
}
function buildScoringPrompt(job: Job, profile: Record<string, unknown>): string { function buildScoringPrompt(job: Job, profile: Record<string, unknown>): string {
return ` return `
You are evaluating a job listing for a candidate. Score how suitable this job is for the candidate on a scale of 0-100. You are evaluating a job listing for a candidate. Score how suitable this job is for the candidate on a scale of 0-100.
@ -93,7 +111,7 @@ Disciplines: ${job.disciplines || 'Not specified'}
Job Description: Job Description:
${job.jobDescription || 'No description available'} ${job.jobDescription || 'No description available'}
Respond with JSON: { "score": <0-100>, "reason": "<brief explanation>" } Respond with JSON only (no code fences): { "score": <0-100>, "reason": "<brief explanation>" }
`; `;
} }