M module-services/service-db/DBServiceAPI.cpp => module-services/service-db/DBServiceAPI.cpp +16 -0
@@ 362,6 362,22 @@ void DBServiceAPI::QuotesIntervalChanged(sys::Service *serv, const std::string &
DBServiceAPI::GetQuery(serv, db::Interface::Name::Quotes, std::move(query));
}
+bool DBServiceAPI::QuotesGetGroup(sys::Service *serv, std::unique_ptr<db::QueryListener> &&listener)
+{
+ auto query = std::make_unique<Quotes::Messages::GetGroup>();
+ query->setQueryListener(std::move(listener));
+ const auto [result, _] = DBServiceAPI::GetQuery(serv, db::Interface::Name::Quotes, std::move(query));
+ return result;
+}
+
+bool DBServiceAPI::QuotesGetInterval(sys::Service *serv, std::unique_ptr<db::QueryListener> &&listener)
+{
+ auto query = std::make_unique<Quotes::Messages::GetInterval>();
+ query->setQueryListener(std::move(listener));
+ const auto [result, _] = DBServiceAPI::GetQuery(serv, db::Interface::Name::Quotes, std::move(query));
+ return result;
+}
+
auto DBServiceAPI::hasContactSameNumbers(sys::Service *serv, const ContactRecord &rec) -> bool
{
std::shared_ptr<DBContactMessage> msg =
M module-services/service-db/include/service-db/DBServiceAPI.hpp => module-services/service-db/include/service-db/DBServiceAPI.hpp +2 -0
@@ 140,4 140,6 @@ class DBServiceAPI
static bool QuotesDeleteEntry(sys::Service *serv, std::uint32_t id, std::unique_ptr<db::QueryListener> &&listener);
static void QuotesGroupChanged(sys::Service *serv, const std::string &group);
static void QuotesIntervalChanged(sys::Service *serv, const std::string &interval);
+ static bool QuotesGetGroup(sys::Service *serv, std::unique_ptr<db::QueryListener> &&listener);
+ static bool QuotesGetInterval(sys::Service *serv, std::unique_ptr<db::QueryListener> &&listener);
};
M module-services/service-db/include/service-db/QuotesMessages.hpp => module-services/service-db/include/service-db/QuotesMessages.hpp +50 -0
@@ 432,6 432,31 @@ namespace Quotes
}
};
+ class GetGroup : public db::Query
+ {
+ public:
+ explicit GetGroup() : Query(Query::Type::Create)
+ {}
+
+ auto debugInfo() const -> std::string
+ {
+ return "GetGroup";
+ }
+ };
+
+ class GetGroupResponse : public db::QueryResult
+ {
+ public:
+ explicit GetGroupResponse(const std::string &group) : group(group)
+ {}
+ const std::string group;
+
+ auto debugInfo() const -> std::string
+ {
+ return "GetGroupResponse";
+ }
+ };
+
class InformIntervalChanged : public db::Query
{
public:
@@ 445,6 470,31 @@ namespace Quotes
}
};
+ class GetInterval : public db::Query
+ {
+ public:
+ explicit GetInterval() : Query(Query::Type::Create)
+ {}
+
+ auto debugInfo() const -> std::string
+ {
+ return "GetInterval";
+ }
+ };
+
+ class GetIntervalResponse : public db::QueryResult
+ {
+ public:
+ explicit GetIntervalResponse(const std::string &interval) : interval(interval)
+ {}
+ const std::string interval;
+
+ auto debugInfo() const -> std::string
+ {
+ return "GetIntervalResponse";
+ }
+ };
+
class WriteQuoteRequest : public db::Query
{
public:
M module-services/service-desktop/endpoints/include/endpoints/JsonKeyNames.hpp => module-services/service-desktop/endpoints/include/endpoints/JsonKeyNames.hpp +22 -21
@@ 67,26 67,26 @@ namespace sdesktop::endpoints::json
inline constexpr auto categoryBackup = "backup";
inline constexpr auto categorySync = "sync";
- inline constexpr auto limit = "limit";
- inline constexpr auto offset = "offset";
- inline constexpr auto order = "order";
- inline constexpr auto entries = "entries";
- inline constexpr auto messageBody = "messageBody";
- inline constexpr auto messageCount = "messageCount";
- inline constexpr auto messageID = "messageID";
- inline constexpr auto messageType = "messageType";
- inline constexpr auto phoneNumber = "phoneNumber";
- inline constexpr auto createdAt = "createdAt";
- inline constexpr auto lastUsedAt = "lastUsedAt";
- inline constexpr auto lastUpdatedAt = "lastUpdatedAt";
- inline constexpr auto isUnread = "isUnread";
- inline constexpr auto contactID = "contactID";
- inline constexpr auto number = "number";
- inline constexpr auto numberID = "numberID";
- inline constexpr auto threadID = "threadID";
- inline constexpr auto messageSnippet = "messageSnippet";
- inline constexpr auto templateBody = "templateBody";
- inline constexpr auto templateID = "templateID";
+ inline constexpr auto limit = "limit";
+ inline constexpr auto offset = "offset";
+ inline constexpr auto order = "order";
+ inline constexpr auto entries = "entries";
+ inline constexpr auto messageBody = "messageBody";
+ inline constexpr auto messageCount = "messageCount";
+ inline constexpr auto messageID = "messageID";
+ inline constexpr auto messageType = "messageType";
+ inline constexpr auto phoneNumber = "phoneNumber";
+ inline constexpr auto createdAt = "createdAt";
+ inline constexpr auto lastUsedAt = "lastUsedAt";
+ inline constexpr auto lastUpdatedAt = "lastUpdatedAt";
+ inline constexpr auto isUnread = "isUnread";
+ inline constexpr auto contactID = "contactID";
+ inline constexpr auto number = "number";
+ inline constexpr auto numberID = "numberID";
+ inline constexpr auto threadID = "threadID";
+ inline constexpr auto messageSnippet = "messageSnippet";
+ inline constexpr auto templateBody = "templateBody";
+ inline constexpr auto templateID = "templateID";
} // namespace messages
namespace outbox
@@ 122,7 122,7 @@ namespace sdesktop::endpoints::json
{
inline constexpr auto value = "value";
inline constexpr auto timestamp = "timestamp";
- }
+ } // namespace timeSync
namespace quotes
{
@@ 131,6 131,7 @@ namespace sdesktop::endpoints::json
inline constexpr auto group = "group";
inline constexpr auto interval = "interval";
inline constexpr auto quoteID = "quoteID";
+ inline constexpr auto settings = "settings";
} // namespace quotes
} // namespace sdesktop::endpoints::json
M products/BellHybrid/services/db/ServiceDB.cpp => products/BellHybrid/services/db/ServiceDB.cpp +40 -1
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2025, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/blob/master/LICENSE.md
#include "include/db/ServiceDB.hpp"
@@ 56,6 56,35 @@ db::Interface *ServiceDB::getInterface(db::Interface::Name interface)
return nullptr;
}
+sys::MessagePointer ServiceDB::DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp)
+{
+ const auto message = ServiceDBCommon::DataReceivedHandler(msgl, resp);
+ auto responseMsg = std::static_pointer_cast<sys::ResponseMessage>(message);
+ if (responseMsg) {
+ return responseMsg;
+ }
+
+ auto type = static_cast<MessageType>(msgl->messageType);
+ switch (type) {
+ case MessageType::DBSyncPackage: {
+ auto time = utils::time::Scoped("DBSyncPackage");
+ auto msg = static_cast<DBServiceMessageSyncPackage *>(msgl);
+ auto ret = StoreIntoSyncPackage({msg->syncPackagePath});
+ responseMsg = std::make_shared<DBServiceResponseMessage>(ret);
+ } break;
+
+ default:
+ break;
+ }
+
+ if (responseMsg == nullptr) {
+ return std::make_shared<sys::ResponseMessage>();
+ }
+
+ responseMsg->responseTo = msgl->messageType;
+ return responseMsg;
+}
+
sys::ReturnCodes ServiceDB::InitHandler()
{
if (const auto returnCode = ServiceDBCommon::InitHandler(); returnCode != sys::ReturnCodes::Success) {
@@ 98,3 127,13 @@ sys::ReturnCodes ServiceDB::InitHandler()
return sys::ReturnCodes::Success;
}
+
+bool ServiceDB::StoreIntoSyncPackage(const std::filesystem::path &syncPackagePath)
+{
+ const auto &path = syncPackagePath / std::filesystem::path(quotesDB->getName()).filename();
+ if (!quotesDB->storeIntoFile(path)) {
+ LOG_ERROR("Store quotesDB in sync package failed");
+ return false;
+ }
+ return true;
+}
M products/BellHybrid/services/db/agents/QuotesAgent.cpp => products/BellHybrid/services/db/agents/QuotesAgent.cpp +23 -0
@@ 36,9 36,15 @@ namespace Quotes
else if (typeid(*query) == typeid(Messages::InformGroupChanged)) {
return handleGroupChanged(query);
}
+ else if (typeid(*query) == typeid(Messages::GetGroup)) {
+ return handleGetGroup(query);
+ }
else if (typeid(*query) == typeid(Messages::InformIntervalChanged)) {
return handleIntervalChanged(query);
}
+ else if (typeid(*query) == typeid(Messages::GetInterval)) {
+ return handleGetInterval(query);
+ }
return nullptr;
}
@@ 160,6 166,14 @@ namespace Quotes
return std::make_unique<Messages::NotificationResult>(true);
}
+ auto QuotesAgent::handleGetGroup(std::shared_ptr<db::Query> query) -> std::unique_ptr<db::QueryResult>
+ {
+ const auto "esGroup = settings->getValue(settings::Quotes::selectedGroup, settings::SettingsScope::Global);
+ auto response = std::make_unique<Messages::GetGroupResponse>(quotesGroup);
+ response->setRequestQuery(query);
+ return response;
+ }
+
auto QuotesAgent::handleIntervalChanged(std::shared_ptr<db::Query> query) -> std::unique_ptr<db::QueryResult>
{
const auto request = std::dynamic_pointer_cast<Messages::InformIntervalChanged>(query);
@@ 174,4 188,13 @@ namespace Quotes
shuffleQuoteModel.updateList(ListUpdateMode::Forced);
return std::make_unique<Messages::NotificationResult>(true);
}
+
+ auto QuotesAgent::handleGetInterval(std::shared_ptr<db::Query> query) -> std::unique_ptr<db::QueryResult>
+ {
+ const auto "esInterval =
+ settings->getValue(settings::Quotes::selectedInterval, settings::SettingsScope::Global);
+ auto response = std::make_unique<Messages::GetIntervalResponse>(quotesInterval);
+ response->setRequestQuery(query);
+ return response;
+ }
} // namespace Quotes
M products/BellHybrid/services/db/agents/QuotesAgent.hpp => products/BellHybrid/services/db/agents/QuotesAgent.hpp +2 -0
@@ 35,6 35,8 @@ namespace Quotes
auto handleEditEntry(std::shared_ptr<db::Query> query) -> std::unique_ptr<db::QueryResult>;
auto handleDeleteEntry(std::shared_ptr<db::Query> query) -> std::unique_ptr<db::QueryResult>;
auto handleGroupChanged(std::shared_ptr<db::Query> query) -> std::unique_ptr<db::QueryResult>;
+ auto handleGetGroup(std::shared_ptr<db::Query> query) -> std::unique_ptr<db::QueryResult>;
auto handleIntervalChanged(std::shared_ptr<db::Query> query) -> std::unique_ptr<db::QueryResult>;
+ auto handleGetInterval(std::shared_ptr<db::Query> query) -> std::unique_ptr<db::QueryResult>;
};
} // namespace Quotes
M products/BellHybrid/services/db/include/db/ServiceDB.hpp => products/BellHybrid/services/db/include/db/ServiceDB.hpp +4 -1
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2025, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/blob/master/LICENSE.md
#pragma once
@@ 34,7 34,10 @@ class ServiceDB : public ServiceDBCommon
std::unique_ptr<db::multimedia_files::MultimediaFilesRecordInterface> multimediaFilesRecordInterface;
db::Interface *getInterface(db::Interface::Name interface) override;
+ sys::MessagePointer DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp) override;
sys::ReturnCodes InitHandler() override;
+
+ bool StoreIntoSyncPackage(const std::filesystem::path &syncPackagePath);
};
namespace sys
M products/BellHybrid/services/desktop/endpoints/quotes/QuotesHelper.cpp => products/BellHybrid/services/desktop/endpoints/quotes/QuotesHelper.cpp +44 -1
@@ 14,7 14,50 @@ namespace sdesktop::endpoints
{
auto QuotesHelper::processGet(Context &context) -> ProcessResult
{
- // TODO: https://appnroll.atlassian.net/browse/BH-2099
+ const auto &body = context.getBody();
+ if (const auto settings = body[json::quotes::settings].string_value(); !settings.empty()) {
+ if (settings == json::quotes::group) {
+ auto listener = std::make_unique<db::EndpointListener>(
+ [=](db::QueryResult *result, Context &context) {
+ const auto getGroupResult = dynamic_cast<Quotes::Messages::GetGroupResponse *>(result);
+ if (getGroupResult == nullptr) {
+ context.setResponseStatus(http::Code::InternalServerError);
+ sender::putToSendQueue(context.createSimpleResponse());
+ return false;
+ }
+
+ context.setResponseBody(json11::Json::object{{json::quotes::group, getGroupResult->group}});
+ context.setResponseStatus(http::Code::OK);
+ sender::putToSendQueue(context.createSimpleResponse());
+ return true;
+ },
+ context);
+
+ DBServiceAPI::QuotesGetGroup(owner, std::move(listener));
+ return {Sent::Yes, std::nullopt};
+ }
+ else if (settings == json::quotes::interval) {
+ auto listener = std::make_unique<db::EndpointListener>(
+ [=](db::QueryResult *result, Context &context) {
+ const auto getIntervalResult = dynamic_cast<Quotes::Messages::GetIntervalResponse *>(result);
+ if (getIntervalResult == nullptr) {
+ context.setResponseStatus(http::Code::InternalServerError);
+ sender::putToSendQueue(context.createSimpleResponse());
+ return false;
+ }
+
+ context.setResponseBody(
+ json11::Json::object{{json::quotes::interval, getIntervalResult->interval}});
+ context.setResponseStatus(http::Code::OK);
+ sender::putToSendQueue(context.createSimpleResponse());
+ return true;
+ },
+ context);
+
+ DBServiceAPI::QuotesGetInterval(owner, std::move(listener));
+ return {Sent::Yes, std::nullopt};
+ }
+ }
return {Sent::No, ResponseContext{.status = http::Code::BadRequest}};
}
M test/custom_quotes.py => test/custom_quotes.py +221 -58
@@ 39,13 39,63 @@ endpoint_types = {
payload_marker = '#'
payload_size_len = 9
port_timeout_short_s = 1
+port_timeout_medium_s = 2
port_timeout_long_s = 5
port_baudrate = 115200
+default_rx_data_size = 1024
+chunk_rx_data_size = 1024 * 200
+
+sync_filename = 'sync.tar'
+sync_path = '/user/temp/' + sync_filename
def get_new_uuid() -> int:
return random.randint(1, 10000)
+def send_data(port_path: str, payload_str: str, expected_response: int) -> bool:
+ payload_len_str = str(len(payload_str)).rjust(payload_size_len, '0')
+ request_str = payload_marker + payload_len_str + payload_str
+
+ with serial.Serial(port_path, port_baudrate, timeout=port_timeout_short_s) as port:
+ port.write(request_str.encode('ascii'))
+ response = port.read(2048)
+ resp_json = json.loads(response[10:])
+ status = resp_json['status']
+ if status == expected_response:
+ print(f'Request success')
+ return True
+ print(f'Request failed, status {status}')
+ return False
+
+def get_request_response(port_path: str, request: str, expected_size: int) -> str:
+ payload_len_str = str(len(request)).rjust(payload_size_len, '0')
+ request_str = payload_marker + payload_len_str + request
+
+ response = ''
+ with serial.Serial(port_path, port_baudrate, timeout=port_timeout_medium_s) as port:
+ port.write(request_str.encode('ascii'))
+ response = port.read(expected_size)
+ return response
+
+def get_str_data(port_path: str, payload_str: str, expected_responses: int, body_str: str) -> str:
+ payload_len_str = str(len(payload_str)).rjust(payload_size_len, '0')
+ request_str = payload_marker + payload_len_str + payload_str
+
+ with serial.Serial(port_path, port_baudrate, timeout=port_timeout_short_s) as port:
+ port.write(request_str.encode('ascii'))
+ response = port.read(2048)
+ resp_json = json.loads(response[10:])
+ status = resp_json['status']
+
+ for expected_status in expected_responses:
+ if status == expected_status:
+ print(f'Request success')
+ body = resp_json['body']
+ return body[body_str]
+
+ print(f'Request failed, status {status}')
+ return ""
+
def add_quote(port_path: str, quote_str: str, author_str: str) -> bool:
uuid = get_new_uuid()
@@ 76,7 126,6 @@ def add_quote(port_path: str, quote_str: str, author_str: str) -> bool:
def edit_quote(port_path: str, quote_id: int, quote_str: str, author_str: str) -> bool:
uuid = get_new_uuid()
-
payload = {
'endpoint': endpoint_types['Quotes'],
'method': http_methods['PUT'],
@@ 87,25 136,11 @@ def edit_quote(port_path: str, quote_id: int, quote_str: str, author_str: str)
'author': author_str
}
}
-
payload_str = json.dumps(payload)
- payload_len_str = str(len(payload_str)).rjust(payload_size_len, '0')
- request_str = payload_marker + payload_len_str + payload_str
-
- with serial.Serial(port_path, port_baudrate, timeout=port_timeout_short_s) as port:
- port.write(request_str.encode('ascii'))
- response = port.read(2048)
- resp_json = json.loads(response[10:])
- status = resp_json['status']
- if status == 200:
- print(f'Request success')
- return True
- print(f'Request failed, status {status}')
- return False
+ return send_data(port_path, payload_str, 200)
def delete_quote(port_path: str, quote_id: int) -> bool:
uuid = get_new_uuid()
-
payload = {
'endpoint': endpoint_types['Quotes'],
'method': http_methods['DELETE'],
@@ 114,25 149,11 @@ def delete_quote(port_path: str, quote_id: int) -> bool:
'quoteID': quote_id
}
}
-
payload_str = json.dumps(payload)
- payload_len_str = str(len(payload_str)).rjust(payload_size_len, '0')
- request_str = payload_marker + payload_len_str + payload_str
-
- with serial.Serial(port_path, port_baudrate, timeout=port_timeout_short_s) as port:
- port.write(request_str.encode('ascii'))
- response = port.read(2048)
- resp_json = json.loads(response[10:])
- status = resp_json['status']
- if status == 204:
- print(f'Request success')
- return True
- print(f'Request failed, status {status}')
- return False
+ return send_data(port_path, payload_str, 204)
def change_group(port_path: str, quote_group: str) -> bool:
uuid = get_new_uuid()
-
payload = {
'endpoint': endpoint_types['Quotes'],
'method': http_methods['PUT'],
@@ 141,25 162,11 @@ def change_group(port_path: str, quote_group: str) -> bool:
'group': quote_group
}
}
-
payload_str = json.dumps(payload)
- payload_len_str = str(len(payload_str)).rjust(payload_size_len, '0')
- request_str = payload_marker + payload_len_str + payload_str
-
- with serial.Serial(port_path, port_baudrate, timeout=port_timeout_short_s) as port:
- port.write(request_str.encode('ascii'))
- response = port.read(2048)
- resp_json = json.loads(response[10:])
- status = resp_json['status']
- if status == 200:
- print(f'Request success')
- return True
- print(f'Request failed, status {status}')
- return False
+ return send_data(port_path, payload_str, 200)
def change_interval(port_path: str, quote_interval: str) -> bool:
uuid = get_new_uuid()
-
payload = {
'endpoint': endpoint_types['Quotes'],
'method': http_methods['PUT'],
@@ 168,22 175,162 @@ def change_interval(port_path: str, quote_interval: str) -> bool:
'interval': quote_interval
}
}
+ payload_str = json.dumps(payload)
+ return send_data(port_path, payload_str, 200)
+
+def get_settings(port_path: str, settings: str) -> str:
+ uuid = get_new_uuid()
+ payload = {
+ 'endpoint': endpoint_types['Quotes'],
+ 'method': http_methods['GET'],
+ 'uuid': uuid,
+ 'body': {
+ 'settings': settings
+ }
+ }
+ payload_str = json.dumps(payload)
+ return get_str_data(port_path, payload_str, [200], settings)
+def start_sync(port_path: str) -> bool:
+ uuid = get_new_uuid()
+ payload = {
+ 'endpoint': endpoint_types['Backup'],
+ 'method': http_methods['POST'],
+ 'uuid': uuid,
+ 'body': {
+ "category" : "sync"
+ }
+ }
payload_str = json.dumps(payload)
- payload_len_str = str(len(payload_str)).rjust(payload_size_len, '0')
- request_str = payload_marker + payload_len_str + payload_str
+ return send_data(port_path, payload_str, 202)
- with serial.Serial(port_path, port_baudrate, timeout=port_timeout_short_s) as port:
- port.write(request_str.encode('ascii'))
- response = port.read(2048)
- resp_json = json.loads(response[10:])
- status = resp_json['status']
- if status == 200:
- print(f'Request success')
+def wait_for_sync_end(port_path: str, timeout: int) -> bool:
+ uuid = get_new_uuid()
+ payload = {
+ 'endpoint': endpoint_types['Backup'],
+ 'method': http_methods['GET'],
+ 'uuid': uuid,
+ 'body': {
+ "category" : "sync"
+ }
+ }
+ payload_str = json.dumps(payload)
+
+ start_timestamp = time.time()
+ while time.time() < start_timestamp + timeout:
+ status = get_str_data(port_path, payload_str, [204, 303], 'state')
+ print("sync status: " + status)
+ if status == "finished":
return True
- print(f'Request failed, status {status}')
+ time.sleep(1)
+
+ return False
+
+def download_file(port_path: str, path: str) -> bool:
+ uuid = get_new_uuid()
+ chunk_size = 0
+ file_size = 0
+
+ payload = {
+ 'endpoint': endpoint_types['FilesystemUpload'],
+ 'method': http_methods['GET'],
+ 'uuid': uuid,
+ 'body': {
+ 'fileName': path
+ }
+ }
+ payload_str = json.dumps(payload)
+
+ requestID = {
+ 'endpoint': endpoint_types['FilesystemUpload'],
+ 'method': http_methods['GET'],
+ 'uuid': uuid,
+ 'body': {
+ 'rxID': 0,
+ 'chunkNo': 1
+ }
+ }
+
+ response = get_request_response(port_path, payload_str, default_rx_data_size)
+ if not response:
+ print("Request GET file " + path + " info failed!")
+ return False
+
+ resp_json = json.loads(response[10:])
+ status = resp_json['status']
+ if status == 200:
+ requestID['body']['rxID'] = resp_json['body']['rxID']
+ chunk_size = resp_json['body']['chunkSize']
+ file_size = resp_json['body']['fileSize']
+ else:
+ print(f'Request failed, status: {status}')
return False
+ chunks = int((file_size / chunk_size) + 1)
+ print(f'File size: {file_size} chunk size: {chunk_size} chunks: {chunks}')
+
+ filename = "temp/" + sync_filename
+ os.makedirs(os.path.dirname(filename), exist_ok=True)
+ progress_bar = tqdm(desc=f'Downloading \'{path}\'', total=file_size, unit='bytes', unit_scale=True, unit_divisor=1024)
+ with open(filename, 'wb') as file:
+ for i in range(1, chunks + 1):
+ requestID_str = json.dumps(requestID)
+ response = get_request_response(port_path, requestID_str, chunk_rx_data_size)
+ if not response:
+ print("Request GET chunkNo: " + requestID['body']['chunkNo'] + " failed!")
+ return False
+
+ resp_json = json.loads(response[10:])
+ status = resp_json['status']
+ if status == 200:
+ data = base64.b64decode(resp_json['body']['data'])
+ file.write(data)
+ requestID['body']['chunkNo'] = i + 1
+ progress_bar.update(len(data))
+ else:
+ print(f'Request failed, status {status}')
+ progress_bar.close()
+ return False
+
+ progress_bar.close()
+ return True
+
+def delete_sync(port_path: str, path: str) -> bool:
+ uuid = get_new_uuid()
+ payload = {
+ 'endpoint': endpoint_types['FilesystemUpload'],
+ 'method': http_methods['DELETE'],
+ 'uuid': uuid,
+ 'body': {
+ "removeFile" : path
+ }
+ }
+ payload_str = json.dumps(payload)
+ return send_data(port_path, payload_str, 204)
+
+def get_quotes(port_path: str) -> bool:
+ if start_sync(port_path) == False:
+ print("Error! Synchronization has not been started.")
+ return False
+ print("Synchronization has started...")
+
+ if wait_for_sync_end(port_path, 20) == False:
+ print("Error! Synchronization fail.")
+ return False
+ print("Synchronization completed successfully.")
+
+ if download_file(port_path, sync_path) == False:
+ print("Error! Sync file download fail.")
+ return False
+ print("Sync file download completed.")
+
+ if delete_sync(port_path, sync_path) == False:
+ print("Error! Failed to delete sync file.")
+ return False
+ print("Sync file deletion completed successfully.")
+
+ return True
+
def main():
parser = argparse.ArgumentParser(
prog='custom_quotes',
@@ 215,14 362,17 @@ def main():
parser.add_argument('-i', '--interval',
metavar='quotes_display_interval',
help='quotes display interval [\'x\' minutes or \'AtMidnight\']')
+ parser.add_argument('-s', '--synchro',
+ metavar='settings_to_get',
+ help='get quotes file or settings [\'quotes\' or \'group\' or \'interval\']')
args = parser.parse_args()
if not args.port:
print('Invalid usage: please specify device port')
print('Run with -h to see help')
return
- if not args.add and not args.delete and not args.edit and not args.group and not args.interval:
- print('Invalid usage: please specify add, delete, edit, group or interval argument')
+ if not args.add and not args.delete and not args.edit and not args.group and not args.interval and not args.synchro:
+ print('Invalid usage: please specify add, delete, edit, synchro, group or interval argument')
print('Run with -h to see help')
return
if args.add:
@@ 250,6 400,19 @@ def main():
elif args.interval:
print("quotes interval: " + args.interval)
status = change_interval(args.port, args.interval)
+ elif args.synchro:
+ if args.synchro == "quotes":
+ print("downloading quotes file")
+ status = get_quotes(args.port)
+ elif args.synchro == "group":
+ group = get_settings(args.port, args.synchro)
+ print("quotes group: " + group)
+ elif args.synchro == "interval":
+ interval = get_settings(args.port, args.synchro)
+ print("quotes interval: " + interval)
+ else:
+ print('Invalid usage: please choose one option: \'quotes\' or \'group\' or \'interval\'')
+ print('Run with -h to see help')
if __name__ == '__main__':
main()