cc main.c -lcurl && ./a.out https://www.linux.org.ru/people/crutch_master/profile && abc2midi lm.abc && xdg-open ./lm46.mid
main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <curl/curl.h>
#define MAX_DAYS 365
struct year
{
uint32_t date;
uint32_t messages;
}user_year[MAX_DAYS];
static size_t profile_json_size = 0;
size_t get_profile_json(void* ptr, size_t size,size_t nmem, void* userdata)
{
if(nmem==0) return 0;
char** str=(char**)userdata;
const char* input=(const char*)ptr;
if(!str[0])
{
str[0]=malloc(nmem+1);
}else{
str[0]=realloc(str[0], profile_json_size+nmem+1);
}
memcpy(str[0]+profile_json_size, input, nmem);
profile_json_size+=nmem;
(*str)[profile_json_size]='\0';
return nmem;
}
int sort_compare(const void *a,const void * b)
{
if(((struct year*)a)->date < ((struct year*)b)->date)
{
return -1;
}else if(((struct year*)a)->date > ((struct year*)b)->date)
{
return 1;
}else
{
return 0;
};
return 0;
}
void sort_profile_year(struct year* y)
{
qsort(y,MAX_DAYS,sizeof(struct year),sort_compare);
}
void distribute_profile_year(struct year * y)
{
struct year yn[MAX_DAYS]={0};
uint32_t day = 0;
for (int i = 0; i != MAX_DAYS; ++i)
{
if(y[i].date != 0) {day=i;break;};
}
yn[0].date=y[day].date;
for (int i = 1; i != MAX_DAYS; ++i)
{
yn[i].date=yn[i-1].date+86400;
}
for (int i = 0,c=day; i != MAX_DAYS; ++i)
{
if(yn[i].date == y[day].date)
{
yn[i].messages=y[day++].messages;
}
y[i]=yn[i];
}
}
int main(int argc, char *argv[])
{
enum io_args
{ arg_url = 1,
arg_out = 2,
};
CURL * curl;
CURLcode res;
curl = curl_easy_init();
char * profile_json_data = NULL;
char urlbuff[1024]={0};
snprintf(urlbuff,1023,"%s%s",argv[arg_url],"?year-stats");
if(curl)
{
curl_easy_setopt(curl, CURLOPT_URL,urlbuff);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &profile_json_data);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,get_profile_json);
res = curl_easy_perform(curl);
if(res != CURLE_OK)
{
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
curl_easy_cleanup(curl);
return 1;
}
curl_easy_cleanup(curl);
}
for (size_t i = 0,c = 0; i < profile_json_size; ++i)
{
unsigned int messges_nums=0;
unsigned int messges_date=0;
if(profile_json_data[i]=='"')
{
if(sscanf(profile_json_data+i,"\"%d\"",&messges_date)==1)
{
user_year[c].date = messges_date;
};
}
if(profile_json_data[i]==':')
{
sscanf(profile_json_data+i,": %d",&messges_nums);
user_year[c++].messages=messges_nums;
}
}
sort_profile_year(user_year);
distribute_profile_year(user_year);
for (int i = 0; i != MAX_DAYS; ++i)
{
printf("[%d][%3d] -> %i\n",user_year[i].date,user_year[i].messages,i);
}
FILE * out = fopen("lm.abc","w");
if(!out)
{
return 1;
}
fprintf(out, "X:46\nK:C\n");
static char * abc_language_table[30] =
{
"F,,","b",a","g","f","e","d","c ",
"B,","A,","G,","F,","E,","D,","C,",
"B,,","A,,","G,,","F,,","E,,",
"D,,","C,,","B,,,","A,,,","G,,,",
"F,,,","E,,,","D,,,","C,,,",
};
static char * xM[7]=
{
"\"Cm\" ",
"\"Dm\" ",
"\"Em\" ",
"\"Fm\" ",
"\"Gm\" ",
"\"Am\" ",
"\"Bm\" ",
};
if(strlen(urlbuff) > 32)
{
int size =strlen(urlbuff);
for (int i = 32; urlbuff[i] != '/' && i < size;)
{
fprintf(out, "%s",abc_language_table[urlbuff[i++] % 29]);
}
}
for (int i = 0; i < MAX_DAYS; ++i)
{
if(i%7==0)
{
fprintf(out, "\n%s", xM[i%6]);
}
fprintf(out, "%s",abc_language_table[user_year[i].messages % 29]);
}
fclose(out);
return 0;
}
:D