Commit 2810d677 authored by Emil Bordin's avatar Emil Bordin
Browse files

Weiter gearbeitet

parent c4014121
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
"beruf","titel","refnr","arbeitsort.ort","arbeitsort.region","arbeitsort.land","arbeitsort.koordinaten.lat","arbeitsort.koordinaten.lon","arbeitsort.entfernung","arbeitsort.plz","arbeitsort.strasse","arbeitsort.ortsteil","arbeitsort.adresszusatz","arbeitgeber","aktuelleVeroeffentlichungsdatum","modifikationsTimestamp","eintrittsdatum","kundennummerHash","externeUrl","studiengang"
"Systeminformatiker/in","Daten- und Systemarchitekt (Mensch*)","10000-1197699075-S","Stuttgart","Baden-Württemberg","Deutschland",48.774672,9.1745012,"1",NA,NA,NA,NA,"people to business GmbH","2024-05-24","2024-05-24T13:24:53.452","2024-06-15","gTnRBOfzjZCERzo1r9ku3t68dbOP_us4Z75vMeREFSs=",NA,NA
"Fachinformatiker/in - Daten- und Prozessanalyse","Ermittlungsassistent/-in (m/w/d)","10000-1199037711-S","Stuttgart","Baden-Württemberg","Deutschland",48.8104398,9.1859217,"5","70191","Hahnemannstr. 1",NA,NA,"Polizeipräsidium Stuttgart","2024-05-28","2024-05-28T16:07:08.945","2024-05-28","zTYmz02k8hj5NtMTz2If62BRQnKiUHJT7D0SKuNAXG8=",NA,NA
"Fachinformatiker/in - Daten- und Prozessanalyse","System- und Applikationsbetreuer (m/w/d)","12288-3642135506-S","Stuttgart","Baden-Württemberg","Deutschland",48.7987861,9.1847491,"3","70191",NA,NA,NA,"Amadeus Fire AG","2024-05-27","2024-05-27T08:47:33.27","2024-05-28",NA,"https://www.persy.jobs/persy/l/job-d8vqx-b",NA
"Fachinformatiker/in - Daten- und Prozessanalyse","Ausbildung zum Fachinformatiker* für Daten- und Prozessanalyse","10000-1198989492-S","Ostfildern","Baden-Württemberg","Deutschland",48.7155319,9.2720819,"9","73760","Hellmuth-Hirth-Str. 2",NA,NA,"Elektror airsystems GmbH","2024-05-23","2024-05-23T10:44:44.55","2025-09-01","uEILzC-RZo49ZqhPiYuFUd579Fb9f038AfyyCWh4nmM=",NA,NA
"Fachinformatiker/in - Daten- und Prozessanalyse","Ausbildung: Fachinformatiker (m/w/d) für Daten und Prozessanalyse","10000-1197980485-S","Stuttgart","Baden-Württemberg","Deutschland",48.8226255,9.0952796,"9","70499","Ingersheimer Str. 10","Weilimdorf",NA,"Informatica GmbH","2024-05-13","2024-05-13T11:28:36.247","2024-09-01","1Hlq1mWcuqOJBLdVaf9-swPOZNoYPuu-K2UmFTH00iQ=",NA,NA
"Fachinformatiker/in - Daten- und Prozessanalyse","Berufseinsteiger User Helpdesk (m/w/d)","12288-3644063819-S","Fellbach, Württemberg","Baden-Württemberg","Deutschland",48.8022574,9.2818045,"8","70734",NA,NA,NA,"Amadeus Fire AG","2024-05-27","2024-05-27T10:47:04.479","2024-05-28",NA,"https://www.persy.jobs/persy/l/job-d7dim-b",NA
+1 −0
Original line number Diff line number Diff line
"refnr"
+7 −0
Original line number Diff line number Diff line
"beruf","titel","refnr","arbeitsort.ort","arbeitsort.region","arbeitsort.land","arbeitsort.koordinaten.lat","arbeitsort.koordinaten.lon","arbeitsort.entfernung","arbeitsort.plz","arbeitsort.strasse","arbeitsort.ortsteil","arbeitsort.adresszusatz","arbeitgeber","aktuelleVeroeffentlichungsdatum","modifikationsTimestamp","eintrittsdatum","kundennummerHash","externeUrl","studiengang"
"Systeminformatiker/in","Daten- und Systemarchitekt (Mensch*)","10000-1197699075-S","Stuttgart","Baden-Württemberg","Deutschland",48.774672,9.1745012,"1",NA,NA,NA,NA,"people to business GmbH","2024-05-24","2024-05-24T13:24:53.452","2024-06-15","gTnRBOfzjZCERzo1r9ku3t68dbOP_us4Z75vMeREFSs=",NA,NA
"Fachinformatiker/in - Daten- und Prozessanalyse","Ermittlungsassistent/-in (m/w/d)","10000-1199037711-S","Stuttgart","Baden-Württemberg","Deutschland",48.8104398,9.1859217,"5","70191","Hahnemannstr. 1",NA,NA,"Polizeipräsidium Stuttgart","2024-05-28","2024-05-28T16:07:08.945","2024-05-28","zTYmz02k8hj5NtMTz2If62BRQnKiUHJT7D0SKuNAXG8=",NA,NA
"Fachinformatiker/in - Daten- und Prozessanalyse","System- und Applikationsbetreuer (m/w/d)","12288-3642135506-S","Stuttgart","Baden-Württemberg","Deutschland",48.7987861,9.1847491,"3","70191",NA,NA,NA,"Amadeus Fire AG","2024-05-27","2024-05-27T08:47:33.27","2024-05-28",NA,"https://www.persy.jobs/persy/l/job-d8vqx-b",NA
"Fachinformatiker/in - Daten- und Prozessanalyse","Ausbildung zum Fachinformatiker* für Daten- und Prozessanalyse","10000-1198989492-S","Ostfildern","Baden-Württemberg","Deutschland",48.7155319,9.2720819,"9","73760","Hellmuth-Hirth-Str. 2",NA,NA,"Elektror airsystems GmbH","2024-05-23","2024-05-23T10:44:44.55","2025-09-01","uEILzC-RZo49ZqhPiYuFUd579Fb9f038AfyyCWh4nmM=",NA,NA
"Fachinformatiker/in - Daten- und Prozessanalyse","Ausbildung: Fachinformatiker (m/w/d) für Daten und Prozessanalyse","10000-1197980485-S","Stuttgart","Baden-Württemberg","Deutschland",48.8226255,9.0952796,"9","70499","Ingersheimer Str. 10","Weilimdorf",NA,"Informatica GmbH","2024-05-13","2024-05-13T11:28:36.247","2024-09-01","1Hlq1mWcuqOJBLdVaf9-swPOZNoYPuu-K2UmFTH00iQ=",NA,NA
"Fachinformatiker/in - Daten- und Prozessanalyse","Berufseinsteiger User Helpdesk (m/w/d)","12288-3644063819-S","Fellbach, Württemberg","Baden-Württemberg","Deutschland",48.8022574,9.2818045,"8","70734",NA,NA,NA,"Amadeus Fire AG","2024-05-27","2024-05-27T10:47:04.479","2024-05-28",NA,"https://www.persy.jobs/persy/l/job-d7dim-b",NA
+1 −1
Original line number Diff line number Diff line
@@ -252,7 +252,7 @@ download_all_jobs <- function(searchterm, location, radius) {
  
  # Den entpackten DataFrame anzeigen
  cat("Entpackter DataFrame:\n")
  print(job_postings_unnested)
  head(job_postings_unnested)
  
  
}
+231 −0
Original line number Diff line number Diff line
# docker_script.R

#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# LOAD LIBRARIES ---- 
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
library("readxl")
library("httr")
library("dplyr")
library("jsonlite")
library("lubridate")
library("readr")

#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# HELPER FUNCTIONS ----
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

# Funktion zum Entpacken der DataFrames
unnest_dataframes <- function(x) {
  y <- do.call(data.frame, x)
  if ("data.frame" %in% sapply(y, class)) y <- unnest_dataframes(y)
  return(y)
}

# Funktion zum Anfordern des Tokens
get_token <- function() {
  headers <- c("Content-Type" = 'application/x-www-form-urlencoded')
  
  data <- list(
    client_id = 'c003a37f-024f-462a-b36d-b001be4cd24a',
    client_secret = '32a39620-32b3-4307-9aa1-511e3d7f48a8',
    grant_type = 'client_credentials'
  )
  
  res <- POST(url = 'https://rest.arbeitsagentur.de/oauth/gettoken_cc',
              add_headers(.headers = headers),
              body = data,
              encode = 'form')
  
  token <- content(res)$access_token
  return(token)
}

# Funktion zum Herunterladen aller Jobs
download_all_jobs <- function(searchterm, location, radius) {
  token <- get_token()
  base_url <- "https://rest.arbeitsagentur.de/jobboerse/jobsuche-service/pc/v4/jobs"
  
  # Parameter für die initiale Anfrage
  initial_payload <- list(
    "was" = searchterm,
    "wo" = location,
    size = 1,
    page = 1,
    "umkreis" = radius
  )
  
  # Initiale Anfrage, um die Gesamtanzahl der Ergebnisse zu bekommen
  initial_response <- GET(url = base_url, 
                          add_headers(Authorization = paste("Bearer", token), Accept = "application/json"),
                          query = initial_payload)
  
  initial_content <- rawToChar(initial_response$content)
  Encoding(initial_content) <- "UTF-8"
  initial_json <- fromJSON(initial_content)
  
  # Debugging: Ausgabe des gesamten Inhalts der initialen API-Antwort
  print(initial_json)
  
  # maxErgebnisse bestimmen
  maxErgebnisse <- initial_json$maxErgebnisse
  
  # Debugging: Ausgabe von maxErgebnisse
  cat("Max Ergebnisse:", maxErgebnisse, "\n")
  
  # Anzahl der Seiten berechnen
  size <- 200
  num_pages <- ceiling(maxErgebnisse / size)
  
  # Liste zum Speichern der Ergebnisse von jeder Seite
  all_job_postings <- list()
  
  # Schleife zum Herunterladen aller Seiten
  for (page in 1:num_pages) {
    payload <- list(
      "was" = searchterm,
      "wo" = location,
      size = size,
      page = page,
      "umkreis" = radius
    )
    
    response <- GET(url = base_url, 
                    add_headers(Authorization = paste("Bearer", token), Accept = "application/json"),
                    query = payload)
    
    content <- rawToChar(response$content)
    Encoding(content) <- "UTF-8"
    data <- fromJSON(content)
    
    # Debugging: Ausgabe der Daten für die aktuelle Seite
    print(data)
    
    if (!is.null(data$stellenangebote)) {
      job_postings <- data$stellenangebote
      # Ergebnisse zur Liste hinzufügen
      all_job_postings[[page]] <- job_postings
    } else {
      message("Keine Stellenangebote auf Seite ", page)
    }
  }
  
  # Alle DataFrames in der Liste zu einem gemeinsamen DataFrame zusammenfügen
  if (length(all_job_postings) > 0) {
    job_postings <- bind_rows(all_job_postings)
  } else {
    job_postings <- tibble()
  }
  
  # Den gefilterten DataFrame anzeigen
  print(job_postings)
  
  # Anwenden der Entpackungsfunktion auf job_postings
  job_postings_unnested <- unnest_dataframes(job_postings)
  
  return(job_postings_unnested)
}

# Funktion zum Ermitteln der aktuell aktiven Jobs
get_active_jobs <- function(subfolder) {
  # Alle Dateien im Unterordner auflisten
  files <- list.files(subfolder, full.names = TRUE)
  
  # Dateien nach Datum sortieren (Annahme: Dateinamen enthalten das Datum im Format YYYY-MM-DD)
  files_sorted <- files[order(sapply(files, function(x) as.Date(sub(".(\\d{4}-\\d{2}-\\d{2})..csv", "\\1", basename(x)))))]
  
  # Den aktuellsten vollständigen Datensatz finden (Annahme: Dateinamen enthalten "full" für vollständige Datensätze)
  full_data_files <- grep("full", files_sorted, value = TRUE)
  latest_full_data <- tail(full_data_files, 1)
  
  # Alle inkrementellen Dateien nach dem vollständigen Datensatz filtern, exklusive der heutigen Datei
  incremental_files <- files_sorted[files_sorted > latest_full_data]
  incremental_files <- incremental_files[!grepl(Sys.Date(), incremental_files)]
  
  # Vollständigen Datensatz laden
  active_jobs_df <- read_csv(latest_full_data)
  
  # Über inkrementelle Dateien iterieren und Daten aktualisieren
  for (file in incremental_files) {
    incremental_data <- read_csv(file)
    active_jobs_df <- bind_rows(active_jobs_df, incremental_data)
  }
  
  # Liste der Job-Referenz-IDs extrahieren
  active_job_ids <- active_jobs_df$job_reference_id
  
  return(active_job_ids)
}

# Funktion zum bedingten Speichern der Downloads
conditional_save_downloads <- function(subfolder, jobs, refid_active_jobs = NULL, searchterm) {
  # Das heutige Datum im Format YYYY-MM-DD
  today_date <- Sys.Date()
  
  # Wochentag abrufen (1 = Sonntag, 2 = Montag, ..., 7 = Samstag)
  today_wday <- wday(today_date)
  
  # Pfad des Unterordners erstellen
  base_path <- "C:/Users/Surface/git/ids_2024_thas_public/01_data/downloads"
  subfolder_path <- file.path(base_path, subfolder)
  
  # Sicherstellen, dass der Unterordner existiert, ansonsten erstellen
  if (!dir.exists(subfolder_path)) {
    dir.create(subfolder_path, recursive = TRUE)
  }
  
  # Überprüfen, ob der Unterordner leer ist
  is_empty_subfolder <- length(list.files(subfolder_path)) == 0
  
  # Bedingung: Heute ist Montag oder der Unterordner ist leer
  if (today_wday == 2 || is_empty_subfolder) {
    # Dateiname für den vollständigen Datensatz
    file_name_full <- paste0(today_date, "_jobs_", searchterm, "_full.csv")
    file_path_full <- file.path(subfolder_path, file_name_full)
    
    # Speichern des vollständigen Datensatzes
    write.csv(jobs, file_path_full, row.names = FALSE)
    
    # Ausgabe des Dateipfads zur Bestätigung
    cat("Vollständiger Datensatz gespeichert unter:", file_path_full, "\n")
  } else {
    # Bedingung: refid_active_jobs ist nicht NULL
    if (!is.null(refid_active_jobs)) {
      # Identifizieren neuer und alter Jobs
      new_jobs <- jobs[!jobs$refnr %in% refid_active_jobs, ]
      old_jobs <- data.frame(refnr = refid_active_jobs[refid_active_jobs %in% jobs$refnr])
      
      # Dateinamen für neue und alte Jobs
      file_name_new <- paste0(today_date, "_jobs_", searchterm, "_new.csv")
      file_name_old <- paste0(today_date, "_jobs_", searchterm, "_old.csv")
      
      file_path_new <- file.path(subfolder_path, file_name_new)
      file_path_old <- file.path(subfolder_path, file_name_old)
      
      # Speichern der neuen Jobs
      write.csv(new_jobs, file_path_new, row.names = FALSE)
      
      # Speichern der alten Jobs
      write.csv(old_jobs, file_path_old, row.names = FALSE)
      
      # Ausgabe der Dateipfade zur Bestätigung
      cat("Neue Jobs gespeichert unter:", file_path_new, "\n")
      cat("Alte Jobs gespeichert unter:", file_path_old, "\n")
    } else {
      # Wenn refid_active_jobs NULL ist und es nicht Montag ist, nichts tun
      cat("Keine neuen Daten zu speichern, da refid_active_jobs NULL ist und heute nicht Montag ist.\n")
    }
  }
}

#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# MAIN SCRIPT ----
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

# Alle Jobs herunterladen
all_jobs <- download_all_jobs("Daten", "Stuttgart", 100)

# Aktive Jobs ermitteln
active_jobs <- get_active_jobs("01_data/downloads")

# Downloads bedingt speichern
conditional_save_downloads("00_jobs_searchterm", all_jobs, active_jobs, "daten")