Last active
December 16, 2015 17:19
-
-
Save asmuth/5469371 to your computer and use it in GitHub Desktop.
product listview rendering in c (WIP)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This file is part of the "LoveOS" project | |
// (c) 2013 DaWanda GmbH, Paul Asmuth <paul@paulasmuth.com>, et al. | |
// All rights reserved. | |
#include "plv.h" | |
#include "ruby.h" | |
VALUE loveos_render = Qnil; | |
// glue code to call the plv_load_json + plv_render methods from ruby | |
VALUE method_render_product_listview_from_json(VALUE self, VALUE json, VALUE lang) { | |
VALUE res; | |
char* buf; | |
plv_data* plv; | |
if (rb_type(json) != RUBY_T_STRING) { | |
rb_raise(rb_eTypeError, "first argument (json) must be a string"); | |
return 0; | |
} | |
if (rb_type(lang) != RUBY_T_STRING) { | |
rb_raise(rb_eTypeError, "second argument (lang) must be a string"); | |
return 0; | |
} | |
plv = calloc(1, sizeof(plv_data)); | |
if (!plv_load_json(plv, RSTRING_PTR(json), RSTRING_PTR(lang))) { | |
rb_raise(rb_eRuntimeError, "error loading product_listview JSON, invalid structure?"); | |
free(plv); | |
return 1; | |
} | |
buf = plv_render(plv); | |
res = rb_str_new2(buf); | |
free(buf); | |
free(plv); | |
return res; | |
} | |
void Init_loveos_render() { | |
loveos_render = rb_define_module("NativeRender"); | |
rb_define_method(loveos_render, "render_product_listview_from_json", | |
method_render_product_listview_from_json, 2); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This file is part of the "LoveOS" project | |
// (c) 2013 DaWanda GmbH, Paul Asmuth <paul@paulasmuth.com>, et al. | |
// All rights reserved. | |
#include "plv.h" | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <jansson.h> | |
#include <string.h> | |
// loads a product_listview json blob (from sqltap) into the plv struct | |
// returns 0 on error, 1 on success | |
int plv_load_json(plv_data* plv, char* json, char* lang) { | |
json_t *root, *product, *images, *image, *user, *shop, *translations; | |
json_error_t error; | |
if (!(root = json_loads(json, 0, &error))) | |
return PLV_LOAD_ERROR; | |
if (!json_is_object(root)) | |
goto error; | |
if (!(product = json_object_get(root, "product"))) | |
goto error; | |
if (!(user = json_object_get(product, "user"))) | |
goto error; | |
if (!(shop = json_object_get(user, "shop"))) | |
goto error; | |
if (!(images = json_object_get(product, "images"))) | |
goto error; | |
if (!(translations = json_object_get(product, "translations"))) | |
goto error; | |
if (!json_is_array(images)) | |
goto error; | |
if (!json_is_array(translations)) | |
goto error; | |
if (!(image = json_array_get(images, 0))) | |
goto error; | |
plv_load_json_attr(product, plv->id, "id"); | |
plv_load_json_attr(product, plv->slug, "slug"); | |
plv_load_json_attr(product, plv->cents, "cents"); | |
plv_load_json_attr(image, plv->image_filename, "filename"); | |
plv_load_json_attr(shop, plv->shop_name, "subdomain"); | |
plv_load_json_attr(product, plv->price_unit, "unit"); | |
plv_load_json_attr(product, plv->cents, "cents"); | |
plv_load_json_attr(product, plv->currency, "currency"); | |
plv_load_json_attr(product, plv->price_milli_units_per_item, | |
"milli_units_per_item"); | |
plv_load_json_translations(plv, translations, lang); | |
json_decref(root); | |
return PLV_LOAD_SUCCESS; | |
error: | |
json_decref(root); | |
return PLV_LOAD_ERROR; | |
} | |
// it ain't pretty but its fast... remember to free the return value | |
// after use (!) | |
char* plv_render(plv_data* plv) { | |
size_t buf_size = sizeof(plv_data) + 4096; | |
char* buf = calloc(1, buf_size); | |
plv_prepare(plv); | |
// oh yeah, we can render the listview with one big printf ;) | |
snprintf(buf, buf_size, PLV_TEMPLATE, | |
plv->url, | |
plv->image_url, | |
plv->url, | |
plv->title, | |
plv->shop_name, | |
plv->shop_name, | |
plv->price_milli_units_per_item, | |
plv->price_unit, | |
plv->price / 100.0, | |
plv->currency | |
); | |
return buf; | |
} | |
void plv_prepare(plv_data* plv) { | |
char s3_folder_id_str[16] = "\0"; | |
// prepare id and price | |
plv->id_int = atoi(plv->id); | |
plv->price = atoi(plv->cents); | |
// prepare product url | |
snprintf(plv->url, PLV_ATTR_SIZE, "/product/%s-%s", | |
plv->id, plv->slug); | |
// prepare image url | |
if ((plv->id_int / PLV_S3_MAX_ID + 1) > 1) | |
snprintf(s3_folder_id_str, 16, "%i", plv->id_int / PLV_S3_MAX_ID + 1); | |
snprintf(plv->image_url, PLV_ATTR_SIZE, "http://%s/Product%s/%i/%i/listview/%s", | |
PLV_S3_HOST, | |
s3_folder_id_str, | |
plv->id_int / 1000, | |
plv->id_int, | |
plv->image_filename | |
); | |
// prepare product title | |
} | |
void plv_render_string(char** buf, const char* str) { | |
strncpy(*buf, str, PLV_ATTR_SIZE); | |
*buf += strlen(str); | |
} | |
void plv_load_json_attr(json_t* base, char* dst, const char* attr) { | |
json_t* tmp = json_object_get(base, attr); | |
if (json_is_string(tmp)) | |
strncpy(dst, json_string_value(tmp), PLV_ATTR_SIZE); | |
} | |
void plv_load_json_translations(plv_data* plv, json_t* translations, char* lang) { | |
json_t *translation, *tmp; | |
int n; | |
for (n = (int) json_array_size(translations); n > 0; n--) { | |
translation = json_array_get(translations, n - 1); | |
tmp = json_object_get(translation, "attribute"); | |
if (strcmp(json_string_value(tmp), "title")) | |
continue; | |
tmp = json_object_get(translation, "text"); | |
if (json_is_string(tmp)) | |
strncpy(plv->title, json_string_value(tmp), PLV_ATTR_SIZE); | |
tmp = json_object_get(translation, "language"); | |
if (!strcmp(json_string_value(tmp), lang)) | |
break; | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This file is part of the "LoveOS" project | |
// (c) 2013 DaWanda GmbH, Paul Asmuth <paul@paulasmuth.com>, et al. | |
// All rights reserved. | |
#ifndef PLV_H | |
#define PLV_H | |
#include <jansson.h> | |
#define PLV_ATTR_SIZE 1024 | |
#define PLV_LOAD_ERROR 0 | |
#define PLV_LOAD_SUCCESS 1 | |
#define PLV_S3_HOST "dawandaimages.s3.amazonaws.com" | |
#define PLV_S3_MAX_ID 31991150 | |
#define PLV_TEMPLATE \ | |
"<li>\ | |
<article class='product'>\ | |
<a href='#pin' class='product-pin-action'>pin this product</a>\ | |
<a href='%s' class='product-pic'>\ | |
<img src='%s' />\ | |
<a href='%s' class='product-title'>%s</a>\ | |
<a href='/shop/%s' class='product-shop'>%s</a>\ | |
<section class='price discounted converted has-pp'\ | |
data-milli-units-per-item='%s' data-unit='%s'>%.2f %s</section>\ | |
</a>\ | |
</article>\ | |
</li>" | |
typedef struct { | |
char id[PLV_ATTR_SIZE]; | |
int id_int; | |
char slug[PLV_ATTR_SIZE]; | |
char url[PLV_ATTR_SIZE]; | |
char image_url[PLV_ATTR_SIZE]; | |
char image_filename[PLV_ATTR_SIZE]; | |
char title[PLV_ATTR_SIZE]; | |
char shop_name[PLV_ATTR_SIZE]; | |
char cents[PLV_ATTR_SIZE]; | |
char currency[PLV_ATTR_SIZE]; | |
int price; | |
char price_milli_units_per_item[PLV_ATTR_SIZE]; | |
char price_unit[PLV_ATTR_SIZE]; | |
} plv_data; | |
int plv_load_json(plv_data* plv, char* json, char* lang); | |
void plv_load_json_attr(json_t* base, char* dst, const char* attr); | |
void plv_load_json_translations(plv_data* plv, json_t* translations, char* lang); | |
char* plv_render(plv_data* plv); | |
void plv_prepare(plv_data* plv); | |
void plv_render_string(char** buf, const char* str); | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment