Compare commits

...

4 Commits

Author SHA1 Message Date
Simon Laux
5a6f2529b1 try to make linter happier 2019-12-20 20:34:42 +01:00
Simon Laux
e25b409c7e cargo fmt 2019-12-20 20:18:32 +01:00
Simon Laux
5479877f65 add provider db documentation url
default case for unwrapping
try fixing python linting
2019-12-20 15:17:07 +01:00
Simon Laux
7da5fe2726 json api for provider overview 2019-12-19 18:33:43 +01:00
7 changed files with 61 additions and 226 deletions

8
Cargo.lock generated
View File

@@ -716,12 +716,13 @@ dependencies = [
[[package]]
name = "deltachat-provider-database"
version = "0.2.1"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
"yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -738,11 +739,12 @@ name = "deltachat_ffi"
version = "1.0.0-beta.20"
dependencies = [
"deltachat 1.0.0-beta.20",
"deltachat-provider-database 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"deltachat-provider-database 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"human-panic 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -3533,7 +3535,7 @@ dependencies = [
"checksum darling_macro 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72"
"checksum debug_stub_derive 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "496b7f8a2f853313c3ca370641d7ff3e42c32974fdccda8f0684599ed0a3ff6b"
"checksum deflate 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)" = "707b6a7b384888a70c8d2e8650b3e60170dfc6a67bb4aa67b6dfca57af4bedb4"
"checksum deltachat-provider-database 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "814dba060d9fdc7a989fccdc4810ada9d1c7a1f09131c78e42412bc6c634b93b"
"checksum deltachat-provider-database 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc18fb898a7bc90565c801d7bd17a4b61478f0da0ea06ecf7f0428bd20242c52"
"checksum derive_builder 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a2658621297f2cf68762a6f7dc0bb7e1ff2cfd6583daef8ee0fed6f7ec468ec0"
"checksum derive_builder_core 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2791ea3e372c8495c0bc2033991d76b512cd799d07491fbd6890124db9458bef"
"checksum des 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74ba5f1b5aee9772379c2670ba81306e65a93c0ee3caade7a1d22b188d88a3af"

View File

@@ -16,11 +16,12 @@ crate-type = ["cdylib", "staticlib"]
[dependencies]
deltachat = { path = "../", default-features = false }
deltachat-provider-database = "0.2.1"
deltachat-provider-database = "0.3.0"
libc = "0.2"
human-panic = "1.0.1"
num-traits = "0.2.6"
failure = "0.1.6"
serde_json = "1.0"
[features]
default = ["vendored", "nightly", "ringbuf"]

View File

@@ -18,7 +18,6 @@ typedef struct _dc_chat dc_chat_t;
typedef struct _dc_msg dc_msg_t;
typedef struct _dc_contact dc_contact_t;
typedef struct _dc_lot dc_lot_t;
typedef struct _dc_provider dc_provider_t;
/**
@@ -3660,106 +3659,30 @@ int dc_contact_is_verified (dc_contact_t* contact);
/**
* @class dc_provider_t
*
* Opaque object containing information about one single email provider.
*/
/**
* Create a provider struct for the given domain.
* Get the provider json object for the given domain.
* For more documentation see https://docs.rs/deltachat-provider-database/
*
* @memberof dc_provider_t
* @param domain The domain to get provider info for.
* @return a dc_provider_t struct which can be used with the dc_provider_get_*
* accessor functions. If no provider info is found, NULL will be
* returned.
* @return a provider json object as string. If no provider info is found, an empty string will be returned.
*/
dc_provider_t* dc_provider_new_from_domain (const char* domain);
char* dc_provider_json_from_domain (const char* domain);
/**
* Create a provider struct for the given email address.
* Get the provider json object for the given email address.
* For more documentation see https://docs.rs/deltachat-provider-database/
*
* The provider is extracted from the email address and it's information is returned.
*
* @memberof dc_provider_t
* @param email The user's email address to extract the provider info form.
* @return a dc_provider_t struct which can be used with the dc_provider_get_*
* accessor functions. If no provider info is found, NULL will be
* returned.
* @return a provider json object as string. If no provider info is found, an empty string will be returned.
*/
dc_provider_t* dc_provider_new_from_email (const char* email);
/**
* URL of the overview page.
*
* This URL allows linking to the providers page on providers.delta.chat.
*
* @memberof dc_provider_t
* @param provider The dc_provider_t struct.
* @return A string which must be released using dc_str_unref().
*/
char* dc_provider_get_overview_page (const dc_provider_t* provider);
/**
* The provider's name.
*
* The name of the provider, e.g. "POSTEO".
*
* @memberof dc_provider_t
* @param provider The dc_provider_t struct.
* @return A string which must be released using dc_str_unref().
*/
char* dc_provider_get_name (const dc_provider_t* provider);
/**
* The markdown content of the providers page.
*
* This contains the preparation steps or additional information if the status
* is @ref DC_PROVIDER_STATUS_BROKEN.
*
* @memberof dc_provider_t
* @param provider The dc_provider_t struct.
* @return A string which must be released using dc_str_unref().
*/
char* dc_provider_get_markdown (const dc_provider_t* provider);
/**
* Date of when the state was last checked/updated.
*
* This is returned as a string.
*
* @memberof dc_provider_t
* @param provider The dc_provider_t struct.
* @return A string which must be released using dc_str_unref().
*/
char* dc_provider_get_status_date (const dc_provider_t* provider);
/**
* Whether DC works with this provider.
*
* Can be one of @ref DC_PROVIDER_STATUS_OK, @ref
* DC_PROVIDER_STATUS_PREPARATION and @ref DC_PROVIDER_STATUS_BROKEN.
*
* @memberof dc_provider_t
* @param provider The dc_provider_t struct.
* @return The status as a constant number.
*/
int dc_provider_get_status (const dc_provider_t* provider);
/**
* Free the provider info struct.
*
* @memberof dc_provider_t
* @param provider The dc_provider_t struct.
*/
void dc_provider_unref (const dc_provider_t* provider);
char* dc_provider_json_from_email (const char* email);
/**
@@ -4475,41 +4398,6 @@ void dc_array_add_id (dc_array_t*, uint32_t); // depreca
#define DC_SHOW_EMAILS_ALL 2
/**
* @defgroup DC_PROVIDER_STATUS DC_PROVIDER_STATUS
*
* These constants are used as return values for dc_provider_get_status().
*
* @addtogroup DC_PROVIDER_STATUS
* @{
*/
/**
* Provider status returned by dc_provider_get_status().
*
* Works right out of the box without any preperation steps needed
*/
#define DC_PROVIDER_STATUS_OK 1
/**
* Provider status returned by dc_provider_get_status().
*
* Works, but preparation steps are needed
*/
#define DC_PROVIDER_STATUS_PREPARATION 2
/**
* Provider status returned by dc_provider_get_status().
*
* Doesn't work (too unstable to use falls also in this category)
*/
#define DC_PROVIDER_STATUS_BROKEN 3
/**
* @}
*/
/*
* TODO: Strings need some doumentation about used placeholders.
*

View File

@@ -1,93 +1,35 @@
extern crate deltachat_provider_database;
use std::ptr;
use crate::string::{to_string_lossy, StrExt};
use deltachat_provider_database::StatusState;
#[no_mangle]
pub type dc_provider_t = deltachat_provider_database::Provider;
#[no_mangle]
pub unsafe extern "C" fn dc_provider_new_from_domain(
pub unsafe extern "C" fn dc_provider_json_from_domain(
domain: *const libc::c_char,
) -> *const dc_provider_t {
match deltachat_provider_database::get_provider_info(&to_string_lossy(domain)) {
Some(provider) => provider,
None => ptr::null(),
) -> *mut libc::c_char {
let domain = to_string_lossy(domain);
match deltachat_provider_database::get_provider_info(&domain) {
Some(provider) => serde_json::to_string(provider)
.unwrap_or("".to_owned())
.strdup(),
None => "".strdup(),
}
}
#[no_mangle]
pub unsafe extern "C" fn dc_provider_new_from_email(
pub unsafe extern "C" fn dc_provider_json_from_email(
email: *const libc::c_char,
) -> *const dc_provider_t {
) -> *mut libc::c_char {
let email = to_string_lossy(email);
let domain = deltachat_provider_database::get_domain_from_email(&email);
match deltachat_provider_database::get_provider_info(domain) {
Some(provider) => provider,
None => ptr::null(),
Some(provider) => serde_json::to_string(provider)
.unwrap_or("".to_owned())
.strdup(),
None => "".strdup(),
}
}
macro_rules! null_guard {
($context:tt) => {
if $context.is_null() {
return ptr::null_mut() as *mut libc::c_char;
}
};
}
#[no_mangle]
pub unsafe extern "C" fn dc_provider_get_overview_page(
provider: *const dc_provider_t,
) -> *mut libc::c_char {
null_guard!(provider);
format!(
"{}/{}",
deltachat_provider_database::PROVIDER_OVERVIEW_URL,
(*provider).overview_page
)
.strdup()
}
#[no_mangle]
pub unsafe extern "C" fn dc_provider_get_name(provider: *const dc_provider_t) -> *mut libc::c_char {
null_guard!(provider);
(*provider).name.strdup()
}
#[no_mangle]
pub unsafe extern "C" fn dc_provider_get_markdown(
provider: *const dc_provider_t,
) -> *mut libc::c_char {
null_guard!(provider);
(*provider).markdown.strdup()
}
#[no_mangle]
pub unsafe extern "C" fn dc_provider_get_status_date(
provider: *const dc_provider_t,
) -> *mut libc::c_char {
null_guard!(provider);
(*provider).status.date.strdup()
}
#[no_mangle]
pub unsafe extern "C" fn dc_provider_get_status(provider: *const dc_provider_t) -> u32 {
if provider.is_null() {
return 0;
}
match (*provider).status.state {
StatusState::OK => 1,
StatusState::PREPARATION => 2,
StatusState::BROKEN => 3,
}
}
#[no_mangle]
pub unsafe extern "C" fn dc_provider_unref(_provider: *const dc_provider_t) {
()
}
// TODO expose general provider overview url?

View File

@@ -1,7 +1,8 @@
"""Provider info class."""
from .capi import ffi, lib
from .capi import lib
from .cutil import as_dc_charpointer, from_dc_charpointer
import json
class ProviderNotFoundError(Exception):
@@ -16,13 +17,12 @@ class Provider(object):
"""
def __init__(self, domain):
provider = ffi.gc(
lib.dc_provider_new_from_domain(as_dc_charpointer(domain)),
lib.dc_provider_unref,
provider = from_dc_charpointer(
lib.dc_provider_json_from_domain(as_dc_charpointer(domain))
)
if provider == ffi.NULL:
if provider == "":
raise ProviderNotFoundError("Provider not found")
self._provider = provider
self._provider = json.loads(provider)
@classmethod
def from_email(cls, email):
@@ -35,33 +35,30 @@ class Provider(object):
@property
def overview_page(self):
"""URL to the overview page of the provider on providers.delta.chat."""
return from_dc_charpointer(
lib.dc_provider_get_overview_page(self._provider))
return "https://providers.delta.chat/" + self._provider['overview_page']
@property
def name(self):
"""The name of the provider."""
return from_dc_charpointer(lib.dc_provider_get_name(self._provider))
return self._provider['name']
@property
def markdown(self):
"""Content of the information page, formatted as markdown."""
return from_dc_charpointer(
lib.dc_provider_get_markdown(self._provider))
return self._provider['markdown']
@property
def status_date(self):
"""The date the provider info was last updated, as a string."""
return from_dc_charpointer(
lib.dc_provider_get_status_date(self._provider))
return self._provider['status']['date']
@property
def status(self):
"""The status of the provider information.
This is one of the
:attr:`deltachat.const.DC_PROVIDER_STATUS_OK`,
:attr:`deltachat.const.DC_PROVIDER_STATUS_PREPARATION` or
:attr:`deltachat.const.DC_PROVIDER_STATUS_BROKEN` constants.
This is
:attr:`"OK"`,
:attr:`"PREPARATION"` or
:attr:`"BROKEN"`.
"""
return lib.dc_provider_get_status(self._provider)
return self._provider['status']['state']

View File

@@ -3,6 +3,7 @@ from deltachat import capi, cutil, const, set_context_callback, clear_context_ca
from deltachat.capi import ffi
from deltachat.capi import lib
from deltachat.account import EventLogger
import json
def test_empty_context():
@@ -103,18 +104,23 @@ def test_get_special_message_id_returns_empty_message(acfactory):
def test_provider_info():
provider = lib.dc_provider_new_from_email(cutil.as_dc_charpointer("ex@example.com"))
assert cutil.from_dc_charpointer(
lib.dc_provider_get_overview_page(provider)
) == "https://providers.delta.chat/example.com"
assert cutil.from_dc_charpointer(lib.dc_provider_get_name(provider)) == "Example"
assert cutil.from_dc_charpointer(lib.dc_provider_get_markdown(provider)) == "\n..."
assert cutil.from_dc_charpointer(lib.dc_provider_get_status_date(provider)) == "2018-09"
assert lib.dc_provider_get_status(provider) == const.DC_PROVIDER_STATUS_PREPARATION
provider_json = cutil.from_dc_charpointer(
lib.dc_provider_json_from_email(cutil.as_dc_charpointer("ex@example.com"))
)
provider = json.loads(provider_json)
assert provider['overview_page'] == "example.com"
assert provider['name'] == "Example"
assert provider['markdown'] == "\n..."
assert provider['status']['date'] == "2018-09"
assert provider['status']['state'] == "PREPARATION"
def test_provider_info_none():
assert lib.dc_provider_new_from_email(cutil.as_dc_charpointer("email@unexistent.no")) == ffi.NULL
provider_json = cutil.from_dc_charpointer(
lib.dc_provider_json_from_email(cutil.as_dc_charpointer("email@unexistent.no"))
)
assert provider_json == ""
def test_get_info_closed():

View File

@@ -1,6 +1,5 @@
import pytest
from deltachat import const
from deltachat import provider
@@ -10,7 +9,7 @@ def test_provider_info_from_email():
assert example.name == "Example"
assert example.markdown == "\n..."
assert example.status_date == "2018-09"
assert example.status == const.DC_PROVIDER_STATUS_PREPARATION
assert example.status == "PREPARATION"
def test_provider_info_from_domain():
@@ -19,7 +18,7 @@ def test_provider_info_from_domain():
assert example.name == "Example"
assert example.markdown == "\n..."
assert example.status_date == "2018-09"
assert example.status == const.DC_PROVIDER_STATUS_PREPARATION
assert example.status == "PREPARATION"
def test_provider_info_none():