📄 pst-transfer-session.c
字号:
/* * Copyright (c) 2004 Jean-Yves Lefort * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Jean-Yves Lefort nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */#include "config.h"#include <string.h>#include <glib/gi18n.h>#include <Python.h>#include "streamtuner.h"#include "pst-helpers.h"#include "pst-transfer-session.h"typedef struct{ PyThreadState **thread_state; PyObject *cb; PyObject *args;} CallbackInfo;typedef struct{ PyObject_HEAD STTransferSession *session;} PSTTransferSession;/*** methods *****************************************************************/static PyObject *pst_transfer_session_get (PSTTransferSession *self, PyObject *args, PyObject *keywords);static PyObject *pst_transfer_session_get_binary (PSTTransferSession *self, PyObject *args, PyObject *keywords);static PyObject *pst_transfer_session_get_by_line (PSTTransferSession *self, PyObject *args, PyObject *keywords);static PyMethodDef methods[] = { { "get", (PyCFunction) pst_transfer_session_get, METH_VARARGS | METH_KEYWORDS }, { "get_binary", (PyCFunction) pst_transfer_session_get_binary, METH_VARARGS | METH_KEYWORDS }, { "get_by_line", (PyCFunction) pst_transfer_session_get_by_line, METH_VARARGS | METH_KEYWORDS }, { NULL }};/*** type object *************************************************************/static PyObject *pst_transfer_session_new (PyTypeObject *type, PyObject *args, PyObject *keywords);static void pst_transfer_session_dealloc (PSTTransferSession *self);static PyTypeObject PSTTransferSession_Type = { PyObject_HEAD_INIT(NULL) 0, /* ob_size */ "ST.TransferSession", /* tp_name */ sizeof(PSTTransferSession), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor) pst_transfer_session_dealloc, /* tp_dealloc */ NULL, /* tp_print */ NULL, /* tp_getattr */ NULL, /* tp_setattr */ NULL, /* tp_compare */ NULL, /* tp_repr */ NULL, /* tp_as_number */ NULL, /* tp_as_sequence */ NULL, /* tp_as_mapping */ NULL, /* tp_hash */ NULL, /* tp_call */ NULL, /* tp_str */ NULL, /* tp_getattro */ NULL, /* tp_setattro */ NULL, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ NULL, /* tp_doc */ NULL, /* tp_traverse */ NULL, /* tp_clear */ NULL, /* tp_richcompare */ 0, /* tp_weaklistoffset */ NULL, /* tp_iter */ NULL, /* tp_iternext */ methods, /* tp_methods */ NULL, /* tp_members */ NULL, /* tp_getset */ NULL, /* tp_base */ NULL, /* tp_dict */ NULL, /* tp_descr_get */ NULL, /* tp_descr_set */ 0, /* tp_dictoffset */ NULL, /* tp_init */ NULL, /* tp_alloc */ pst_transfer_session_new /* tp_new */};PyObject *PSTExc_AbortError = NULL;/*** function declarations ***************************************************/static void pst_transfer_session_get_by_line_cb (const char *line, gpointer data);/*** type methods ************************************************************/static PyObject *pst_transfer_session_new (PyTypeObject *type, PyObject *args, PyObject *keywords){ static char *keyword_list[] = { NULL }; PSTTransferSession *self; if (! PyArg_ParseTupleAndKeywords(args, keywords, "", keyword_list)) return NULL; self = (PSTTransferSession *) type->tp_alloc(type, 0); if (! self) return NULL; self->session = st_transfer_session_new(); return (PyObject *) self;}static voidpst_transfer_session_dealloc (PSTTransferSession *self){ st_transfer_session_free(self->session); self->ob_type->tp_free((PyObject *) self);}/*** object methods **********************************************************/static PyObject *pst_transfer_session_get (PSTTransferSession *self, PyObject *args, PyObject *keywords){ static char *keyword_list[] = { "url", "flags", "fetch_headers", "fetch_body", NULL }; const char *url; unsigned int flags = 0; gboolean fetch_headers = FALSE; gboolean fetch_body = TRUE; gboolean status; char *headers = NULL; char *body = NULL; GError *err = NULL; PyObject *result; if (! PyArg_ParseTupleAndKeywords(args, keywords, "s|iii", keyword_list, &url, &flags, &fetch_headers, &fetch_body)) return NULL; Py_BEGIN_ALLOW_THREADS status = st_transfer_session_get(self->session, url, flags, fetch_headers ? &headers : NULL, fetch_body ? &body : NULL, &err); Py_END_ALLOW_THREADS if (! status) { if (err) { PyErr_SetString(PyExc_RuntimeError, err->message); g_error_free(err); } else PyErr_SetString(PSTExc_AbortError, _("aborted by the user")); return NULL; } if (fetch_headers && fetch_body) result = Py_BuildValue("(ss)", headers, body); else if (fetch_headers) result = PyString_FromString(headers); else if (fetch_body) result = PyString_FromString(body); else result = pst_none(); g_free(headers); g_free(body); return result;}static PyObject *pst_transfer_session_get_binary (PSTTransferSession *self, PyObject *args, PyObject *keywords){ static char *keyword_list[] = { "url", "flags", "fetch_headers", "fetch_body", NULL }; const char *url; unsigned int flags = 0; gboolean fetch_headers = FALSE; gboolean fetch_body = TRUE; gboolean status; char *headers = NULL; guint8 *body = NULL; unsigned int body_len = 0; GError *err = NULL; PyObject *buffer; int pstatus; PyObject *result = NULL; if (! PyArg_ParseTupleAndKeywords(args, keywords, "s|iii", keyword_list, &url, &flags, &fetch_headers, &fetch_body)) return NULL; Py_BEGIN_ALLOW_THREADS status = st_transfer_session_get_binary(self->session, url, flags, fetch_headers ? &headers : NULL, fetch_body ? &body : NULL, fetch_body ? &body_len : NULL, &err); Py_END_ALLOW_THREADS if (! status) { if (err) { PyErr_SetString(PyExc_RuntimeError, err->message); g_error_free(err); } else PyErr_SetString(PSTExc_AbortError, _("aborted by the user")); return NULL; } if (fetch_body) { gpointer ptr; int len; buffer = PyBuffer_New(body_len); if (! buffer) goto end; pstatus = PyObject_AsWriteBuffer(buffer, &ptr, &len); g_return_val_if_fail(pstatus == 0, NULL); g_return_val_if_fail(len == body_len, NULL); memcpy(ptr, body, len); } if (fetch_headers && fetch_body) result = Py_BuildValue("(sN)", headers, buffer); else if (fetch_headers) result = PyString_FromString(headers); else if (fetch_body) result = buffer; else result = pst_none(); end: g_free(headers); g_free(body); return result;}static PyObject *pst_transfer_session_get_by_line (PSTTransferSession *self, PyObject *args, PyObject *keywords){ static char *keyword_list[] = { "url", "flags", "header_cb", "header_args", "body_cb", "body_args", NULL }; const char *url; unsigned int flags = 0; PyThreadState *thread_state; CallbackInfo header_info = { &thread_state, NULL, NULL }; CallbackInfo body_info = { &thread_state, NULL, NULL }; GError *err = NULL; gboolean status; if (! PyArg_ParseTupleAndKeywords(args, keywords, "s|iOO!OO!", keyword_list, &url, &flags, &header_info.cb, &PyTuple_Type, &header_info.args, &body_info.cb, &PyTuple_Type, &body_info.args)) return NULL; thread_state = PyEval_SaveThread(); status = st_transfer_session_get_by_line(self->session, url, flags, header_info.cb ? pst_transfer_session_get_by_line_cb : NULL, header_info.cb ? &header_info : NULL, body_info.cb ? pst_transfer_session_get_by_line_cb : NULL, body_info.cb ? &body_info: NULL, &err); PyEval_RestoreThread(thread_state); if (! status) { if (err) { PyErr_SetString(PyExc_RuntimeError, err->message); g_error_free(err); } else PyErr_SetString(PSTExc_AbortError, _("aborted by the user")); return NULL; } return pst_none();}/*** streamtuner callbacks ***************************************************/static voidpst_transfer_session_get_by_line_cb (const char *line, gpointer data){ CallbackInfo *info = data; PyObject *pline; PyObject *pargs; PyObject *presult; PyEval_RestoreThread(*info->thread_state); pline = Py_BuildValue("(s)", line); if (! pline) { PyErr_Print(); goto end; } if (info->args) { pargs = PySequence_Concat(pline, info->args); Py_DECREF(pline); if (! pargs) { PyErr_Print(); goto end; } } else pargs = pline; presult = PyObject_CallObject(info->cb, pargs); Py_DECREF(pargs); if (presult) Py_DECREF(presult); else PyErr_Print(); end: *info->thread_state = PyEval_SaveThread();}/*** C API *******************************************************************/gbooleanpst_transfer_session_register (PyObject *module){ PyTypeObject *ptr = &PSTTransferSession_Type; g_return_val_if_fail(module != NULL, FALSE); if (PyType_Ready(&PSTTransferSession_Type) < 0) return FALSE; Py_INCREF(&PSTTransferSession_Type); PyModule_AddObject(module, "TransferSession", (PyObject *) ptr); PyModule_AddIntConstant(module, "TRANSFER_PASS_NEWLINE", ST_TRANSFER_PASS_NEWLINE); PyModule_AddIntConstant(module, "TRANSFER_UTF8", ST_TRANSFER_UTF8); PyModule_AddIntConstant(module, "TRANSFER_PARSE_HTTP_CHARSET", ST_TRANSFER_PARSE_HTTP_CHARSET); PyModule_AddIntConstant(module, "TRANSFER_PARSE_HTML_CHARSET", ST_TRANSFER_PARSE_HTML_CHARSET); if (! PSTExc_AbortError) PSTExc_AbortError = PyErr_NewException("ST.AbortError", NULL, NULL); PyModule_AddObject(module, "AbortError", PSTExc_AbortError); return TRUE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -