summaryrefslogtreecommitdiff
path: root/src/shoki/cpy
diff options
context:
space:
mode:
Diffstat (limited to 'src/shoki/cpy')
-rw-r--r--src/shoki/cpy/lib.pxd13
-rw-r--r--src/shoki/cpy/post.pxd58
-rw-r--r--src/shoki/cpy/result.pxd8
-rw-r--r--src/shoki/cpy/setup.py6
-rw-r--r--src/shoki/cpy/shoki.pyx132
-rw-r--r--src/shoki/cpy/str.pxd11
-rw-r--r--src/shoki/cpy/types.pxd11
7 files changed, 239 insertions, 0 deletions
diff --git a/src/shoki/cpy/lib.pxd b/src/shoki/cpy/lib.pxd
new file mode 100644
index 0000000..5749141
--- /dev/null
+++ b/src/shoki/cpy/lib.pxd
@@ -0,0 +1,13 @@
+include "types.pxd"
+
+cdef extern from "<al/lib.h>":
+ void al_free(void *ptr)
+ void al_malloc(size_t size)
+ void al_strlen(char *s)
+ void al_bzero(void *s, size_t n)
+
+cdef extern from "<al/log.h>":
+ s32 al_log_info(const char *ns, const char *, ...)
+ s32 al_log_warn(const char *ns, const char *, ...)
+ s32 al_log_error(const char *ns, const char *, ...)
+ s32 al_log_debug(const char *ns, const char *, ...)
diff --git a/src/shoki/cpy/post.pxd b/src/shoki/cpy/post.pxd
new file mode 100644
index 0000000..0b0a97e
--- /dev/null
+++ b/src/shoki/cpy/post.pxd
@@ -0,0 +1,58 @@
+include "str.pxd"
+
+cdef extern from "../../shoki/src/post.h":
+ ctypedef struct sho_optional_int:
+ s64 i
+ bool set
+
+ cdef struct sho_post_date:
+ u8 type
+ s64 timestamp
+
+ cdef struct sho_post_media:
+ u8 type
+ str url
+ str thumbnail_url
+
+ ctypedef struct sho_dates_array:
+ u32 size
+ u32 alloc
+ sho_post_date *data
+
+ ctypedef struct sho_media_array:
+ u32 size
+ u32 alloc
+ sho_post_media *data
+
+ cdef struct sho_post_user:
+ str unique_id
+ str username
+ str display_name
+ str profile_image_url
+
+ cdef struct sho_post_ref:
+ str unique_id
+
+ cdef struct sho_post:
+ u16 version
+ u8 type
+ str unique_id
+ str raw_responses
+ str url
+ sho_dates_array dates
+ sho_post_user author
+ str title
+ str text
+ sho_optional_int likes
+ sho_optional_int reposts
+ sho_optional_int quotes
+ sho_optional_int comments
+ sho_optional_int views
+ sho_media_array media
+ sho_post_ref post
+ sho_post_ref quoted
+ sho_post_ref in_reply_to
+
+ void sho_post_reset(sho_post *post)
+ void sho_post_add_media(sho_post *post, u8 type, str *url, str *thumbnail_url)
+ void sho_post_add_date(sho_post *post, u8 type, s64 timestamp)
diff --git a/src/shoki/cpy/result.pxd b/src/shoki/cpy/result.pxd
new file mode 100644
index 0000000..1bebb55
--- /dev/null
+++ b/src/shoki/cpy/result.pxd
@@ -0,0 +1,8 @@
+include "post.pxd"
+
+cdef extern from "../../shoki/src/search.h":
+ cdef struct sho_result:
+ pass
+
+ void sho_result_add_post(sho_result *res, s32 page, sho_post *post)
+ void sho_result_add_to_list(sho_result *res, s32 page, str *unique_id)
diff --git a/src/shoki/cpy/setup.py b/src/shoki/cpy/setup.py
new file mode 100644
index 0000000..1b491f1
--- /dev/null
+++ b/src/shoki/cpy/setup.py
@@ -0,0 +1,6 @@
+from Cython.Build import cythonize
+from Cython.Compiler import Options
+from setuptools import Extension
+Options.embed = True
+alabaster_inc = "../../../subprojects/libalabaster/include"
+cythonize([Extension("shoki", ["shoki.pyx"], include_dirs=[alabaster_inc], extra_link_args=[])], language_level=3)
diff --git a/src/shoki/cpy/shoki.pyx b/src/shoki/cpy/shoki.pyx
new file mode 100644
index 0000000..6d1dd56
--- /dev/null
+++ b/src/shoki/cpy/shoki.pyx
@@ -0,0 +1,132 @@
+cimport lib
+cimport str
+cimport post
+cimport result
+
+import sys
+sys.path.append('./py')
+
+cdef public int log_info(char *msg) except -1:
+ return lib.al_log_info("shoki", "%s", msg)
+
+cdef public int log_warn(char *msg) except -1:
+ return lib.al_log_warn("shoki", "%s", msg)
+
+cdef public int log_error(char *msg) except -1:
+ return lib.al_log_error("shoki", "%s", msg)
+
+cdef public int log_debug(char *msg) except -1:
+ return lib.al_log_debug("shoki", "%s", msg)
+
+def encode_str(str):
+ return str.encode('UTF-8')
+
+def decode_str(str):
+ return str.decode('UTF-8')
+
+class OutputHook(object):
+ def __init__(self):
+ self.fd = sys.__stdout__
+
+ def __getattr__(self, attr):
+ return getattr(self.fd, attr)
+
+ def write(self, msg):
+ if len(msg) > 0 and msg != '\n':
+ log_debug(encode_str(msg))
+
+hook = OutputHook()
+sys.stdout = hook
+sys.stderr = hook
+
+class ShokiLogger():
+ def debug(self, msg):
+ log_debug(encode_str(msg))
+
+ def info(self, msg):
+ log_info(encode_str(msg))
+
+ def warning(self, msg):
+ log_warn(encode_str(msg))
+
+ def error(self, msg):
+ log_error(encode_str(msg))
+
+import log
+log.set_logger(ShokiLogger())
+
+def exception_handler(exception_type, exception, traceback):
+ log.error(repr(exception))
+sys.excepthook = exception_handler
+
+import client
+from post import PostType, DateType
+
+shoki = client.ShokiClient()
+for name, p in client.ALL_PROVIDERS.items():
+ if p[0].init():
+ shoki.register_provider(name, p)
+
+cdef public int sho_client_search(str.str *provider, str.str *query) except -1:
+ cdef char *c_str0 = str.al_str_to_c_str(provider)
+ cdef char *c_str1 = str.al_str_to_c_str(query)
+ ret = shoki.search(decode_str(c_str0), decode_str(c_str1))
+ lib.al_free(c_str0)
+ lib.al_free(c_str1)
+ return ret
+
+cdef public int py_str_to_str(str.str *s, char *py_c_str) except -1:
+ str.al_str_from(s, py_c_str)
+ return 0
+
+cdef public int sho_client_get_page(result.sho_result *res, int search_id, int num) except -1:
+ cdef post.sho_post cpost
+ cdef str.str url
+ cdef str.str thumbnail_url
+ cdef str.str unique_id
+ page = shoki.get_page(search_id, num)
+ if not page: return -1
+ for py_post in page['posts']:
+ post.sho_post_reset(&cpost)
+ cpost.version = py_post.version
+ cpost.type = py_post.type.value
+ py_str_to_str(&cpost.unique_id, encode_str(py_post.unique_id))
+ py_str_to_str(&cpost.url, encode_str(py_post.url))
+ for date in py_post.dates:
+ post.sho_post_add_date(&cpost, date.value, py_post.dates[date])
+ py_str_to_str(&cpost.author.unique_id, encode_str(py_post.author.unique_id))
+ py_str_to_str(&cpost.author.username, encode_str(py_post.author.username))
+ py_str_to_str(&cpost.author.display_name, encode_str(py_post.author.display_name))
+ py_str_to_str(&cpost.author.profile_image_url, encode_str(py_post.author.profile_image_url))
+ if cpost.type == PostType.REPOST.value:
+ py_str_to_str(&cpost.post.unique_id, encode_str(py_post.post.unique_id))
+ result.sho_result_add_post(res, num, &cpost)
+ continue
+ py_str_to_str(&cpost.title, encode_str(py_post.title))
+ py_str_to_str(&cpost.text, encode_str(py_post.text))
+ cpost.likes.set = py_post.likes != None
+ if cpost.likes.set:
+ cpost.likes.i = py_post.likes
+ cpost.reposts.set = py_post.reposts != None
+ if cpost.reposts.set:
+ cpost.reposts.i = py_post.reposts
+ cpost.quotes.set = py_post.quotes != None
+ if cpost.quotes.set:
+ cpost.quotes.i = py_post.quotes
+ cpost.comments.set = py_post.comments != None
+ if cpost.comments.set:
+ cpost.comments.i = py_post.comments
+ cpost.views.set = py_post.views != None
+ if cpost.views.set:
+ cpost.views.i = py_post.views
+ for media in py_post.media:
+ py_str_to_str(&url, encode_str(media.url))
+ py_str_to_str(&thumbnail_url, encode_str(media.thumbnail_url))
+ post.sho_post_add_media(&cpost, 0, &url, &thumbnail_url)
+ py_str_to_str(&cpost.quoted.unique_id, encode_str(py_post.quoted.unique_id))
+ py_str_to_str(&cpost.in_reply_to.unique_id, encode_str(py_post.in_reply_to.unique_id))
+ result.sho_result_add_post(res, num, &cpost)
+ for py_unique_id in page['list']:
+ py_str_to_str(&unique_id, encode_str(py_unique_id))
+ result.sho_result_add_to_list(res, num, &unique_id)
+ return 0
diff --git a/src/shoki/cpy/str.pxd b/src/shoki/cpy/str.pxd
new file mode 100644
index 0000000..a12ced4
--- /dev/null
+++ b/src/shoki/cpy/str.pxd
@@ -0,0 +1,11 @@
+include "types.pxd"
+
+cdef extern from "<al/str.h>":
+ ctypedef struct str:
+ u32 len
+ s32 alloc
+ char *data
+
+ void al_str_from(str *s, const char *str)
+ char *al_str_to_c_str(str *s)
+
diff --git a/src/shoki/cpy/types.pxd b/src/shoki/cpy/types.pxd
new file mode 100644
index 0000000..fec35a5
--- /dev/null
+++ b/src/shoki/cpy/types.pxd
@@ -0,0 +1,11 @@
+ctypedef unsigned char u8;
+ctypedef char s8;
+ctypedef unsigned short u16;
+ctypedef short s16;
+ctypedef unsigned int u32;
+ctypedef int s32;
+ctypedef unsigned long u64;
+ctypedef long s64;
+ctypedef float f32;
+ctypedef double f64;
+ctypedef bint bool