aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorqorg11 <qorg@vxempire.xyz>2021-07-24 21:06:03 +0200
committerqorg11 <qorg@vxempire.xyz>2021-07-24 21:06:03 +0200
commit180bcfb9ae5991166eeb465cbd43a83bf8d4b828 (patch)
tree47287479157cfa45ef9609602bb3cc9c6ab63e1a
parent079f53ad97241c9933864169a6f77c5fd4381084 (diff)
parent7610f6300f78e333d26ca99f84ccb1f4a3c7147a (diff)
downloaddemiurge-180bcfb9ae5991166eeb465cbd43a83bf8d4b828.tar.gz
demiurge-180bcfb9ae5991166eeb465cbd43a83bf8d4b828.zip
Merge branch 'feature-follow'
-rw-r--r--src/Makefile6
-rw-r--r--src/asprintf.c8
-rw-r--r--src/asprintf.h4
-rw-r--r--src/follow.c148
-rw-r--r--src/follow.h5
-rw-r--r--src/login.c14
-rw-r--r--src/main.c34
-rw-r--r--src/post.c4
-rw-r--r--src/upload_file.c4
9 files changed, 196 insertions, 31 deletions
diff --git a/src/Makefile b/src/Makefile
index e0dc9ae..c74d14e 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,13 +1,13 @@
# demiurge makefile
TARGET = demiurge
-OBJS = login.o util.o post.o main.o upload_file.o
+OBJS = login.o util.o post.o main.o upload_file.o asprintf.o follow.o
CC = cc
-CFLAGS = -O2 -MD -std=c11 -Wall -Wextra -lcurl -lreadline -ljson-c
+CFLAGS += -O2 -MD -std=c11 -Wall -Wextra -lcurl -g -lreadline -ljson-c
$(TARGET): $(OBJS)
- $(CC) $(OBJS) $(CFLAGS) $(CFLAGSDEF) -o $(TARGET)
+ $(CC) $(OBJS) $(CFLAGS) -o $(TARGET)
%.o: %.c
$(CC) -c $(CFLAGS) $(CFLAGSDEF) $< -o $@
diff --git a/src/asprintf.c b/src/asprintf.c
index 8026c52..ee01c2e 100644
--- a/src/asprintf.c
+++ b/src/asprintf.c
@@ -20,20 +20,20 @@
#include <stdarg.h>
#include "asprintf.h"
-/* Implementation of asprintf() */
+/* Implementation of dm_asprintf() */
int
-asprintf(char **restrict strp, const char *restrict fmt, ...)
+dm_asprintf(char **restrict strp, const char *restrict fmt, ...)
{
va_list args;
int size = 0;
va_start(args, fmt);
va_end(args);
- return size = vasprintf(strp, fmt, args);
+ return size = dm_vasprintf(strp, fmt, args);
}
int
-vasprintf(char **restrict strp, const char *restrict fmt, va_list ap)
+dm_vasprintf(char **restrict strp, const char *restrict fmt, va_list ap)
{
va_list args;
va_copy(args, ap);
diff --git a/src/asprintf.h b/src/asprintf.h
index 76f1f4f..fe26354 100644
--- a/src/asprintf.h
+++ b/src/asprintf.h
@@ -18,7 +18,7 @@
#include <stdarg.h>
int
-asprintf(char **restrict strp, const char *restrict fmt, ...);
+dm_asprintf(char **restrict strp, const char *restrict fmt, ...);
int
-vasprintf(char **restrict strp, const char *restrict fmt, va_list ap);
+dm_vasprintf(char **restrict strp, const char *restrict fmt, va_list ap);
diff --git a/src/follow.c b/src/follow.c
new file mode 100644
index 0000000..e21808e
--- /dev/null
+++ b/src/follow.c
@@ -0,0 +1,148 @@
+/*
+ This file is part of demiurge.
+
+ demiurge 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.
+
+ demiurge 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 demiurge. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <curl/curl.h>
+#include <json-c/json.h>
+#include <string.h>
+#include "util.h"
+#include "asprintf.h"
+
+char *
+get_account_id(char *name)
+{
+ char instance[50];
+ char client_id[50];
+ char client_secret[50];
+ char access_token[50];
+
+ get_tokens_from_file(
+ ".demiurgerc", instance, client_id, client_secret, access_token);
+ CURL *curl = curl_easy_init();
+ if(curl == NULL) {
+ fprintf(stderr, "Error creating libcurl thing\n");
+ return NULL;
+ }
+ char *api_url_fmt = "%s/api/v1/accounts/%s/";
+ char *api_url;
+ dm_asprintf(&api_url, api_url_fmt, instance, name);
+ struct json_object *parsed_json;
+ struct json_object *account_id;
+
+ /* For some reason I don't understand, you can't get users remote
+ users withotu authorization. So I have to pass the
+ authorization header. */
+
+ char *header_fmt = "Authorization: Bearer %s";
+ char *authorization_header = NULL;
+ struct curl_slist *header_list = NULL;
+
+ dm_asprintf(&authorization_header, header_fmt, access_token);
+ header_list = curl_slist_append(header_list, authorization_header);
+
+ curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list);
+
+ /* Curl options */
+ curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list);
+ curl_easy_setopt(curl, CURLOPT_URL, api_url);
+ /* Create buffer for the result */
+
+ struct memory chunk = { 0 };
+
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, cb);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
+
+ /* free */
+
+ curl_easy_perform(curl);
+ curl_easy_cleanup(curl);
+ free(api_url);
+ free(authorization_header);
+ curl_slist_free_all(header_list);
+ /* parse the thing */
+
+ parsed_json = json_tokener_parse(chunk.response);
+ json_object_object_get_ex(parsed_json, "id", &account_id);
+
+ /* keep freeing */
+ char *str = (char *)json_object_get_string(account_id);
+ char *return_str = malloc(strlen(str + 1));
+ strcpy(return_str, str); // strdup() segfaults for some reason
+ json_object_put(parsed_json);
+ free(chunk.response);
+ return return_str;
+}
+
+int
+follow_account(char *id, char action)
+{
+ char instance[50];
+ char client_id[50];
+ char client_secret[50];
+ char access_token[50];
+ get_tokens_from_file(
+ ".demiurgerc", instance, client_id, client_secret, access_token);
+ CURL *curl = curl_easy_init();
+ if(curl == NULL) {
+ fprintf(stderr, "Error creating libcurl thing\n");
+ return -1;
+ }
+ char *api_url_fmt = "%s/api/v1/accounts/%s/follow";
+ if(action == 'f')
+ api_url_fmt = "%s/api/v1/accounts/%s/follow";
+ else if(action == 'u')
+ api_url_fmt = "%s/api/v1/accounts/%s/unfollow";
+
+ char *api_url;
+ dm_asprintf(&api_url, api_url_fmt, instance, id);
+
+ char *header_fmt = "Authorization: Bearer %s";
+ char *authorization_header = NULL;
+ struct curl_slist *header_list = NULL;
+
+ dm_asprintf(&authorization_header, header_fmt, access_token);
+ header_list = curl_slist_append(header_list, authorization_header);
+
+ curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list);
+ curl_easy_setopt(curl, CURLOPT_POST, 1L);
+ curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
+ curl_easy_setopt(curl, CURLOPT_URL, api_url);
+
+ struct memory chunk = { 0 };
+
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, cb);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
+
+ curl_easy_perform(curl);
+ curl_easy_cleanup(curl);
+ free(api_url);
+ free(authorization_header);
+ curl_slist_free_all(header_list);
+
+ struct json_object *parsed_json;
+ struct json_object *following;
+
+ parsed_json = json_tokener_parse(chunk.response);
+ json_object_object_get_ex(parsed_json, "following", &following);
+ printf("Following: %s\n", json_object_get_string(following));
+
+ json_object_put(parsed_json);
+ curl_slist_free_all(header_list);
+ free(chunk.response);
+
+ return 0;
+}
diff --git a/src/follow.h b/src/follow.h
new file mode 100644
index 0000000..de919f3
--- /dev/null
+++ b/src/follow.h
@@ -0,0 +1,5 @@
+char *
+get_account_id(char *name);
+
+int
+follow_account(char *id, char action);
diff --git a/src/login.c b/src/login.c
index 44d4866..e60b1f0 100644
--- a/src/login.c
+++ b/src/login.c
@@ -68,7 +68,7 @@ setup()
char *post_url = NULL;
- asprintf(&post_url, "%s%s", instance, api_url);
+ dm_asprintf(&post_url, "%s%s", instance, api_url);
curl_easy_setopt(curl, CURLOPT_URL, post_url);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, buf);
@@ -80,7 +80,7 @@ setup()
curl_easy_setopt(curl,
CURLOPT_POSTFIELDS,
"client_name=demiurge&redirect_uris=urn:ietf:wg:oauth:2."
- "0:oob&scope=read write");
+ "0:oob&scope=read write follow");
curl_easy_perform(curl);
curl_easy_cleanup(curl);
@@ -97,14 +97,14 @@ setup()
const char *client_secret = json_object_get_string(json_client_secret);
char *fmt = "%s%sresonse_type=code&client_id=%s&redirect_uri=urn:ietf:wg:"
- "oauth:2.0:oob&force_login&scope=read write";
+ "oauth:2.0:oob&force_login&scope=read write follow";
api_url = "/oauth/authorize?";
free(post_url);
post_url = NULL;
- asprintf(&post_url, fmt, instance, api_url, client_id);
+ dm_asprintf(&post_url, fmt, instance, api_url, client_id);
puts(post_url);
curl = curl_easy_init();
@@ -114,17 +114,17 @@ setup()
char *access_token_fmt =
"client_id=%s&client_secret=%s&redirect_uri=urn:ietf:wg:oauth:2.0:"
- "oob&grant_type=authorization_code&code=%s&scope=read write";
+ "oob&grant_type=authorization_code&code=%s&scope=read write follow";
api_url = "/oauth/token";
char *post_token_url = NULL;
- asprintf(
+ dm_asprintf(
&post_token_url, access_token_fmt, client_id, client_secret, code);
post_url = NULL;
- asprintf(&post_url, "%s%s", instance, api_url);
+ dm_asprintf(&post_url, "%s%s", instance, api_url);
curl_easy_setopt(curl, CURLOPT_URL, post_url);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_token_url);
diff --git a/src/main.c b/src/main.c
index ada947d..bfd3b6a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -21,11 +21,13 @@
#include <stdlib.h>
#include <getopt.h>
#include <libgen.h>
+#include <stdbool.h>
#include "login.h"
#include "util.h"
#include "post.h"
#include "upload_file.h"
+#include "follow.h"
/* prints usage */
@@ -47,7 +49,7 @@ main(int argc, char **argv)
char *status = NULL;
char *visibility = NULL;
char *id_ptr = NULL;
-
+ char *account_id = NULL;
/* TODO: Support filename and visibility */
if(!isatty(0)) {
@@ -62,17 +64,27 @@ main(int argc, char **argv)
return -1;
}
- while((c = getopt(argc, argv, "s:v:F:")) != -1) {
+ while((c = getopt(argc, argv, "s:v:F:f:u:")) != -1) {
switch(c) {
- case 's':
- status = optarg;
- break;
- case 'v':
- visibility = optarg;
- break;
- case 'F':
- upload_file(optarg, basename(optarg), &id_ptr);
- break;
+ case 's':
+ status = optarg;
+ break;
+ case 'v':
+ visibility = optarg;
+ break;
+ case 'F':
+ upload_file(optarg, basename(optarg), &id_ptr);
+ break;
+ case 'f':
+ account_id = get_account_id(optarg);
+ follow_account(account_id,'f');
+ free(account_id);
+ return 0;
+ case 'u':
+ account_id = get_account_id(optarg);
+ follow_account(account_id,'u');
+ free(account_id);
+ return 0;
}
}
diff --git a/src/post.c b/src/post.c
index 9e9273d..7994493 100644
--- a/src/post.c
+++ b/src/post.c
@@ -45,12 +45,12 @@ post_status(const char *status, const char *scope, const char *media_id)
char *api_url = "/api/v1/statuses";
char *url = NULL;
- asprintf(&url, "%s%s", instance, api_url);
+ dm_asprintf(&url, "%s%s", instance, api_url);
char *header_fmt = "Authorization: Bearer %s";
char *authorization_header = NULL;
struct curl_slist *header_list = NULL;
- asprintf(&authorization_header, header_fmt, access_token);
+ dm_asprintf(&authorization_header, header_fmt, access_token);
header_list = curl_slist_append(header_list, authorization_header);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list);
diff --git a/src/upload_file.c b/src/upload_file.c
index 88de19f..c223efa 100644
--- a/src/upload_file.c
+++ b/src/upload_file.c
@@ -45,7 +45,7 @@ upload_file(const char *path, const char *description, char **id_ptr)
curl_easy_setopt(curl, CURLOPT_WRITEDATA, buf);
char *url_to_post = NULL;
- asprintf(&url_to_post, "%s/api/v1/media", instance);
+ dm_asprintf(&url_to_post, "%s/api/v1/media", instance);
/* Don't repeat yourself, so they say, it's the root of all evil
* today */
@@ -53,7 +53,7 @@ upload_file(const char *path, const char *description, char **id_ptr)
char *header_fmt = "Authorization: Bearer %s";
struct curl_slist *header_list = NULL;
char *authorization_header = NULL;
- asprintf(&authorization_header, header_fmt, access_token);
+ dm_asprintf(&authorization_header, header_fmt, access_token);
header_list = curl_slist_append(header_list, authorization_header);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list);