diff options
| -rw-r--r-- | mastoapi.c | 145 |
1 files changed, 137 insertions, 8 deletions
| @@ -3,6 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | #include "xs.h" | 4 | #include "xs.h" |
| 5 | #include "xs_encdec.h" | 5 | #include "xs_encdec.h" |
| 6 | #include "xs_openssl.h" | ||
| 6 | #include "xs_json.h" | 7 | #include "xs_json.h" |
| 7 | #include "xs_io.h" | 8 | #include "xs_io.h" |
| 8 | #include "xs_time.h" | 9 | #include "xs_time.h" |
| @@ -347,9 +348,9 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, | |||
| 347 | printf("mastoapi get:\n%s\n", j); | 348 | printf("mastoapi get:\n%s\n", j); |
| 348 | } | 349 | } |
| 349 | 350 | ||
| 350 | int status = 404; | 351 | int status = 404; |
| 351 | xs_dict *msg = xs_dict_get(req, "q_vars"); | 352 | xs_dict *args = xs_dict_get(req, "q_vars"); |
| 352 | xs *cmd = xs_replace(q_path, "/api/v1", ""); | 353 | xs *cmd = xs_replace(q_path, "/api/v1", ""); |
| 353 | char *v; | 354 | char *v; |
| 354 | 355 | ||
| 355 | snac snac = {0}; | 356 | snac snac = {0}; |
| @@ -376,7 +377,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, | |||
| 376 | 377 | ||
| 377 | if (strcmp(cmd, "/accounts/verify_credentials") == 0) { | 378 | if (strcmp(cmd, "/accounts/verify_credentials") == 0) { |
| 378 | if (logged_in) { | 379 | if (logged_in) { |
| 379 | xs_dict *acct = xs_dict_new(); | 380 | xs *acct = xs_dict_new(); |
| 380 | 381 | ||
| 381 | acct = xs_dict_append(acct, "id", xs_dict_get(snac.config, "uid")); | 382 | acct = xs_dict_append(acct, "id", xs_dict_get(snac.config, "uid")); |
| 382 | acct = xs_dict_append(acct, "username", xs_dict_get(snac.config, "uid")); | 383 | acct = xs_dict_append(acct, "username", xs_dict_get(snac.config, "uid")); |
| @@ -386,12 +387,13 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, | |||
| 386 | acct = xs_dict_append(acct, "note", xs_dict_get(snac.config, "bio")); | 387 | acct = xs_dict_append(acct, "note", xs_dict_get(snac.config, "bio")); |
| 387 | acct = xs_dict_append(acct, "url", snac.actor); | 388 | acct = xs_dict_append(acct, "url", snac.actor); |
| 388 | 389 | ||
| 389 | xs *avatar = xs_dup(xs_dict_get(snac.config, "avatar")); | 390 | xs *avatar = NULL; |
| 391 | char *av = xs_dict_get(snac.config, "avatar"); | ||
| 390 | 392 | ||
| 391 | if (xs_is_null(avatar) || *avatar == '\0') { | 393 | if (xs_is_null(av) || *av == '\0') |
| 392 | xs_free(avatar); | ||
| 393 | avatar = xs_fmt("%s/susie.png", srv_baseurl); | 394 | avatar = xs_fmt("%s/susie.png", srv_baseurl); |
| 394 | } | 395 | else |
| 396 | avatar = xs_dup(av); | ||
| 395 | 397 | ||
| 396 | acct = xs_dict_append(acct, "avatar", avatar); | 398 | acct = xs_dict_append(acct, "avatar", avatar); |
| 397 | 399 | ||
| @@ -403,6 +405,133 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, | |||
| 403 | status = 422; // "Unprocessable entity" (no login) | 405 | status = 422; // "Unprocessable entity" (no login) |
| 404 | } | 406 | } |
| 405 | } | 407 | } |
| 408 | else | ||
| 409 | if (strcmp(cmd, "/timelines/home") == 0) { | ||
| 410 | /* the private timeline */ | ||
| 411 | if (logged_in) { | ||
| 412 | const char *max_id = xs_dict_get(args, "max_id"); | ||
| 413 | const char *since_id = xs_dict_get(args, "since_id"); | ||
| 414 | const char *min_id = xs_dict_get(args, "min_id"); | ||
| 415 | const char *limit_s = xs_dict_get(args, "limit"); | ||
| 416 | int limit = 20; | ||
| 417 | int cnt = 0; | ||
| 418 | |||
| 419 | if (!xs_is_null(limit_s)) | ||
| 420 | limit = atoi(limit_s); | ||
| 421 | |||
| 422 | xs *out = xs_list_new(); | ||
| 423 | xs *timeline = timeline_list(&snac, "private", 0, limit); | ||
| 424 | xs_list *p = timeline; | ||
| 425 | xs_str *v; | ||
| 426 | |||
| 427 | while (xs_list_iter(&p, &v) && cnt < limit) { | ||
| 428 | xs *msg = NULL; | ||
| 429 | |||
| 430 | if (max_id) | ||
| 431 | break; | ||
| 432 | |||
| 433 | /* get the entry */ | ||
| 434 | if (!valid_status(timeline_get_by_md5(&snac, v, &msg))) | ||
| 435 | continue; | ||
| 436 | |||
| 437 | /* discard not-Notes */ | ||
| 438 | if (strcmp(xs_dict_get(msg, "type"), "Note") != 0) | ||
| 439 | continue; | ||
| 440 | |||
| 441 | xs *actor = NULL; | ||
| 442 | actor_get(&snac, xs_dict_get(msg, "attributedTo"), &actor); | ||
| 443 | |||
| 444 | /* if the author is not here, discard */ | ||
| 445 | if (actor == NULL) | ||
| 446 | continue; | ||
| 447 | |||
| 448 | xs *acct = xs_dict_new(); | ||
| 449 | |||
| 450 | const char *display_name = xs_dict_get(actor, "name"); | ||
| 451 | if (xs_is_null(display_name) || *display_name == '\0') | ||
| 452 | display_name = xs_dict_get(actor, "preferredUsername"); | ||
| 453 | |||
| 454 | const char *id = xs_dict_get(actor, "id"); | ||
| 455 | xs *acct_md5 = xs_md5_hex(id, strlen(id)); | ||
| 456 | acct = xs_dict_append(acct, "id", acct_md5); | ||
| 457 | acct = xs_dict_append(acct, "username", xs_dict_get(actor, "preferredUsername")); | ||
| 458 | acct = xs_dict_append(acct, "acct", xs_dict_get(actor, "preferredUsername")); | ||
| 459 | acct = xs_dict_append(acct, "display_name", display_name); | ||
| 460 | acct = xs_dict_append(acct, "created_at", xs_dict_get(actor, "published")); | ||
| 461 | acct = xs_dict_append(acct, "note", xs_dict_get(actor, "summary")); | ||
| 462 | acct = xs_dict_append(acct, "url", id); | ||
| 463 | |||
| 464 | xs *avatar = NULL; | ||
| 465 | xs_dict *av = xs_dict_get(actor, "icon"); | ||
| 466 | |||
| 467 | if (xs_type(av) == XSTYPE_DICT) | ||
| 468 | avatar = xs_dup(xs_dict_get(av, "url")); | ||
| 469 | else | ||
| 470 | avatar = xs_fmt("%s/susie.png", srv_baseurl); | ||
| 471 | |||
| 472 | acct = xs_dict_append(acct, "avatar", avatar); | ||
| 473 | |||
| 474 | xs *f = xs_val_new(XSTYPE_FALSE); | ||
| 475 | xs *t = xs_val_new(XSTYPE_TRUE); | ||
| 476 | xs *n = xs_val_new(XSTYPE_NULL); | ||
| 477 | xs *el = xs_list_new(); | ||
| 478 | xs *ed = xs_dict_new(); | ||
| 479 | char *tmp; | ||
| 480 | |||
| 481 | xs *st = xs_dict_new(); | ||
| 482 | |||
| 483 | st = xs_dict_append(st, "id", v); | ||
| 484 | st = xs_dict_append(st, "uri", xs_dict_get(msg, "id")); | ||
| 485 | st = xs_dict_append(st, "created_at", xs_dict_get(msg, "published")); | ||
| 486 | st = xs_dict_append(st, "account", acct); | ||
| 487 | st = xs_dict_append(st, "content", xs_dict_get(msg, "content")); | ||
| 488 | st = xs_dict_append(st, "visibility", "public"); | ||
| 489 | |||
| 490 | tmp = xs_dict_get(msg, "sensitive"); | ||
| 491 | if (xs_is_null(tmp)) | ||
| 492 | tmp = f; | ||
| 493 | |||
| 494 | st = xs_dict_append(st, "sensitive", tmp); | ||
| 495 | st = xs_dict_append(st, "spoiler_text", ""); | ||
| 496 | |||
| 497 | st = xs_dict_append(st, "media_attachments", el); | ||
| 498 | st = xs_dict_append(st, "mentions", el); | ||
| 499 | st = xs_dict_append(st, "tags", el); | ||
| 500 | st = xs_dict_append(st, "emojis", el); | ||
| 501 | |||
| 502 | st = xs_dict_append(st, "reblogs_count", xs_number_new(0)); | ||
| 503 | st = xs_dict_append(st, "favourites_count", xs_number_new(0)); | ||
| 504 | st = xs_dict_append(st, "replies_count", xs_number_new(0)); | ||
| 505 | |||
| 506 | st = xs_dict_append(st, "url", xs_dict_get(msg, "id")); | ||
| 507 | |||
| 508 | st = xs_dict_append(st, "in_reply_to_id", n); | ||
| 509 | st = xs_dict_append(st, "in_reply_to_account_id", n); | ||
| 510 | st = xs_dict_append(st, "reblog", n); | ||
| 511 | st = xs_dict_append(st, "poll", n); | ||
| 512 | st = xs_dict_append(st, "card", ed); | ||
| 513 | |||
| 514 | st = xs_dict_append(st, "language", "en"); | ||
| 515 | st = xs_dict_append(st, "text", ""); | ||
| 516 | st = xs_dict_append(st, "edited_at", n); | ||
| 517 | |||
| 518 | out = xs_list_append(out, st); | ||
| 519 | |||
| 520 | cnt++; | ||
| 521 | } | ||
| 522 | |||
| 523 | *body = xs_json_dumps_pp(out, 4); | ||
| 524 | *ctype = "application/json"; | ||
| 525 | status = 200; | ||
| 526 | } | ||
| 527 | else { | ||
| 528 | status = 401; // unauthorized | ||
| 529 | } | ||
| 530 | } | ||
| 531 | else | ||
| 532 | if (strcmp(cmd, "/timelines/public") == 0) { | ||
| 533 | /* the public timeline */ | ||
| 534 | } | ||
| 406 | 535 | ||
| 407 | /* user cleanup */ | 536 | /* user cleanup */ |
| 408 | if (logged_in) | 537 | if (logged_in) |