Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexandrePTJ committed May 22, 2024
2 parents 6d60ff2 + 3724698 commit 284d82f
Show file tree
Hide file tree
Showing 45 changed files with 1,375 additions and 502 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
strategy:
fail-fast: false
matrix:
qt_version: [6.5.1, 5.15.2]
qt_version: [6.7.0, 5.15.2]
steps:
- name: Checkout repo
uses: actions/checkout@v3
Expand Down Expand Up @@ -62,7 +62,7 @@ jobs:
artifacts: 'Kemai-*.AppImage'

WindowsJob:
name: Windows Qt-6.5.1
name: Windows Qt-6.7.0
runs-on: windows-latest
steps:
- name: Checkout repo
Expand All @@ -74,7 +74,7 @@ jobs:
- name: Install Qt
uses: jurplel/install-qt-action@v3
with:
version: '6.5.1'
version: '6.7.0'
tools: 'tools_opensslv3_x64'
cache: true
aqtversion: '==3.1.*'
Expand Down Expand Up @@ -104,7 +104,7 @@ jobs:
artifacts: 'cmake-build-release-win/Kemai-*.msi'

MacOSJob:
name: MacOS Qt-6.5.1
name: MacOS Qt-6.7.0
runs-on: macos-latest
strategy:
matrix:
Expand All @@ -119,7 +119,7 @@ jobs:
- name: Install Qt
uses: jurplel/install-qt-action@v3
with:
version: '6.5.1'
version: '6.7.0'
cache: true
aqtversion: '==3.1.*'

Expand Down
13 changes: 12 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]


## [0.11.0] - 2024-05-22

### Fixed
- Fix combo selection after model reset (Thanks to @virtulis)

## Added
- Template button to reload previous timesheet without starting it (Thanks to @poelzi)
- Allow usage of API Token for kimai>=2.14.0


## [0.10.0] - 2023-07-17

### Fixed
Expand Down Expand Up @@ -178,7 +188,8 @@ Special thanks to @shrippen for its support through [sponsorship](https://github
Initial version.


[Unreleased]: https://github.com/AlexandrePTJ/kemai/compare/0.10.0...HEAD
[Unreleased]: https://github.com/AlexandrePTJ/kemai/compare/0.11.0...HEAD
[0.11.0]: https://github.com/AlexandrePTJ/kemai/compare/0.10.0...0.11.0
[0.10.0]: https://github.com/AlexandrePTJ/kemai/compare/0.9.4...0.10.0
[0.9.4]: https://github.com/AlexandrePTJ/kemai/compare/0.9.3...0.9.4
[0.9.3]: https://github.com/AlexandrePTJ/kemai/compare/0.9.2...0.9.3
Expand Down
60 changes: 43 additions & 17 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.11)
project(KemaiProject VERSION 0.10.0 LANGUAGES CXX)
project(KemaiProject VERSION 0.11.0 LANGUAGES CXX)

# Point CMake to the custom modules
list(APPEND CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/cmake)
Expand All @@ -9,18 +9,38 @@ list(APPEND CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR})
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Add dependencies
include(FetchContent)
FetchContent_Declare(magic_enum
GIT_REPOSITORY https://github.com/Neargye/magic_enum.git
GIT_TAG v0.9.3)
FetchContent_Declare(spdlog
GIT_REPOSITORY https://github.com/gabime/spdlog.git
GIT_TAG v1.12.0)
FetchContent_Declare(range-v3
GIT_REPOSITORY https://github.com/ericniebler/range-v3.git
GIT_TAG 0.12.0)
FetchContent_MakeAvailable(magic_enum spdlog range-v3)
# Options
option(KEMAI_ENABLE_UPDATE_CHECK "Allow Kemai to check for update from Github releases" ON)
option(KEMAI_BUILD_LOCAL_DEPENDENCIES "Download and build dependencies (except Qt6)" ON)

# Install dependencies sources to build if required
if (KEMAI_BUILD_LOCAL_DEPENDENCIES)
set(SPDLOG_FMT_EXTERNAL ON)

include(FetchContent)
FetchContent_Declare(fmt
GIT_REPOSITORY https://github.com/fmtlib/fmt
GIT_TAG 10.2.1
OVERRIDE_FIND_PACKAGE)
FetchContent_Declare(magic_enum
GIT_REPOSITORY https://github.com/Neargye/magic_enum.git
GIT_TAG v0.9.5
OVERRIDE_FIND_PACKAGE)
FetchContent_Declare(spdlog
GIT_REPOSITORY https://github.com/gabime/spdlog.git
GIT_TAG v1.14.0
OVERRIDE_FIND_PACKAGE)
FetchContent_Declare(range-v3
GIT_REPOSITORY https://github.com/ericniebler/range-v3.git
GIT_TAG 0.12.0
OVERRIDE_FIND_PACKAGE)
endif (KEMAI_BUILD_LOCAL_DEPENDENCIES)

# Find external dependencies
find_package(fmt REQUIRED)
find_package(magic_enum REQUIRED)
find_package(spdlog REQUIRED)
find_package(range-v3 REQUIRED)

# Setup Qt
set(CMAKE_AUTOMOC ON)
Expand All @@ -47,9 +67,6 @@ set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH})

# Options
option(KEMAI_ENABLE_UPDATE_CHECK "Allow Kemai to check for update from Github releases" ON)

# OS Dependant options / configurations
if (WIN32)
# Hide console
Expand All @@ -76,17 +93,26 @@ elseif (APPLE)
# set(CMAKE_OSX_DEPLOYMENT_TARGET 10.12)
set(DEPLOY_DIR .)
set(CPACK_GENERATOR DragNDrop)
install(FILES LICENSE.txt DESTINATION ${DEPLOY_DIR})
else ()
include(GNUInstallDirs)
set(OS_BUNDLE)
set(DEPLOY_DIR bin)
# install(FILES share/kemai.desktop DESTINATION ${)
install(FILES share/kemai.desktop
DESTINATION ${CMAKE_INSTALL_DATADIR}/applications
)
install(FILES src/resources/icons/kimai.png
DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/256x256/apps/
)
install(FILES LICENSE.txt DESTINATION ${CMAKE_INSTALL_DOCDIR}/)
endif ()

# Project code
add_subdirectory(src)

# Install targets and files
install(TARGETS Kemai DESTINATION ${DEPLOY_DIR})
install(FILES LICENSE.txt DESTINATION ${DEPLOY_DIR})

if (WIN32)
windeployqt(Kemai ${DEPLOY_DIR})
Expand Down
4 changes: 2 additions & 2 deletions CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"name": "default-windows",
"hidden": true,
"cacheVariables": {
"CMAKE_PREFIX_PATH": "c:/Qt/6.5.1/msvc2019_64",
"CMAKE_PREFIX_PATH": "c:/Qt/6.7.0/msvc2019_64",
"OPENSSL_ROOT": "c:/Qt/Tools/OpenSSLv3/Win_x64",
"CMAKE_INSTALL_PREFIX": "dist"
}
Expand All @@ -30,7 +30,7 @@
"name": "default-macos",
"hidden": true,
"cacheVariables": {
"CMAKE_PREFIX_PATH": "$env{HOME}/Qt/6.5.1/macos",
"CMAKE_PREFIX_PATH": "$env{HOME}/Qt/6.7.0/macos",
"CMAKE_INSTALL_PREFIX": "dist"
}
},
Expand Down
38 changes: 32 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,35 @@
# Kemai, a Kimai Desktop Client


## Build Status

|Develop|Master|Translation|
|:--:|:--:|:--:|
|![Build status](https://github.com/AlexandrePTJ/kemai/actions/workflows/main.yml/badge.svg?branch=develop)|![Build status](https://github.com/AlexandrePTJ/kemai/actions/workflows/main.yml/badge.svg?branch=master)|[![Translation status](https://hosted.weblate.org/widgets/kemai/-/kemai/svg-badge.svg)](https://hosted.weblate.org/engage/kemai/)|

## How to use
## How to install

_Kemai_ connects to your _Kimai_ instance through its API. As credentials for API are not the same as login, here is how to create them:
Several methods to install _Kemai_ are available.

![API password](https://github.com/AlexandrePTJ/kemai/blob/master/docs/api_password.gif)

Then, you can set this credentials to _Kemai_ settings :
### From GitHub releases

Pre-build packages are available from [Releases](https://github.com/AlexandrePTJ/kemai/releases/latest). Just select the asset for your OS.

Binaries with `-NoUpdate` suffix will not automaticaly check for new update. Thoses binaries are intent to be use with OS specifics packages manager.


### From Homebrew (mac OS only)

A [Tap](https://github.com/AlexandrePTJ/homebrew-cask) repository is available to simplify _Kemai_ install through `brew`

```shell script
> brew tap alexandreptj/cask
> brew install kemai
```

![Kemai settings](https://github.com/AlexandrePTJ/kemai/blob/master/docs/kemai_settings.gif)

## How to build
### From source

_Kemai_ is Qt6 based application. It uses CMake to build. So regular cmake process will work.

Expand All @@ -25,6 +38,18 @@ _Kemai_ is Qt6 based application. It uses CMake to build. So regular cmake proce
> cmake --build build --config Release
```


## How to use

_Kemai_ connects to your _Kimai_ instance through its API. As credentials for API are not the same as login, here is how to create them:

![API password](https://github.com/AlexandrePTJ/kemai/blob/master/docs/api_password.gif)

Then, you can set this credentials to _Kemai_ settings :

![Kemai settings](https://github.com/AlexandrePTJ/kemai/blob/master/docs/kemai_settings.gif)


## How to help

Ideas, pull requests and translation are welcome.
Expand All @@ -33,6 +58,7 @@ For the later, [Weblate](https://hosted.weblate.org/engage/kemai/) is used. Here

[![Translation status](https://hosted.weblate.org/widgets/kemai/-/kemai/multi-auto.svg)](https://hosted.weblate.org/engage/kemai/)


## Why Kemai

Because "Il n'y a que Maille qui m'aille".
9 changes: 9 additions & 0 deletions share/kemai.desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[Desktop Entry]
Type=Application
Name=Kemai
Comment=Kimai timetracking frontend
TryExec=Kemai
Exec=Kemai
Terminal=false
Categories=Office;Utility;
Icon=kimai
6 changes: 6 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ set(SRCS
client/kimaiAPI.cpp
client/kimaiCache.cpp
client/kimaiClient.cpp
client/kimaiFeatures.cpp
client/kimaiReply.cpp
client/parser.cpp
context/kemaiSession.cpp
Expand Down Expand Up @@ -42,6 +43,7 @@ set(HDRS
client/kimaiCache.h
client/kimaiClient.h
client/kimaiClient_p.h
client/kimaiFeatures.h
client/kimaiReply.h
client/parser.h
context/kemaiSession.h
Expand All @@ -57,6 +59,7 @@ set(HDRS
gui/settingsDialog.h
gui/taskWidget.h
gui/timeSheetListWidgetItem.h
misc/customFmt.h
misc/dataReader.h
misc/helpers.h
models/kimaiDataListModel.h
Expand Down Expand Up @@ -92,6 +95,7 @@ set(KEMAI_TS_FILES
resources/l10n/kemai_el.ts
resources/l10n/kemai_fr.ts
resources/l10n/kemai_hr.ts
resources/l10n/kemai_hu.ts
resources/l10n/kemai_it.ts
resources/l10n/kemai_nb_NO.ts
resources/l10n/kemai_nl.ts
Expand All @@ -110,6 +114,8 @@ set(RESX
resources/kemai.qrc
${KEMAI_L10N_QRC})

qt_add_resources(${PROJECT_NAME} ${RESX})

# OS Specifics
if (WIN32)
list(APPEND SRCS
Expand Down
33 changes: 24 additions & 9 deletions src/client/kimaiClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,17 @@ QNetworkRequest KimaiClient::KimaiClientPrivate::prepareRequest(ApiMethod method
*/
QNetworkRequest networkRequest;
networkRequest.setUrl(url);
networkRequest.setRawHeader("X-AUTH-USER", username.toUtf8());
networkRequest.setRawHeader("X-AUTH-TOKEN", token.toUtf8());

// Until kimai 2.13, use username/password to identify. Use API Token from 2.14
if (apiToken.isEmpty())
{
networkRequest.setRawHeader("X-AUTH-USER", username.toUtf8());
networkRequest.setRawHeader("X-AUTH-TOKEN", token.toUtf8());
}
else
{
networkRequest.setRawHeader("Authorization", QString("Bearer %1").arg(apiToken).toLatin1());
}
networkRequest.setHeader(QNetworkRequest::UserAgentHeader, QString("%1/%2").arg(qApp->applicationName(), qApp->applicationVersion()));
networkRequest.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);
if (!data.isEmpty())
Expand All @@ -131,27 +140,27 @@ QNetworkRequest KimaiClient::KimaiClientPrivate::prepareRequest(ApiMethod method

QNetworkReply* KimaiClient::KimaiClientPrivate::sendGetRequest(const QNetworkRequest& networkRequest) const
{
spdlog::debug("[GET] {}", networkRequest.url().toString().toStdString());
spdlog::debug("[GET] {}", networkRequest.url().toString());
return networkAccessManager->get(networkRequest);
}

QNetworkReply* KimaiClient::KimaiClientPrivate::sendPostRequest(const QNetworkRequest& networkRequest, const QByteArray& data) const
{
spdlog::debug("[POST] {}", networkRequest.url().toString().toStdString());
spdlog::debug("[POST] {}", networkRequest.url().toString());
return networkAccessManager->post(networkRequest, data);
}

QNetworkReply* KimaiClient::KimaiClientPrivate::sendPatchRequest(const QNetworkRequest& networkRequest, const QByteArray& data) const
{
spdlog::debug("[PATCH] {}", networkRequest.url().toString().toStdString());
spdlog::debug("[PATCH] {}", networkRequest.url().toString());
return networkAccessManager->sendCustomRequest(networkRequest, "PATCH", data);
}

void KimaiClient::KimaiClientPrivate::onNamSslErrors(QNetworkReply* /*reply*/, const QList<QSslError>& errors)
{
for (const auto& error : errors)
{
spdlog::error("SSL Error: {}", error.errorString().toStdString());
spdlog::error("SSL Error: {}", error.errorString());
}

// Process certificate errors one by one.
Expand All @@ -171,14 +180,20 @@ void KimaiClient::setHost(const QString& host)
mD->host = host;
}

void KimaiClient::setUsername(const QString& username)
void KimaiClient::setLegacyAuth(const QString& username, const QString& token)
{
mD->username = username;
mD->token = token;
}

bool KimaiClient::isUsingLegacyAuth() const
{
return mD->apiToken.isEmpty();
}

void KimaiClient::setToken(const QString& token)
void KimaiClient::setAPIToken(const QString& token)
{
mD->token = token;
mD->apiToken = token;
}

VersionRequestResult KimaiClient::requestKimaiVersion()
Expand Down
7 changes: 5 additions & 2 deletions src/client/kimaiClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,11 @@ class KimaiClient : public QObject
~KimaiClient() override;

void setHost(const QString& host);
void setUsername(const QString& username);
void setToken(const QString& token);

void setLegacyAuth(const QString& username, const QString& token);
bool isUsingLegacyAuth() const;

void setAPIToken(const QString& token);

VersionRequestResult requestKimaiVersion();
MeRequestResult requestMeUserInfo();
Expand Down
Loading

0 comments on commit 284d82f

Please sign in to comment.