Files

666 lines
25 KiB
C
Raw Permalink Normal View History

2018-01-03 14:18:06 +01:00
/*
* This file is part of the MicroPython ESP32 project, https://github.com/loboris/MicroPython_ESP32_psRAM_LoBo
2018-01-03 14:18:06 +01:00
*
* The MIT License (MIT)
*
* Copyright (c) 2018 LoBo (https://github.com/loboris)
2018-01-03 14:18:06 +01:00
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "sdkconfig.h"
#ifdef CONFIG_MICROPY_USE_CURL
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "rom/ets_sys.h"
#include "esp_system.h"
#include "py/obj.h"
#include "py/runtime.h"
2018-12-04 14:06:15 +08:00
#include "modmachine.h"
#include "modnetwork.h"
2018-01-03 14:18:06 +01:00
#include "libs/espcurl.h"
2018-12-04 14:06:15 +08:00
#include "libs/curl_mail.h"
2018-01-03 14:18:06 +01:00
#include "extmod/vfs_native.h"
2018-02-07 17:51:08 +01:00
2018-01-03 14:18:06 +01:00
//----------------------------------
static int check_file(char *fname) {
struct stat sb;
if ((stat(fname, &sb) == 0) && (sb.st_size > 0)) {
return 1;
}
return 0;
}
// Print some info about curl environment
//--------------------------------------------------
static void print_curl_info(const mp_print_t *print)
{
curl_version_info_data *data = curl_version_info(CURLVERSION_NOW);
mp_printf(print, "Curl Info (\n");
mp_printf(print, " Curl version info\n");
mp_printf(print, " version: %s - %d\n", data->version, data->version_num);
mp_printf(print, " Host: %s\n", data->host);
if (data->features & CURL_VERSION_IPV6) {
mp_printf(print, " - IP V6 supported\n");
} else {
mp_printf(print, " - IP V6 NOT supported\n");
}
if (data->features & CURL_VERSION_SSL) {
mp_printf(print, " - SSL supported\n");
} else {
mp_printf(print, " - SSL NOT supported\n");
}
if (data->features & CURL_VERSION_LIBZ) {
mp_printf(print, " - LIBZ supported\n");
} else {
mp_printf(print, " - LIBZ NOT supported\n");
}
if (data->features & CURL_VERSION_DEBUG) {
mp_printf(print, " - DEBUG supported\n");
} else {
mp_printf(print, " - DEBUG NOT supported\n");
}
mp_printf(print, " Protocols:\n");
int i=0;
while(data->protocols[i] != NULL) {
mp_printf(print, " - %s\n", data->protocols[i]);
i++;
}
mp_printf(print, ")\n");
}
//-----------------------------
STATIC mp_obj_t curl_info(void)
{
print_curl_info(&mp_plat_print);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(curl_info_obj, curl_info);
//--------------------------------------------------------------------------------------
STATIC mp_obj_t curl_Options(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args)
{
enum { ARG_print, ARG_verbose, ARG_progress, ARG_timeout, ARG_maxfsize, ARG_hdrlen, ARG_bodylen, ARG_nodecode };
const mp_arg_t allowed_args[] = {
{ MP_QSTR_print, MP_ARG_BOOL, { .u_bool = true } },
{ MP_QSTR_verbose, MP_ARG_KW_ONLY | MP_ARG_INT, { .u_int = -1 } },
{ MP_QSTR_progress, MP_ARG_KW_ONLY | MP_ARG_INT, { .u_int = -1 } },
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, { .u_int = -1 } },
{ MP_QSTR_maxfsize, MP_ARG_KW_ONLY | MP_ARG_INT, { .u_int = -1 } },
{ MP_QSTR_hdrlen, MP_ARG_KW_ONLY | MP_ARG_INT, { .u_int = -1 } },
{ MP_QSTR_bodylen, MP_ARG_KW_ONLY | MP_ARG_INT, { .u_int = -1 } },
{ MP_QSTR_nodecode, MP_ARG_KW_ONLY | MP_ARG_INT, { .u_int = -1 } },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
if (args[ARG_verbose].u_int >= 0) curl_verbose = args[ARG_verbose].u_int & 1;
if (args[ARG_progress].u_int >= 0) curl_progress = args[ARG_progress].u_int;
if (args[ARG_timeout].u_int >= 10) curl_timeout = args[ARG_timeout].u_int;
if (args[ARG_maxfsize].u_int > 1000) curl_maxbytes = args[ARG_maxfsize].u_int;
2018-01-21 16:14:38 +01:00
if (args[ARG_hdrlen].u_int > MIN_HDR_BUF_LEN) hdr_maxlen = args[ARG_hdrlen].u_int;
if (args[ARG_bodylen].u_int > MIN_BODY_BUF_LEN) body_maxlen = args[ARG_bodylen].u_int;
2018-01-03 14:18:06 +01:00
if (args[ARG_nodecode].u_int >= 0) curl_nodecode = args[ARG_nodecode].u_int & 1;
if (args[ARG_print].u_bool) {
mp_printf(&mp_plat_print, "Curl options(\n Verbose: %s, Progress: %d, Timeout: %d, Max fsize: %d, Header len: %d, Body len: %d, Decode content: %s\n)\n",
((curl_verbose) ? "True" : "False"), curl_progress, curl_timeout, curl_maxbytes, hdr_maxlen, body_maxlen, ((curl_nodecode) ? "False" : "True"));
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(curl_Options_obj, 0, curl_Options);
//----------------------------------------------------------------------------------
STATIC mp_obj_t curl_GET(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args)
{
2018-12-04 14:06:15 +08:00
network_checkConnection();
2018-01-03 14:18:06 +01:00
enum { ARG_url, ARG_file };
const mp_arg_t allowed_args[] = {
{ MP_QSTR_url, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_obj = mp_const_none } },
{ MP_QSTR_file, MP_ARG_OBJ, { .u_obj = mp_const_none } },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
int res;
int hdr_len = hdr_maxlen;
int body_len = body_maxlen;
vstr_t header;
vstr_t body;
char *url = NULL;
char *fname = NULL;
char fullname[128] = {'\0'};
url = (char *)mp_obj_str_get_str(args[ARG_url].u_obj);
if (MP_OBJ_IS_STR(args[ARG_file].u_obj)) {
// GET to file
fname = (char *)mp_obj_str_get_str(args[ARG_file].u_obj);
if (strcmp(fname, "simulate") != 0) {
res = physicalPath(fname, fullname);
if ((res != 0) || (strlen(fullname) == 0)) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "Error resolving file name"));
}
fname = fullname;
}
2018-01-21 16:14:38 +01:00
body_len = MIN_BODY_BUF_LEN;
2018-01-03 14:18:06 +01:00
}
vstr_init_len(&header, hdr_len);
vstr_init_len(&body, body_len);
header.buf[0] = '\0';
body.buf[0] = '\0';
MP_THREAD_GIL_EXIT();
res = Curl_GET(url, fname, header.buf, body.buf, header.len, body.len);
MP_THREAD_GIL_ENTER();
mp_obj_t tuple[3];
tuple[0] = mp_obj_new_int(res);
header.len = strlen(header.buf);
body.len = strlen(body.buf);
tuple[1] = mp_obj_new_str_from_vstr(&mp_type_str, &header);
tuple[2] = mp_obj_new_str_from_vstr(&mp_type_str, &body);
return mp_obj_new_tuple(3, tuple);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(curl_GET_obj, 1, curl_GET);
2018-12-04 14:06:15 +08:00
//---------------------------------------------------------------------------------------
STATIC mp_obj_t curl_GET_MAIL(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args)
{
network_checkConnection();
enum { ARG_opts, ARG_user, ARG_pass, ARG_server, ARG_port, ARG_file, ARG_req };
const mp_arg_t allowed_args[] = {
{ MP_QSTR_opts, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_obj = mp_const_none } },
{ MP_QSTR_user, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_obj = mp_const_none } },
{ MP_QSTR_password, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_obj = mp_const_none } },
{ MP_QSTR_server, MP_ARG_KW_ONLY | MP_ARG_OBJ, { .u_obj = mp_const_none } },
{ MP_QSTR_port, MP_ARG_KW_ONLY | MP_ARG_INT, { .u_int = GMAIL_IMAP_PORT } },
{ MP_QSTR_file, MP_ARG_KW_ONLY | MP_ARG_OBJ, { .u_obj = mp_const_none } },
{ MP_QSTR_req, MP_ARG_KW_ONLY | MP_ARG_OBJ, { .u_obj = mp_const_none } },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
char *cust_req = NULL;
char *opts = (char *)mp_obj_str_get_str(args[ARG_opts].u_obj);
char *user = (char *)mp_obj_str_get_str(args[ARG_user].u_obj);
char *pass = (char *)mp_obj_str_get_str(args[ARG_pass].u_obj);
char mail_server[128] = {'\0'};
int res;
int hdr_len = hdr_maxlen;
int body_len = body_maxlen;
vstr_t header;
vstr_t body;
char *fname = NULL;
char fullname[128] = {'\0'};
uint32_t mail_port = args[ARG_port].u_int;
if (MP_OBJ_IS_STR(args[ARG_req].u_obj)) {
(char *)mp_obj_str_get_str(args[ARG_req].u_obj);
}
if (MP_OBJ_IS_STR(args[ARG_server].u_obj)) sprintf(mail_server, "%s", (char *)mp_obj_str_get_str(args[ARG_server].u_obj));
else sprintf(mail_server, GMAIL_IMAP);
if (MP_OBJ_IS_STR(args[ARG_file].u_obj)) {
// GET to file
fname = (char *)mp_obj_str_get_str(args[ARG_file].u_obj);
if (strcmp(fname, "simulate") != 0) {
res = physicalPath(fname, fullname);
if ((res != 0) || (strlen(fullname) == 0)) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "Error resolving file name"));
}
fname = fullname;
}
body_len = MIN_BODY_BUF_LEN;
}
vstr_init_len(&header, hdr_len);
vstr_init_len(&body, body_len);
header.buf[0] = '\0';
body.buf[0] = '\0';
MP_THREAD_GIL_EXIT();
res = Curl_IMAP_GET(opts, fname, header.buf, body.buf, header.len, body.len, mail_server, mail_port, user, pass, cust_req);
MP_THREAD_GIL_ENTER();
mp_obj_t tuple[3];
tuple[0] = mp_obj_new_int(res);
header.len = strlen(header.buf);
body.len = strlen(body.buf);
tuple[1] = mp_obj_new_str_from_vstr(&mp_type_str, &header);
tuple[2] = mp_obj_new_str_from_vstr(&mp_type_str, &body);
return mp_obj_new_tuple(3, tuple);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(curl_GET_MAIL_obj, 1, curl_GET_MAIL);
2018-01-03 14:18:06 +01:00
//-----------------------------------------------------------------------------------
STATIC mp_obj_t curl_POST(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args)
{
2018-12-04 14:06:15 +08:00
network_checkConnection();
2018-01-03 14:18:06 +01:00
enum { ARG_url, ARG_params };
const mp_arg_t allowed_args[] = {
{ MP_QSTR_url, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_obj = mp_const_none } },
{ MP_QSTR_params, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_obj = mp_const_none } },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
int res;
int hdr_len = hdr_maxlen;
int body_len = body_maxlen;
vstr_t header;
vstr_t body;
char *url = NULL;
char fullname[128] = {'\0'};
url = (char *)mp_obj_str_get_str(args[ARG_url].u_obj);
if (formpost) curl_formfree(formpost);
formpost=NULL;
lastptr=NULL;
2018-12-04 14:06:15 +08:00
int nparam = 0;
2018-01-03 14:18:06 +01:00
// get POST parameters
if (MP_OBJ_IS_TYPE(args[ARG_params].u_obj, &mp_type_dict)) {
2018-12-04 14:06:15 +08:00
const char *key;
const char *value;
mp_obj_dict_t *dict = MP_OBJ_TO_PTR(args[ARG_params].u_obj);
size_t max = dict->map.alloc;
mp_map_t *map = &dict->map;
mp_map_elem_t *next;
size_t cur = 0;
while (1) {
next = NULL;
for (size_t i = cur; i < max; i++) {
if (MP_MAP_SLOT_IS_FILLED(map, i)) {
cur = i + 1;
next = &(map->table[i]);
break;
}
}
if (next == NULL) break;
key = mp_obj_str_get_str(next->key);
if (MP_OBJ_IS_STR(next->value)) {
value = mp_obj_str_get_str(next->value);
uint8_t fadded = 0;
if (strlen(value) < 128) {
res = physicalPath(value, fullname);
if ((res == 0) && (strlen(fullname) > 0)) {
if (check_file(fullname)) {
curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, key, CURLFORM_FILE, fullname, CURLFORM_END);
nparam++;
fadded = 1;
}
}
}
if (fadded == 0) {
curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, key, CURLFORM_COPYCONTENTS, value, CURLFORM_END);
nparam++;
}
}
else if (MP_OBJ_IS_INT(next->value)) {
int ival = mp_obj_get_int(next->value);
char sval[64];
sprintf(sval,"%d", ival);
curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, key, CURLFORM_COPYCONTENTS, sval, CURLFORM_END);
nparam++;
}
else if (MP_OBJ_IS_TYPE(next->value, &mp_type_float)) {
double fval = mp_obj_get_float(next->value);
char sval[64];
sprintf(sval,"%f", fval);
curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, key, CURLFORM_COPYCONTENTS, sval, CURLFORM_END);
nparam++;
}
2018-01-03 14:18:06 +01:00
}
if (nparam == 0) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "Expected at least one POST parameter"));
}
}
else {
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "Expected Dict type argument"));
}
vstr_init_len(&header, hdr_len);
vstr_init_len(&body, body_len);
header.buf[0] = '\0';
body.buf[0] = '\0';
MP_THREAD_GIL_EXIT();
res = Curl_POST(url, header.buf, body.buf, header.len, body.len);
MP_THREAD_GIL_ENTER();
mp_obj_t tuple[3];
header.len = strlen(header.buf);
body.len = strlen(body.buf);
tuple[0] = mp_obj_new_int(res);
tuple[1] = mp_obj_new_str_from_vstr(&mp_type_str, &header);
tuple[2] = mp_obj_new_str_from_vstr(&mp_type_str, &body);
return mp_obj_new_tuple(3, tuple);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(curl_POST_obj, 1, curl_POST);
//---------------------------------------------------------------------------------------
STATIC mp_obj_t curl_sendmail(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args)
{
2018-12-04 14:06:15 +08:00
network_checkConnection();
enum { ARG_user, ARG_pass, ARG_to, ARG_subject, ARG_msg, ARG_cc, ARG_bcc, ARG_attach, ARG_server, ARG_port, ARG_prot };
2018-01-03 14:18:06 +01:00
const mp_arg_t allowed_args[] = {
{ MP_QSTR_user, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_obj = mp_const_none } },
{ MP_QSTR_password, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_obj = mp_const_none } },
{ MP_QSTR_to, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_obj = mp_const_none } },
{ MP_QSTR_subject, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_obj = mp_const_none } },
{ MP_QSTR_msg, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_obj = mp_const_none } },
{ MP_QSTR_cc, MP_ARG_KW_ONLY | MP_ARG_OBJ, { .u_obj = mp_const_none } },
2018-12-04 14:06:15 +08:00
{ MP_QSTR_bcc, MP_ARG_KW_ONLY | MP_ARG_OBJ, { .u_obj = mp_const_none } },
2018-01-03 14:18:06 +01:00
{ MP_QSTR_attach, MP_ARG_KW_ONLY | MP_ARG_OBJ, { .u_obj = mp_const_none } },
{ MP_QSTR_server, MP_ARG_KW_ONLY | MP_ARG_OBJ, { .u_obj = mp_const_none } },
{ MP_QSTR_port, MP_ARG_KW_ONLY | MP_ARG_INT, { .u_int = GMAIL_PORT } },
2018-12-04 14:06:15 +08:00
{ MP_QSTR_protocol, MP_ARG_KW_ONLY | MP_ARG_INT, { .u_int = CURLMAIL_PROTOCOL_SMTPS } },
2018-01-03 14:18:06 +01:00
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
char *user = (char *)mp_obj_str_get_str(args[ARG_user].u_obj);
char *pass = (char *)mp_obj_str_get_str(args[ARG_pass].u_obj);
char *subj = (char *)mp_obj_str_get_str(args[ARG_subject].u_obj);
char *msg = (char *)mp_obj_str_get_str(args[ARG_msg].u_obj);
char *to = NULL;
char mail_server[128] = {'\0'};
uint32_t mail_port = args[ARG_port].u_int;
uint8_t mail_protocol = args[ARG_prot].u_int;
2018-12-04 14:06:15 +08:00
if ((mail_protocol != CURLMAIL_PROTOCOL_SMTP) && (mail_protocol != CURLMAIL_PROTOCOL_SMTPS)) {
2018-01-03 14:18:06 +01:00
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "Unsupported SMTP protocol"));
}
if (MP_OBJ_IS_STR(args[ARG_server].u_obj)) {
sprintf(mail_server, "%s", (char *)mp_obj_str_get_str(args[ARG_server].u_obj));
}
else sprintf(mail_server, GMAIL_SMTP);
2018-12-04 14:06:15 +08:00
// Create curlmail object
curl_mail mailobj = curlmail_create(user, subj);
2018-01-03 14:18:06 +01:00
if (mailobj == NULL) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "Error creating mail object"));
}
2018-12-04 14:06:15 +08:00
// Add recipients
2018-01-03 14:18:06 +01:00
if (MP_OBJ_IS_STR(args[ARG_to].u_obj)) {
to = (char *)mp_obj_str_get_str(args[ARG_to].u_obj);
2018-12-04 14:06:15 +08:00
curlmail_add_to(mailobj, to);
}
2018-01-03 14:18:06 +01:00
else if (MP_OBJ_IS_TYPE(args[ARG_to].u_obj, &mp_type_tuple)) {
mp_obj_t *items;
uint len;
mp_obj_tuple_get(args[ARG_to].u_obj, &len, &items);
2018-12-04 14:06:15 +08:00
if (len == 0) {
curlmail_destroy(mailobj);
curl_global_cleanup();
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Recipient(s) expected"));
}
2018-01-03 14:18:06 +01:00
for (int i = 0; i < len; i++) {
to = (char *)mp_obj_str_get_str(items[i]);
2018-12-04 14:06:15 +08:00
curlmail_add_to(mailobj, to);
2018-01-03 14:18:06 +01:00
}
}
else {
2018-12-04 14:06:15 +08:00
curlmail_destroy(mailobj);
curl_global_cleanup();
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Recipient(s) expected"));
2018-01-03 14:18:06 +01:00
}
2018-12-04 14:06:15 +08:00
// Add CC recipients
2018-01-03 14:18:06 +01:00
if (MP_OBJ_IS_STR(args[ARG_cc].u_obj)) {
to = (char *)mp_obj_str_get_str(args[ARG_cc].u_obj);
2018-12-04 14:06:15 +08:00
curlmail_add_cc(mailobj, to);
}
2018-01-03 14:18:06 +01:00
else if (MP_OBJ_IS_TYPE(args[ARG_cc].u_obj, &mp_type_tuple)) {
mp_obj_t *items;
uint len;
mp_obj_tuple_get(args[ARG_cc].u_obj, &len, &items);
for (int i = 0; i < len; i++) {
to = (char *)mp_obj_str_get_str(items[i]);
2018-12-04 14:06:15 +08:00
curlmail_add_cc(mailobj, to);
2018-01-03 14:18:06 +01:00
}
}
2018-12-04 14:06:15 +08:00
// Add BCC recipients
if (MP_OBJ_IS_STR(args[ARG_bcc].u_obj)) {
to = (char *)mp_obj_str_get_str(args[ARG_bcc].u_obj);
curlmail_add_bcc(mailobj, to);
}
else if (MP_OBJ_IS_TYPE(args[ARG_bcc].u_obj, &mp_type_tuple)) {
mp_obj_t *items;
uint len;
mp_obj_tuple_get(args[ARG_bcc].u_obj, &len, &items);
for (int i = 0; i < len; i++) {
to = (char *)mp_obj_str_get_str(items[i]);
curlmail_add_bcc(mailobj, to);
}
}
// Add attachments
2018-01-03 14:18:06 +01:00
if (MP_OBJ_IS_STR(args[ARG_attach].u_obj)) {
char *fname = (char *)mp_obj_str_get_str(args[ARG_attach].u_obj);
char fullname[128] = {'\0'};
int res = physicalPath(fname, fullname);
if ((res == 0) && (strlen(fullname) > 0)) {
int exists = check_file(fullname);
2018-12-04 14:06:15 +08:00
if (exists) curlmail_add_attachment_file(mailobj, fullname, NULL);
2018-01-03 14:18:06 +01:00
}
2018-12-04 14:06:15 +08:00
}
2018-01-03 14:18:06 +01:00
else if (MP_OBJ_IS_TYPE(args[ARG_attach].u_obj, &mp_type_tuple)) {
mp_obj_t *items;
uint len;
mp_obj_tuple_get(args[ARG_attach].u_obj, &len, &items);
2018-12-04 14:06:15 +08:00
if (len > CURLMAIL_MAX_ATTACHMENTS) {
curlmail_destroy(mailobj);
curl_global_cleanup();
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Maximum number of attachments exceeded"));
}
2018-01-03 14:18:06 +01:00
char *fname = NULL;
char fullname[128] = {'\0'};
for (int i = 0; i < len; i++) {
fname = (char *)mp_obj_str_get_str(items[i]);
int res = physicalPath(fname, fullname);
if ((res == 0) && (strlen(fullname) > 0)) {
int exists = check_file(fullname);
2018-12-04 14:06:15 +08:00
if (exists) curlmail_add_attachment_file(mailobj, fullname, NULL);
2018-01-03 14:18:06 +01:00
}
}
}
2018-12-04 14:06:15 +08:00
curlmail_set_body(mailobj, msg);
2018-01-03 14:18:06 +01:00
2018-12-04 14:06:15 +08:00
// set headers
curlmail_add_header(mailobj, "Importance: Low");
curlmail_add_header(mailobj, "X-Priority: 5");
curlmail_add_header(mailobj, "X-MSMail-Priority: Low");
2018-01-03 14:18:06 +01:00
const char* errmsg = NULL;
2018-12-04 14:06:15 +08:00
errmsg = curlmail_protocol_send(mailobj, mail_server, mail_port, mail_protocol, user, pass);
2018-01-03 14:18:06 +01:00
// Cleanup
2018-12-04 14:06:15 +08:00
curlmail_destroy(mailobj);
curl_global_cleanup();
2018-01-03 14:18:06 +01:00
if (errmsg) {
2018-12-04 14:06:15 +08:00
if (curl_verbose) mp_printf(&mp_plat_print, "ERROR: %s\n", errmsg);
2018-01-03 14:18:06 +01:00
return mp_const_false;
}
return mp_const_true;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(curl_sendmail_obj, 1, curl_sendmail);
#ifdef CONFIG_MICROPY_USE_CURLFTP
//-------------------------------------------------------------------------------------------------------
STATIC mp_obj_t curl_FTP_helper(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args, uint8_t type)
{
2018-12-04 14:06:15 +08:00
network_checkConnection();
2018-01-03 14:18:06 +01:00
enum { ARG_url, ARG_user, ARG_pass, ARG_file };
const mp_arg_t allowed_args[] = {
{ MP_QSTR_url, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_obj = mp_const_none } },
{ MP_QSTR_user, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_obj = mp_const_none } },
{ MP_QSTR_password, MP_ARG_REQUIRED | MP_ARG_OBJ, { .u_obj = mp_const_none } },
{ MP_QSTR_file, MP_ARG_OBJ, { .u_obj = mp_const_none } },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
int res;
int hdr_len = hdr_maxlen;
int body_len = body_maxlen;
vstr_t header;
vstr_t body;
const char *url = mp_obj_str_get_str(args[ARG_url].u_obj);;
const char *user = mp_obj_str_get_str(args[ARG_user].u_obj);;
const char *pass = mp_obj_str_get_str(args[ARG_pass].u_obj);;
char userpass[64];
char *fname = NULL;
char fullname[128] = {'\0'};
if (strstr(url, "ftp://") != url) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "URL must start with 'ftp://'"));
}
sprintf(userpass, "%s:%s", user, pass);
if ((type == 0) || (type == 1)) {
if (MP_OBJ_IS_STR(args[ARG_file].u_obj)) {
// GET to file
fname = (char *)mp_obj_str_get_str(args[ARG_file].u_obj);
if (strcmp(fname, "simulate") != 0) {
res = physicalPath(fname, fullname);
if ((res != 0) || (strlen(fullname) == 0)) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "Error resolving file name"));
}
fname = fullname;
}
2018-01-21 16:14:38 +01:00
body_len = MIN_BODY_BUF_LEN;
2018-01-03 14:18:06 +01:00
}
else if (type == 1) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "Expected file name for PUT command"));
}
}
vstr_init_len(&header, hdr_len);
vstr_init_len(&body, body_len);
header.buf[0] = '\0';
body.buf[0] = '\0';
MP_THREAD_GIL_EXIT();
2018-12-04 14:06:15 +08:00
res = Curl_FTP(type&1, (char *)url, userpass, fname, header.buf, body.buf, header.len, body.len);
2018-01-03 14:18:06 +01:00
MP_THREAD_GIL_ENTER();
mp_obj_t tuple[3];
tuple[0] = mp_obj_new_int(res);
header.len = strlen(header.buf);
body.len = strlen(body.buf);
tuple[1] = mp_obj_new_str_from_vstr(&mp_type_str, &header);
tuple[2] = mp_obj_new_str_from_vstr(&mp_type_str, &body);
return mp_obj_new_tuple(3, tuple);
}
//--------------------------------------------------------------------------------------
STATIC mp_obj_t curl_FTP_GET(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args)
{
return curl_FTP_helper(n_args, pos_args, kw_args, 0);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(curl_FTP_GET_obj, 3, curl_FTP_GET);
//--------------------------------------------------------------------------------------
STATIC mp_obj_t curl_FTP_PUT(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args)
{
return curl_FTP_helper(n_args, pos_args, kw_args, 1);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(curl_FTP_PUT_obj, 3, curl_FTP_PUT);
//---------------------------------------------------------------------------------------
STATIC mp_obj_t curl_FTP_LIST(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args)
{
return curl_FTP_helper(n_args, pos_args, kw_args, 2);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(curl_FTP_LIST_obj, 3, curl_FTP_LIST);
#endif
//============================================================
STATIC const mp_rom_map_elem_t curl_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_curl) },
2018-01-21 16:14:38 +01:00
{ MP_ROM_QSTR(MP_QSTR_info), MP_ROM_PTR(&curl_info_obj) },
{ MP_ROM_QSTR(MP_QSTR_options), MP_ROM_PTR(&curl_Options_obj) },
{ MP_ROM_QSTR(MP_QSTR_get), MP_ROM_PTR(&curl_GET_obj) },
{ MP_ROM_QSTR(MP_QSTR_post), MP_ROM_PTR(&curl_POST_obj) },
{ MP_ROM_QSTR(MP_QSTR_sendmail), MP_ROM_PTR(&curl_sendmail_obj) },
2018-12-04 14:06:15 +08:00
{ MP_ROM_QSTR(MP_QSTR_getmail), MP_ROM_PTR(&curl_GET_MAIL_obj) },
2018-02-07 17:51:08 +01:00
2018-01-03 14:18:06 +01:00
#ifdef CONFIG_MICROPY_USE_CURLFTP
2018-01-21 16:14:38 +01:00
{ MP_ROM_QSTR(MP_QSTR_ftp_get), MP_ROM_PTR(&curl_FTP_GET_obj) },
{ MP_ROM_QSTR(MP_QSTR_ftp_put), MP_ROM_PTR(&curl_FTP_PUT_obj) },
{ MP_ROM_QSTR(MP_QSTR_ftp_list), MP_ROM_PTR(&curl_FTP_LIST_obj) },
2018-01-03 14:18:06 +01:00
#endif
2018-01-21 16:14:38 +01:00
// Constants
2018-12-04 14:06:15 +08:00
{ MP_ROM_QSTR(MP_QSTR_SMTP), MP_ROM_INT(CURLMAIL_PROTOCOL_SMTP) },
{ MP_ROM_QSTR(MP_QSTR_SMTPS), MP_ROM_INT(CURLMAIL_PROTOCOL_SMTPS) },
2018-01-03 14:18:06 +01:00
};
STATIC MP_DEFINE_CONST_DICT(curl_module_globals, curl_module_globals_table);
//======================================
const mp_obj_module_t mp_module_curl = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&curl_module_globals,
};
#endif