summaryrefslogtreecommitdiff
path: root/input_gadgets.c
blob: cf6e3d65a1b0276193f44da5668d817dbe88f0b5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include <string.h>
#include <stdlib.h>
#include <curl/curl.h>
#include <regex.h>

#include "input_gadgets.h"

#define temperatur_regex  "<strong>\\s*\n\\s*Wetterdaten vom ([0-9.]{10}) um ([0-9:]{5}) MEZ</strong>(.|\n)*>Temperatur</td>\\s*\n\\s*<td [^>]*><strong>([^<]*)</strong>"

static size_t
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
  size_t realsize = size * nmemb;
  struct MemoryStruct *mem = (struct MemoryStruct *)userp;
 
  char *ptr = realloc(mem->memory, mem->size + realsize + 1);
  if(ptr == NULL) {
    /* out of memory! */ 
    printf("not enough memory (realloc returned NULL)\n");
    return 0;
  }
 
  mem->memory = ptr;
  memcpy(&(mem->memory[mem->size]), contents, realsize);
  mem->size += realsize;
  mem->memory[mem->size] = 0;
 
  return realsize;
}

int gadgets_retrieve_temperature(unsigned char *output, int max_len)
{
  CURL *curl_handle;
  CURLcode res;
  struct MemoryStruct chunk;
  int ret_val;

  chunk.memory = malloc(1);
  chunk.size = 0;

  curl_global_init(CURL_GLOBAL_ALL);

  curl_handle = curl_easy_init();
  if (!curl_handle) {
    perror("Failed to init curl");
    free(chunk.memory);
    return EXIT_FAILURE;
  }
  curl_easy_setopt(curl_handle, CURLOPT_URL, "https://wetter.mb.fh-jena.de/station/datenbank/php_giese/online.php");
  curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L);
  curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
  curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);
  curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
  res = curl_easy_perform(curl_handle);
  curl_easy_cleanup(curl_handle);
  if (res != CURLE_OK) {
    fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
    free(chunk.memory);
    return EXIT_FAILURE;
  }

  regex_t re;
  regmatch_t rm[5];
  if (regcomp(&re, temperatur_regex, REG_EXTENDED|REG_NEWLINE) != 0)
  {
    fprintf(stderr, "Failed to compile regex '%s'\n", temperatur_regex);
    free(chunk.memory);
    return EXIT_FAILURE;
  }
  if (ret_val = regexec(&re, chunk.memory, 5, rm, 0))
  {
    char *reg_err;
    reg_err = malloc(1024);
    regerror(ret_val, &re, reg_err, 1024);
    fprintf(stderr, "%d %s\n",ret_val,reg_err);
    regfree(&re);
    free(chunk.memory);
    return EXIT_FAILURE;
  }
  regfree(&re);
  int i = snprintf(output, max_len, "%.*s (%.*s %.*s)",
    (int)(rm[4].rm_eo - rm[4].rm_so), (char*)(chunk.memory + rm[4].rm_so),
    (int)(rm[2].rm_eo - rm[2].rm_so), (char*)(chunk.memory + rm[2].rm_so),
    (int)(rm[1].rm_eo - rm[1].rm_so), (char*)(chunk.memory + rm[1].rm_so)
  );
  for (; i>=0; i--)
    if (output[i] == '(')
      break;
  for (; i>=0; i--)
    if (output[i] == '.')
      output[i] = ',';
  free(chunk.memory);
  return 0;
}