mirror of
https://github.com/hmalik144/Automation---ReedJobApplications.git
synced 2025-12-10 03:05:30 +00:00
Initial commit
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
# Project exclude paths
|
||||
/target/
|
||||
2
.idea/.gitignore
generated
vendored
Normal file
2
.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
# Default ignored files
|
||||
/workspace.xml
|
||||
13
.idea/compiler.xml
generated
Normal file
13
.idea/compiler.xml
generated
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<annotationProcessing>
|
||||
<profile name="Maven default annotation processors profile" enabled="true">
|
||||
<sourceOutputDir name="target/generated-sources/annotations" />
|
||||
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
||||
<outputRelativeToContentRoot value="true" />
|
||||
<module name="JobApplications" />
|
||||
</profile>
|
||||
</annotationProcessing>
|
||||
</component>
|
||||
</project>
|
||||
14
.idea/misc.xml
generated
Normal file
14
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="MavenProjectsManager">
|
||||
<option name="originalFiles">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/pom.xml" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="11" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
2
JobApplications.iml
Normal file
2
JobApplications.iml
Normal file
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4" />
|
||||
136
pom.xml
Normal file
136
pom.xml
Normal file
@@ -0,0 +1,136 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.example</groupId>
|
||||
<artifactId>JobApplications</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<kotlin.version>1.3.61</kotlin.version>
|
||||
<maven.compiler.source>1.7</maven.compiler.source>
|
||||
<maven.compiler.target>1.7</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-test</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi</artifactId>
|
||||
<version>4.1.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-ooxml</artifactId>
|
||||
<version>4.1.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.seleniumhq.selenium</groupId>
|
||||
<artifactId>selenium-chrome-driver</artifactId>
|
||||
<version>3.141.59</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.seleniumhq.selenium</groupId>
|
||||
<artifactId>selenium-java</artifactId>
|
||||
<version>3.141.59</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.tylerthrailkill.helpers</groupId>
|
||||
<artifactId>pretty-print</artifactId>
|
||||
<version>2.0.2</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/com.squareup.retrofit/retrofit -->
|
||||
<dependency>
|
||||
<groupId>com.squareup.retrofit2</groupId>
|
||||
<artifactId>retrofit</artifactId>
|
||||
<version>2.6.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.retrofit2</groupId>
|
||||
<artifactId>converter-gson</artifactId>
|
||||
<version>2.6.0</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.json/json -->
|
||||
<dependency>
|
||||
<groupId>org.json</groupId>
|
||||
<artifactId>json</artifactId>
|
||||
<version>20190722</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlinx</groupId>
|
||||
<artifactId>kotlinx-coroutines-core</artifactId>
|
||||
<version>1.3.3</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
|
||||
<testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-maven-plugin</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>compile</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>test-compile</id>
|
||||
<phase>test-compile</phase>
|
||||
<goals>
|
||||
<goal>test-compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<jvmTarget>1.8</jvmTarget>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>2.6</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-assembly</id>
|
||||
<phase>package</phase>
|
||||
<goals> <goal>single</goal> </goals>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>Main</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
||||
</build>
|
||||
|
||||
</project>
|
||||
16
src/main/java/JobObject.kt
Normal file
16
src/main/java/JobObject.kt
Normal file
@@ -0,0 +1,16 @@
|
||||
import java.util.*
|
||||
|
||||
data class JobObject(
|
||||
var jobId: String? = null,
|
||||
var website: String? = null,
|
||||
var jobTitle: String? = null,
|
||||
var location: String? = null,
|
||||
var company: String? = null,
|
||||
var url: String? = null,
|
||||
var dateApplied : String? = null
|
||||
){
|
||||
|
||||
override fun toString(): String {
|
||||
return super.toString()
|
||||
}
|
||||
}
|
||||
142
src/main/java/LegacyCode.kt
Normal file
142
src/main/java/LegacyCode.kt
Normal file
@@ -0,0 +1,142 @@
|
||||
import Constants.Companion.REED_KEYWORDS
|
||||
import Constants.Companion.REED_LOCATION
|
||||
import Constants.Companion.REED_PASSWORD
|
||||
import Constants.Companion.REED_USERNAME
|
||||
import org.openqa.selenium.By
|
||||
import org.openqa.selenium.WebElement
|
||||
import org.openqa.selenium.chrome.ChromeDriver
|
||||
import org.openqa.selenium.support.ui.ExpectedConditions
|
||||
import org.openqa.selenium.support.ui.WebDriverWait
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
fun StartSearch(){
|
||||
|
||||
//Open Chrome
|
||||
System.setProperty("webdriver.chrome.driver","C:\\Selenium\\selenium-java-3.141.59\\chromedriver_win32\\chromedriver.exe" )
|
||||
val driver = ChromeDriver()
|
||||
|
||||
//open reed website login
|
||||
driver.get("https://www.reed.co.uk/account/signin?returnUrl=%2F#&card=signin")
|
||||
val wait = WebDriverWait(driver, 20)
|
||||
|
||||
//wait for page to load
|
||||
val lastElementToLoad = driver.findElementById("signin-button")
|
||||
wait.until(ExpectedConditions.elementToBeClickable(lastElementToLoad))
|
||||
|
||||
//insert credentials and sign in
|
||||
driver.findElementByXPath("//*[@id=\"Credentials_Email\"]").sendKeys(REED_USERNAME)
|
||||
driver.findElementByXPath("//*[@id=\"Credentials_Password\"]").sendKeys(REED_PASSWORD)
|
||||
lastElementToLoad.click()
|
||||
|
||||
//wait for page to load
|
||||
val jobSearchEditText = driver.findElementByXPath("//*[@id=\"keywords\"]")
|
||||
wait.until(ExpectedConditions.elementToBeClickable(jobSearchEditText))
|
||||
|
||||
// //submit search
|
||||
jobSearchEditText.sendKeys(REED_KEYWORDS)
|
||||
driver.findElementByXPath("//*[@id=\"location\"]").sendKeys(REED_LOCATION)
|
||||
driver.findElementByXPath("//*[@id=\"main-search\"]/div[1]/div[3]/button").click()
|
||||
|
||||
//todo: change to wait
|
||||
Thread.sleep(1500)
|
||||
|
||||
val ad = driver.findElementByXPath("//*[@id=\"content\"]/div[1]/div[2]/h1")
|
||||
wait.until(ExpectedConditions.elementToBeClickable(ad))
|
||||
|
||||
//find number of pages
|
||||
val text = driver.findElementByCssSelector("div.page-counter").text /* eg. 1 - 25 of 99 jobs */
|
||||
print(text)
|
||||
val count = text.toTotalCount()
|
||||
val pages = count.getNumberOfPages()
|
||||
|
||||
//loop through pages of search
|
||||
for (i in 1..pages){
|
||||
|
||||
//open page by number on search
|
||||
//todo: change this url builder
|
||||
driver.get("https://www.reed.co.uk/jobs/android-developer-jobs-in-kilburn-london?pageno=$i")
|
||||
Thread.sleep(2500)
|
||||
|
||||
//elements list of jobs on page
|
||||
val list = driver.findElementsByCssSelector("div.col-sm-12.col-md-9.col-lg-10.details")
|
||||
|
||||
//turn list into global list job object
|
||||
list.forEach {
|
||||
val badge = it.findElement(By.cssSelector("div.badge-container"))
|
||||
//check if there is a badge element
|
||||
if (badge.isDisplayed){
|
||||
//see if applied is in badge
|
||||
val applied = badge.findElements(By.cssSelector("span.label.label-applied"))
|
||||
//if applied doesnt exist then add to global list of jobs
|
||||
if (applied.isNullOrEmpty()){
|
||||
val jobObject = it.toJobObject()
|
||||
jobsList.add(jobObject)
|
||||
}
|
||||
|
||||
}else{
|
||||
//no badge exists so add to list of jobs declared at the top
|
||||
val jobObject = it.toJobObject()
|
||||
jobsList.add(jobObject)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//loop through the jobs collected
|
||||
jobsList.forEach{
|
||||
//open the URl
|
||||
driver.get(it.url)
|
||||
|
||||
val title = driver.findElementByXPath("//*[@id=\"content\"]/div/div[2]/article")
|
||||
wait.until(ExpectedConditions.elementToBeClickable(title))
|
||||
|
||||
//check for external apply element
|
||||
val applyExternal = driver.findElementsByCssSelector("span.external-app-caption")
|
||||
|
||||
//if external apply is empty then apply for job
|
||||
if (applyExternal.isNullOrEmpty()){
|
||||
|
||||
print(it.jobTitle + " ${it.url} \n" )
|
||||
|
||||
|
||||
//find apply button
|
||||
val applyNow = driver.findElementsByXPath("//*[@id=\"applyButtonSide\"]")
|
||||
|
||||
if (!applyNow.isNullOrEmpty()){
|
||||
|
||||
//click apply
|
||||
applyNow[1].click()
|
||||
|
||||
try{
|
||||
val successfulApplied = driver.findElementByXPath("//*[@id=\"content\"]/div/div[1]/a")
|
||||
wait.until(ExpectedConditions.visibilityOf(successfulApplied))
|
||||
}catch (e: Exception){
|
||||
println(it.jobId + " did not apply")
|
||||
println("\n" + e.toString() + "\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun String.toTotalCount() : Int = this.substringAfter("of ").substringBefore( " jobs").toInt()
|
||||
|
||||
fun Int.getNumberOfPages():Int = if (this % 25 ==0){
|
||||
this/25;
|
||||
}else{
|
||||
(this.toDouble()/25).roundToInt()
|
||||
}
|
||||
|
||||
fun WebElement.toJobObject():JobObject {
|
||||
val attribute = this.findElement(By.tagName("a"))
|
||||
|
||||
val id = attribute.getAttribute("data-id")
|
||||
val url = attribute.getAttribute("href")
|
||||
val jobtitle = attribute.getAttribute("title")
|
||||
|
||||
val location = this.findElement(By.xpath("//*[@id=\"jobSection${id}\"]/div[1]/div[1]/ul[2]/li")).text
|
||||
val company = this.findElement(By.xpath("//*[@id=\"jobSection${id}\"]/div[1]/header/div[2]/a")).text
|
||||
|
||||
return JobObject("reed-${id}","Reed.co.uk",jobtitle,location,company,url)
|
||||
|
||||
}
|
||||
99
src/main/java/Main.kt
Normal file
99
src/main/java/Main.kt
Normal file
@@ -0,0 +1,99 @@
|
||||
import Constants.Companion.REED_PASSWORD
|
||||
import Constants.Companion.REED_USERNAME
|
||||
import api.network.NetworkRequests
|
||||
import api.network.responses.ReedJobObject
|
||||
import org.openqa.selenium.JavascriptExecutor
|
||||
import org.openqa.selenium.chrome.ChromeDriver
|
||||
import org.openqa.selenium.support.ui.ExpectedConditions
|
||||
import org.openqa.selenium.support.ui.WebDriverWait
|
||||
|
||||
|
||||
var jobsList = mutableListOf<JobObject>()
|
||||
var reedJobsList = listOf<ReedJobObject>()
|
||||
lateinit var driver: ChromeDriver
|
||||
lateinit var wait: WebDriverWait
|
||||
|
||||
public fun main(args: Array<String>){
|
||||
setup()
|
||||
setupWebDriver()
|
||||
logonToReed()
|
||||
applyForJobsThroughLoop()
|
||||
}
|
||||
|
||||
fun setup(){
|
||||
val result = NetworkRequests().getSearchApi()
|
||||
|
||||
if (!result.isNullOrEmpty()){
|
||||
reedJobsList = result
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun setupWebDriver(){
|
||||
//Open Chrome
|
||||
System.setProperty("webdriver.chrome.driver","C:\\Selenium\\selenium-java-3.141.59\\chromedriver_win32\\chromedriver.exe" )
|
||||
driver = ChromeDriver()
|
||||
wait = WebDriverWait(driver, 20)
|
||||
}
|
||||
|
||||
fun applyForJobsThroughLoop(){
|
||||
|
||||
reedJobsList.forEach {
|
||||
try {
|
||||
driver.get(it.jobUrl)
|
||||
applyForJob(it)
|
||||
|
||||
}catch (e: Exception){
|
||||
println("\n" + e.toString() + "\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun logonToReed(){
|
||||
driver.get("https://www.reed.co.uk/account/signin?returnUrl=%2F#&card=signin")
|
||||
|
||||
//wait for page to load
|
||||
val lastElementToLoad = driver.findElementById("signin-button")
|
||||
wait.until(ExpectedConditions.elementToBeClickable(lastElementToLoad))
|
||||
|
||||
//insert credentials and sign in
|
||||
driver.findElementByXPath("//*[@id=\"Credentials_Email\"]").sendKeys(REED_USERNAME)
|
||||
driver.findElementByXPath("//*[@id=\"Credentials_Password\"]").sendKeys(REED_PASSWORD)
|
||||
lastElementToLoad.click()
|
||||
|
||||
//wait for page to load
|
||||
val jobSearchEditText = driver.findElementByXPath("//*[@id=\"keywords\"]")
|
||||
wait.until(ExpectedConditions.elementToBeClickable(jobSearchEditText))
|
||||
}
|
||||
|
||||
fun applyForJob(jobObject: ReedJobObject){
|
||||
val appliedBefore = driver.findElementsByXPath("//*[@id=\"content\"]/div/div[2]/article/div/div[1]/div")
|
||||
|
||||
if (appliedBefore.isNullOrEmpty()){
|
||||
println("${jobObject.jobId} has not been applied")
|
||||
//find apply button
|
||||
val applyNow = driver.findElementsByXPath("//*[@id=\"applyButtonSide\"]")
|
||||
|
||||
if (!applyNow.isNullOrEmpty()){
|
||||
//click apply
|
||||
val index = if (applyNow.size > 1){ 1 }else{ 0 }
|
||||
applyNow[index].click()
|
||||
|
||||
try{
|
||||
// val successfulApplied = driver.findElementByCssSelector("div.alert.alert-success alert-borderless")
|
||||
wait.until{
|
||||
driver.executeScript("return document.readyState") == "complete"
|
||||
}
|
||||
|
||||
}catch (e: Exception){
|
||||
println("\n" + e.toString() + "\n")
|
||||
}
|
||||
}
|
||||
}else{
|
||||
println("${jobObject.jobId} has been applied")
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
23
src/main/java/api/network/BasicInterceptor.kt
Normal file
23
src/main/java/api/network/BasicInterceptor.kt
Normal file
@@ -0,0 +1,23 @@
|
||||
package api.network
|
||||
|
||||
import Constants.Companion.REED_API_KEY
|
||||
import okhttp3.Credentials
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.Response
|
||||
|
||||
class BasicInterceptor() : Interceptor{
|
||||
|
||||
private val credentials = Credentials.basic(REED_API_KEY,"")
|
||||
|
||||
|
||||
override fun intercept(chain: Interceptor.Chain): Response {
|
||||
val request = chain.request();
|
||||
val builder = request.newBuilder().header(
|
||||
"Authorization", credentials
|
||||
).build()
|
||||
|
||||
return chain.proceed(builder)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
31
src/main/java/api/network/NetworkRequests.kt
Normal file
31
src/main/java/api/network/NetworkRequests.kt
Normal file
@@ -0,0 +1,31 @@
|
||||
package api.network
|
||||
|
||||
import Constants.Companion.REED_KEYWORDS
|
||||
import Constants.Companion.REED_LOCATION
|
||||
import Constants.Companion.REED_MINIMUM_SALARY
|
||||
import api.network.responses.ReedJobObject
|
||||
import com.example.h_mal.androiddevelopertechtest_incrowdsports.data.network.ReedApi
|
||||
import com.example.h_mal.androiddevelopertechtest_incrowdsports.data.network.SafeApiRequest
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
class NetworkRequests : SafeApiRequest(){
|
||||
|
||||
val reedApi = ReedApi()
|
||||
|
||||
fun getSearchApi() : List<ReedJobObject>?{
|
||||
try {
|
||||
val response = runBlocking { apiRequest { reedApi.getGameData(REED_KEYWORDS, REED_LOCATION, REED_MINIMUM_SALARY) } }
|
||||
|
||||
response.results?.let {
|
||||
return it
|
||||
}
|
||||
|
||||
}catch (e : Exception){
|
||||
println("*** $e")
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
41
src/main/java/api/network/ReedApi.kt
Normal file
41
src/main/java/api/network/ReedApi.kt
Normal file
@@ -0,0 +1,41 @@
|
||||
package com.example.h_mal.androiddevelopertechtest_incrowdsports.data.network
|
||||
|
||||
import ReedResponse
|
||||
import api.network.BasicInterceptor
|
||||
import api.network.responses.ReedJobObject
|
||||
import okhttp3.OkHttpClient
|
||||
import retrofit2.Response
|
||||
import retrofit2.Retrofit
|
||||
import retrofit2.converter.gson.GsonConverterFactory
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Path
|
||||
import retrofit2.http.Query
|
||||
|
||||
|
||||
interface ReedApi {
|
||||
|
||||
//get the game data from api call of relevent gameID
|
||||
@GET("search")
|
||||
suspend fun getGameData(@Query("keywords") keywords: String,
|
||||
@Query("locationName") locationName: String,
|
||||
@Query("minimumSalary") minimumSalary: String) : Response<ReedResponse>
|
||||
|
||||
//instantiate api class
|
||||
companion object{
|
||||
operator fun invoke() : ReedApi{
|
||||
val okkHttpclient = OkHttpClient.Builder()
|
||||
.addNetworkInterceptor(BasicInterceptor())
|
||||
.build()
|
||||
|
||||
//return api class ss retrofit client
|
||||
return Retrofit.Builder()
|
||||
.client(okkHttpclient)
|
||||
.baseUrl("https://www.reed.co.uk/api/1.0/")
|
||||
.addConverterFactory(GsonConverterFactory.create())
|
||||
.build()
|
||||
.create(ReedApi::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
35
src/main/java/api/network/SafeApiRequest.kt
Normal file
35
src/main/java/api/network/SafeApiRequest.kt
Normal file
@@ -0,0 +1,35 @@
|
||||
package com.example.h_mal.androiddevelopertechtest_incrowdsports.data.network
|
||||
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
import retrofit2.Response
|
||||
import java.io.IOException
|
||||
|
||||
abstract class SafeApiRequest {
|
||||
|
||||
//abstract function to unwrap body from response of api call
|
||||
suspend fun<T: Any> apiRequest(call: suspend () -> Response<T>) : T{
|
||||
//get the reponse
|
||||
val response = call.invoke()
|
||||
if(response.isSuccessful){
|
||||
//response is successful so return the body
|
||||
return response.body()!!
|
||||
}else{
|
||||
//the response failed so throw an error
|
||||
|
||||
val error = response.errorBody()?.string()
|
||||
|
||||
val message = StringBuilder()
|
||||
error?.let{
|
||||
try{
|
||||
message.append(JSONObject(it).getString("message"))
|
||||
}catch(e: JSONException){ }
|
||||
message.append("\n")
|
||||
}
|
||||
message.append("Error Code: ${response.code()}")
|
||||
|
||||
throw IOException(message.toString())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
17
src/main/java/api/network/responses/ReedJobObject.kt
Normal file
17
src/main/java/api/network/responses/ReedJobObject.kt
Normal file
@@ -0,0 +1,17 @@
|
||||
package api.network.responses
|
||||
data class ReedJobObject(
|
||||
val date: String?,
|
||||
val employerProfileId: String?,
|
||||
val locationName: String?,
|
||||
val maximumSalary: String?,
|
||||
val jobTitle: String?,
|
||||
val employerName: String?,
|
||||
val employerProfileName: String?,
|
||||
val jobId: Int?,
|
||||
val employerId: String?,
|
||||
val minimumSalary: String?,
|
||||
val jobUrl: String?,
|
||||
val jobDescription: String?,
|
||||
val expirationDate: String?,
|
||||
val applications: Int?
|
||||
)
|
||||
8
src/main/java/api/network/responses/ReedResponse.kt
Normal file
8
src/main/java/api/network/responses/ReedResponse.kt
Normal file
@@ -0,0 +1,8 @@
|
||||
|
||||
|
||||
import api.network.responses.ReedJobObject
|
||||
|
||||
data class ReedResponse (
|
||||
val results : List<ReedJobObject>?,
|
||||
val totalResults : Int?
|
||||
)
|
||||
Reference in New Issue
Block a user