feat: added the ability for linkedin

This commit is contained in:
Andre Henriques 2024-10-03 14:10:09 +01:00
parent aa461e65a2
commit fb6f1b35fd
4 changed files with 90 additions and 76 deletions

View File

@ -2,10 +2,8 @@ package com.andr3h3nriqu3s.applications
import java.sql.ResultSet
import java.util.UUID
import kotlin.collections.setOf
import kotlin.collections.emptyList
import okhttp3.OkHttpClient
import okhttp3.Request
import kotlin.collections.setOf
import org.springframework.http.MediaType
import org.springframework.jdbc.core.JdbcTemplate
import org.springframework.jdbc.core.RowMapper
@ -69,7 +67,12 @@ data class FlairRequest(val id: String, val text: String)
data class UpdateUrl(val id: String, val url: String)
data class CVData(val company: String, val recruiter: String, val message: String, val flairs: List<SimpleFlair>)
data class CVData(
val company: String,
val recruiter: String,
val message: String,
val flairs: List<SimpleFlair>
)
@RestController
@ControllerAdvice
@ -82,23 +85,20 @@ class ApplicationsController(
) {
@GetMapping(path = ["/cv/{id}"], produces = [MediaType.APPLICATION_JSON_VALUE])
public fun getCV(
@PathVariable id: String,
@RequestHeader("token") token: String?
): CVData? {
val user = sessionService.verifyToken(token);
public fun getCV(@PathVariable id: String, @RequestHeader("token") token: String?): CVData? {
val user = sessionService.verifyToken(token)
val application = applicationService.findApplicationByIdNoUser(id);
val application = applicationService.findApplicationByIdNoUser(id)
if (application == null) return null;
if (application == null) return null
if (user == null) {
viewService.create(application.id)
}
val flairs = application.flairs.map {it.toFlairSimple()};
val flairs = application.flairs.map { it.toFlairSimple() }
return CVData(application.company, application.recruiter, application.message, flairs);
return CVData(application.company, application.recruiter, application.message, flairs)
}
@PostMapping(path = ["/text"], produces = [MediaType.APPLICATION_JSON_VALUE])
@ -144,7 +144,15 @@ class ApplicationsController(
print(urls.size)
print(" links\n")
urls = urls.filter { predicate -> predicate.contains("jobListing") }
// jobListing is for glassdoor urls
// jobs/view is for linkeding urls
urls =
urls.filter { predicate ->
print("url: ")
print(predicate)
print("\n")
predicate.contains("jobListing") || predicate.contains("jobs/view")
}
print("found fileted: ")
print(urls.size)
@ -156,56 +164,13 @@ class ApplicationsController(
print(urls.size)
print(" links\n")
var client = OkHttpClient()
var applications =
urls.map { elm ->
var request =
Request.Builder()
.url(elm)
.header(
"User-Agent",
"Mozilla/5.0 (X11; Linux x86_64; rv:127.0) Gecko/20100101 Firefox/127.0"
)
.addHeader(
"Accept",
"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8"
)
.addHeader(
"Cookie",
"gdId=aafdcb86-c37d-4bfd-8d84-4a07f11dbfc2; AWSALB=Qj3Rvldo90lFQhsChPHFXcGlVxdaZOEwr1ZP4d+whxBTlXCprKj+utUCz4DHXoC6fFrewDdFdRCPBbM0v2WQQdY4URUD4lYXd0GsBEWS/5AzZX0i9yk4C7Cfz5xA; AWSALBCORS=Qj3Rvldo90lFQhsChPHFXcGlVxdaZOEwr1ZP4d+whxBTlXCprKj+utUCz4DHXoC6fFrewDdFdRCPBbM0v2WQQdY4URUD4lYXd0GsBEWS/5AzZX0i9yk4C7Cfz5xA; indeedCtk=1i17t757dk2mo801; at=Sf_nQa0d6HxrGoYn305KELOfsWT0o-KrKdraenJrTJMqApEH4LO70x3i0oOafGWes13u8kOSq8PzPD1pZAxAVOEz0hrNnOhRnLGl3Ako4I-CYx_oCB_YhFe7M-do__yNC-ipCVlbzUujwQzCW83mKFLMHk9N12RSjhzsPEQi6Xw4n66wvXSttDChGCpY-BMSn862U-OQ9gnNzy3j214vctizTPC3g2Ig7Qysg3AY7lo-HPkHaq9fojbituLfbtgtpkCDtWAwR2-3XCWu6d2H_gk7ZWn6CH1FgLf640fd1Kep7K3kArceNq046PEalzHnJMLPSnvusS_jJatdk-x4k2rxF1FJvK0MLkPiKr39V8i7J27uOMwFLRD-49EoJUOZzTxQ1wb3lyt503NuwPhYolRGr3Xla2b6wyzYRSk2e-RHHElzvCn-FlWXaTQqEiZXKEjAGihlagUz8HFmY6bRf0FLCKvA26oVjT1vEoICmn32FOHr9M65YDllTbgHj3dDeTUczzxf_nrDSyide_UL08LsZIYJAtyueUSBqvqq49WlKemvhyKBMUloNP68A_MfT5suKPasvQu-n_ZvXahY7O5KbgtIR0QVnSimFC8yaVy8Sqjo5cq2f1VnZ6kxXj9frSK-v_jz1J7hobOAo8Mlfy_EfzBDV_3nywqjT1pKgzRRmHcNLnj_cn2rPga3NUjxpYzl485eevPDv9Gj62qAMHh1w5S6v1QkSBmgaSyKpBKYD1zD86JLJ6Upf0bVM8WcHv9u33GuKX0CgC_P-P3189AgLgtISr-2NuIaNTkKMxenagCvri6oGLj6OYMD6nO9JQ_jKUqS6ShRMhDD9K1bSUE42c2_ePhBDLWFyb3AZiJvVjcL1v1k1dO93jCn7XUQZkE7x7m1QeGC0f_5OK1IZeGuJn8Jsx-u2EvT7DNSV0LNY1hfIXauy9KCLFdTeoqDuGSumi81cg; uc=8013A8318C98C5171B57B9070099BAD115C8BBA5C5A6DB94DFFE7C86F37B699E2B54A4621F700A694011D5B5CA447CCC87B1BAC35D51A1AA5B5FF13CBDC5343400624A80C8E3C3A1966ED67EBC62D473CD7C57C9E6D138AD745B36C8625AD88EA13CE3458B51AD202B52198961B4D49007278A9385005B27B951F0F7091D61DCBBD54D21C8CFBCAD7AABEF4EA398F978; trs=direct:direct:direct:2024-06-25+07%3A59%3A23.686:undefined:undefined; cf_clearance=IZpDoUoDUUNidzYbSZRoIq6S93FXgL7hmz6.PdfEiUM-1720205316-1.0.1.1-tNL38ZNHbQw9XbL3J9g4oL4aHwiAoXXuYdOb4Xi8Z3B4yWKOuL31FrrPrqPRcxVUV7BNEdlqSMaNF3k8q.Tv0A; rl_session=RudderEncrypt%3AU2FsdGVkX19OL1VCjdlEuacjPBxOQ%2FsqFNPp5d9Dke5bKES7onFGAEFzkA4iuW3rfqQ8v2sfoX19gn7Zm3Qd83i6PWHRHESeelsza78DN%2B2U7IwWQEiyEeptsuZyTPhHxb5ALLCzUhgHcvnsh3GhQw%3D%3D; rl_user_id=RudderEncrypt%3AU2FsdGVkX19%2BQEGQCkE9Cg3Ikh5t8h65RqO0N24wvgA%3D; rl_trait=RudderEncrypt%3AU2FsdGVkX1%2B1EoAGj4RTTyGWbZRPkyuua9oOW4YQPaE%3D; rl_group_id=RudderEncrypt%3AU2FsdGVkX18STRtzoe4K%2FzJKt8zfNqQwMj7KTzQDhfQ%3D; rl_group_trait=RudderEncrypt%3AU2FsdGVkX1%2B5Kbrex9bI6O0Gr524R6IRASVZGgrWNco%3D; rl_anonymous_id=RudderEncrypt%3AU2FsdGVkX19X88n4GXRAtkOTDXcuHojO%2BetO8p7n37y2YLe6nWW5P87Stu9l86nJ4zGDs7e8D5MEUPW6KrCywQ%3D%3D; rl_page_init_referrer=RudderEncrypt%3AU2FsdGVkX19MgsL8FFX%2BSjRpwcg0nu4XxNDvIPdg2WGEivR2%2BsH1%2BqAvvlaEZmiQ; rl_page_init_referring_domain=RudderEncrypt%3AU2FsdGVkX18kgmzvlkMRtIo%2BzqUQ%2FVRfcuCvngKkmV8qAgqKAKraZOr9Qpqc6loH; _cfuvid=ezdGXFBaF3Eh.jiKZrHkmaV7GItIbZ4qPUy7gOyHgns-1720604124536-0.0.1.1-604800000; gdGPCset=true; _urc=293647244; AFSID=MTQ3YTQxNzEtZmYwMC00N2Y0LWJiOGMtNzVjMmRjZWM5MTQ4; gdsid=1720604123405:1720637554591:4466F8BAFD3D2D34B6058423B0F90392; JSESSIONID=BA9AA08792C5E981A69CF079E7A91B35; GSESSIONID=undefined; cass=0; asst=1720637634.1; __cf_bm=6b1QlZvq2zEE.Cqvcg0g2a0OiPObgL0IKFr.vZwZSwQ-1720637555-1.0.1.1-qaRfjwA.xRIpqzfJiksMvc_hWVvVnfGJ1YnRToNwK.m3Od0BXKUvOVnvhrpiR9bP311eCdI.EAYQZvKpwD7KHQ; bs=oiDddWzpeaDeES0KI7rnsQ:NDp0g4i9mXeF0vvvvYq2Ud_auNQosyTqd2NVCprviXG0nOGhPzqbVJa16DxpiFQkIluzbbDJqHLht66Dwrqn4yi7u_FvaGOojP_y91QEUZU:Hex7BRo2zXhuIdlGhiQR8uO5nGn2VCjpx6dF2aJPIxk"
)
.addHeader("Accept-Language", "en-US,en;q=0.7,pt;q=0.3")
.addHeader("Accept-Encoding", "gzip, deflate, br, zstd")
.addHeader("Connection", "keep-alive")
.build()
var new_url: String =
client.newCall(request).execute().use { response ->
print("response:")
print(response)
print("\n")
response.request.url.toString()
}
var unique: String? = new_url!!.split("?")[0]
var original_url: String? = elm
if (new_url == elm) {
original_url = null
unique = null
}
Thread.sleep(2000)
print("Got new url!\n")
Application(
UUID.randomUUID().toString(),
new_url,
original_url,
unique,
if (elm.contains("linkedin")) elm.split("?")[0] else elm,
if (elm.contains("linkedin")) elm.split("?")[0] else null,
if (elm.contains("linkedin")) elm.split("?")[0] else null,
"New Aplication",
user.id,
"",
@ -419,7 +384,11 @@ class ApplicationsController(
}
@Service
class ApplicationService(val db: JdbcTemplate, val flairService: FlairService, val viewService: ViewService) {
class ApplicationService(
val db: JdbcTemplate,
val flairService: FlairService,
val viewService: ViewService
) {
public fun findApplicationByUrl(user: UserDb, url: String, unique_url: String?): Application? {
if (unique_url != null) {
@ -473,7 +442,8 @@ class ApplicationService(val db: JdbcTemplate, val flairService: FlairService, v
}
public fun findApplicationByIdNoUser(id: String): Application? {
var applications = db.query("select * from applications where id=?", arrayOf(id), Application).toList()
var applications =
db.query("select * from applications where id=?", arrayOf(id), Application).toList()
if (applications.size == 0) {
return null

View File

@ -30,6 +30,15 @@ browser.runtime.onMessage.addListener(async (message, sender, sendResponse) => {
});
return;
}
if (message.type === "R_GET_DATA_FROM_PAGE") {
let windowList = (await browser.storage.local.get("windows")).windows ?? [];
if (windowList.length !== 1) return;
const tab = await browser.tabs.get(windowList[0]);
browser.tabs.sendMessage(tab.id, {
type: "GET_DATA_FROM_PAGE",
});
return;
}
if (message.type !== "MY_GET_URL") return;
let windowList = (await browser.storage.local.get("windows")).windows ?? [];

View File

@ -2,6 +2,21 @@ browser.runtime.onMessage.addListener((message) => {
if (message.type === "MY_GET_URL_R") {
window.postMessage(message);
} else if (message.type === "GET_DATA_FROM_PAGE") {
// Parse things for linkedin
if (window.location.host.includes("linkedin")) {
if (window.location.host.includes("merchantpool1")) {
return;
}
const jobTitle = document.querySelector('h1').textContent;
const company = document.querySelector('.relative a[target="_self"]').textContent;
const money = document.querySelector('ul li div div div li-icon[type="job"]')?.parentNode?.parentNode?.parentNode?.parentNode?.children[1]?.children[0]?.textContent?.replaceAll(/\s{2,}/g, '') ?? '';
const description = document.querySelector('article').textContent;
browser.runtime.sendMessage({ type: "GOT_INFO_R", company, jobTitle, money, description });
return;
}
// Ignore everything that is no glassdoor
if (!window.location.host.includes("glassdoor")) return;
const company = document.querySelector('header[data-test="job-details-header"]')
.children[0].children[0].querySelector("h4").innerHTML;
const jobTitle = document
@ -30,5 +45,7 @@ window.addEventListener("message", (e) => {
window.postMessage({ type: "HAS_EXTENSION" });
} else if (e.data.type === "REGISTER_INTEREST") {
browser.runtime.sendMessage({ type: "REGISTER_INTEREST" });
}
} else if (e.data.type === "R_GET_DATA_FROM_PAGE") {
browser.runtime.sendMessage({ type: "R_GET_DATA_FROM_PAGE" });
}
});

View File

@ -20,6 +20,7 @@
let changeUrl: HTMLDialogElement;
let lastExtData: any = $state(undefined);
let autoExtData = false;
async function activate(item?: Application) {
if (!item) {
@ -61,6 +62,7 @@
}
applicationStore.loadApplications(true);
autoExtData = false;
lastExtData = undefined;
}
@ -101,6 +103,11 @@
function onMessage(e: MessageEvent) {
if (e.data.type === 'GOT_INFO_R') {
lastExtData = e.data;
if (autoExtData) {
window.requestAnimationFrame(() => {
setExtData();
});
}
}
}
@ -120,18 +127,17 @@
activeItem.payrange = lastExtData.money;
window.requestAnimationFrame(() => {
save().then(async () => {
if (!lastExtData.description) {
lastExtData = undefined;
return;
}
await post('application/text/flair', {
id: activeItem?.id ?? '',
text: lastExtData.description,
});
loadActive();
lastExtData = undefined;
});
if (!lastExtData.description) {
lastExtData = undefined;
return;
}
await post('application/text/flair', {
id: activeItem?.id ?? '',
text: lastExtData.description
});
loadActive();
lastExtData = undefined;
});
});
}
@ -341,6 +347,16 @@
</button>
{#if lastExtData !== undefined}
<button class="btn-primary" onclick={() => setExtData()}> Ext Data </button>
{:else}
<button
class="btn-primary"
onclick={() => {
autoExtData = true;
window.postMessage({ type: 'R_GET_DATA_FROM_PAGE' });
}}
>
Get Ext Data
</button>
{/if}
{#if activeItem.original_url == null}
<button class="btn-primary" onclick={() => changeUrl.showModal()}>
@ -353,7 +369,9 @@
</div>
</div>
{#if applicationStore.dragging}
<div class="flex w-full flex-grow rounded-lg p-3 gap-2 absolute bottom-0 left-0 right-0 bg-white">
<div
class="flex w-full flex-grow rounded-lg p-3 gap-2 absolute bottom-0 left-0 right-0 bg-white"
>
<!-- Do nothing -->
<DropZone
icon="box-arrow-down"