Browse Source

Swarfarm option added tho the update command. Does nothing, but has a basic CURL implementation for the team list.

Iñigo Valentin 4 years ago
parent
commit
dcee6af631

+ 1 - 1
Makefile

@@ -22,7 +22,7 @@ CFLAGS=
 OPTS_DEBUG=-Wall -g
 OPTS_TEST=
 OPTS=-O3
-LIBS=-lsqlite3 -lm -ljson-c
+LIBS=-lsqlite3 -lm -ljson-c -lcurl
 OUT=bin/RuneOptimizer
 OUT_DEBUG=bin/RuneOptimizer_DEBUG
 TEST_SRC=src/test/RuneOptimizerTest.c

+ 2 - 0
src/RuneOptimizer/RuneOptimizer.c

@@ -31,6 +31,7 @@
 #include <json-c/json.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <curl/curl.h>
 #include "RuneOptimizer.h"
 #include "error/error.h"
 #include "db/db.c"
@@ -42,6 +43,7 @@
 #include "player/player.c"
 #include "gui/gui.c"
 
+
 int main(int argc, char *argv[]){
     // Parse the arguments to find the command (index 1)
 

+ 6 - 0
src/RuneOptimizer/update/update.c

@@ -29,6 +29,7 @@
 #include "update_json_unit.c"
 #include "update_info.c"
 #include "update_json.c"
+#include "update_swarfarm.c"
 #include "update_efficiency.c"
 
 /**
@@ -88,6 +89,11 @@ int cmd_update(int argc, char *argv[]){
             );
         }
     }
+    if (NULL != strstr(argv[0], "swarfarm.com")){
+        return update_swarfarm(
+          argv[0], six_stars, with_runes, clear_teams, gui
+        );
+    }
     // TODO: More ifs as more options are implemented...
     fprintf(stderr, "Unknwon source supplied: %s\n", argv[0]);
     return ERROR_INPUT_UPDATE_UNKNOWN_SOURCE;

+ 18 - 0
src/RuneOptimizer/update/update.h

@@ -368,6 +368,24 @@ void update_rune_totals(struct DB_Rune *rune);
  */
 int update_efficiency(char *id, float *efficiency, float *max_efficiency);
 
+/**
+ * Updates the database from a swarfarm URL.
+ *
+ * @param[in] url Swarfarm profile URL.
+ * @param[in] six_stars Indicator to import only 6* units. Units with runes will
+ * be saved anyway.
+ * @param[in] with_runes Indicator to import only units with runes.
+ * @param[in] clear_teams Indicator to recreate tables teams and units_teams.
+ * @param[in] gui Indicator to format output for thr GUI.
+ * @return SUCCESS or an error code. See
+ * <a href="file:../error/error.h">../error/error.h</a> for a list of error
+ * codes.
+ */
+int update_swarfarm(
+  char url[], unsigned char six_stars,
+  unsigned char with_runes, unsigned char clear_teams, unsigned char gui
+);
+
 /**
  * Parses the command parameters and calls one of the update functions.
  *

+ 184 - 0
src/RuneOptimizer/update/update_swarfarm.c

@@ -0,0 +1,184 @@
+/*
+ * This file is part of RuneOptimizer.
+ *
+ * RuneOptimizer is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option)
+ * any later version.
+ *
+ * RuneOptimizer is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * RuneOptimizer. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+/**
+ * @file update_swarfarm.c
+ * Implementation of update_swarfarm.
+ */
+
+typedef struct Swarfarm_Response {
+   char *response;
+   size_t size;
+} Swarfarm_Response;
+
+
+static size_t update_swarfarm_callback(
+  void *data, size_t size, size_t nmemb, void *response
+){
+    size_t real_size = size * nmemb;
+    Swarfarm_Response *resp = (Swarfarm_Response *)response;
+    char *response_ptr = realloc(resp->response, resp->size + real_size + 1);
+    if (NULL == response_ptr){
+        // TODO: No more memory to realocate, do something!
+        return(0);
+    }
+    resp->response = response_ptr;
+    memcpy(&(resp->response[resp->size]), data, real_size);
+    resp->size += real_size;
+    resp->response[resp->size] = 0;
+    return(real_size);
+}
+
+int update_swarfarm(
+  char url[], unsigned char six_stars,
+  unsigned char with_runes, unsigned char clear_teams, unsigned char gui
+){
+    printf("UPDATE SWARFARM: %s\n", url);
+    char *profile_name = strstr(url, "/profile/");
+    if (profile_name == NULL){
+        // TODO: ERROR, return
+    }
+    profile_name += 9;
+    printf("PR NAME %s\n", profile_name);
+    if (NULL != strstr(profile_name, "/")){
+        profile_name[strcspn(profile_name, "/")] = '\0';
+        printf("SHORT: %s\n", profile_name);
+    }
+    char teams_url[128];
+    sprintf(teams_url, "https://swarfarm.com/api/v2/profiles/%s/teams/", profile_name);
+    printf("TEAM_URL: %s\n", teams_url);
+    Swarfarm_Response response = {0};
+
+      //wt.readptr = output;
+      //wt.sizeread = strlen(output);
+
+    // TODO: separate this to a function
+    CURL *curl;
+    curl = curl_easy_init();
+    CURLcode res;
+    /*
+     * Add your processing
+     */
+
+    curl_easy_setopt(curl, CURLOPT_URL, teams_url);
+    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
+    //curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, update_swarfarm_teams);
+    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, update_swarfarm_callback);
+    curl_easy_setopt(curl, CURLOPT_MAXFILESIZE, 10000000L);
+    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 50L); // 30 seconds
+    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&response);
+      //curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, (long)CURL_HTTP_VERSION_3);
+      /* Perform the request, res will get the return code */
+    res = curl_easy_perform(curl);
+    /* Check for errors */
+    if(res != CURLE_OK){
+        fprintf(
+          stderr, "Error geting teams from the SwarFarm API: %s\n",
+          curl_easy_strerror(res)
+        );
+    }
+    curl_easy_cleanup(curl);
+
+    printf("  OUTPUT: %s\n", response.response);
+
+    int total_teams = 0;
+    json_object *root = json_tokener_parse(response.response);
+    if (!root){
+            fprintf(
+              stderr, "Invalid JSON recieved from SwarFarm when querying teams\n"
+            );
+            return(-1); // TODO ERROR CODE
+        }
+    json_object *team_count = json_object_object_get(root, "count");
+    total_teams = json_object_get_int(team_count);
+    printf("TOTAL TEAMS: %d\n", total_teams);
+
+
+printf("\n\nRETURNING\n");
+    return(0);
+
+    // Counters for objcts saved
+    /*unsigned int total_units = 0;
+    unsigned int total_runes = 0;
+    unsigned int total_stats = 0;
+
+    if (gui == FALSE) printf("Updating from json url: %s\n", url);
+
+    // Read the JSON content
+    json_object *root = json_object_from_file(url);
+    if (!root){
+        fprintf(stderr, "Cant access url: %s\n", url);
+        return(ERROR_INPUT_UPDATE_UNKNOWN_SOURCE);
+    }
+
+    json_object *wizard_id = json_object_object_get(root, "wizard_id");
+    json_object *wizard_info = json_object_object_get(root, "wizard_info");
+    json_object *wizard_name =
+      json_object_object_get(wizard_info, "wizard_name");
+    json_object *wizard_level =
+      json_object_object_get(wizard_info, "wizard_level");
+    printf("Player ID: %s\n", json_object_get_string(wizard_id));
+    printf("Player name: %s\n", json_object_get_string(wizard_name));
+    printf("Player level: %s\n", json_object_get_string(wizard_level));
+    fflush(stdout); // To refresh GUI output.
+
+    // Recreate the database tables
+    int status = update_db_tables(clear_teams);
+    if (SUCCESS != status) return(status);
+
+    // Parse runes
+    json_object *runes = json_object_object_get(root, "runes");
+    int rune_count = json_object_array_length(runes);
+    json_object *idx;
+    for (int i = 0; i < rune_count; i++){
+        total_runes ++;
+        idx = json_object_array_get_idx(runes, i);
+        status = update_json_rune(idx, "");
+        if (status != -1) total_stats += status;
+    }
+
+    // Parse units
+    json_object *unit_list = json_object_object_get(root, "unit_list");
+    int unit_count = json_object_array_length(unit_list);
+    for (int i = 0; i < unit_count; i++){
+        idx = json_object_array_get_idx(unit_list, i);
+
+        status = update_json_unit(
+          idx, six_stars, with_runes, &total_runes, &total_stats
+        );
+        if (status == 1) total_units ++;
+    }
+
+    status = update_current_stats();
+    if (SUCCESS != status) return(status);
+
+    // Insert into table info
+    status = update_info(
+      json_object_get_string(wizard_id),
+      json_object_get_string(wizard_name),
+      json_object_get_string(wizard_level)
+    );
+    if (SUCCESS != status) return(status);
+
+    // All parsed
+    printf("%d units saved.\n", total_units);
+    printf("%d runes saved.\n", total_runes);
+    printf("%d rune stats saved.\n", total_stats);
+    printf("Player info updated\n");*/
+
+    return(SUCCESS);
+}