Commit 9ee4a1b7 authored by Vincent Pinon's avatar Vincent Pinon
Browse files

Apply !177: dependency change! Qt NetworkAuth instead of Qt WebEngine

parents c6adee5e c523ac4a
Pipeline #51098 canceled with stage
......@@ -52,7 +52,7 @@ find_package(KF5 REQUIRED COMPONENTS Archive Bookmarks CoreAddons Config ConfigW
# Qt
set(QT_MIN_VERSION 5.11.0)
find_package(Qt5 REQUIRED COMPONENTS Core DBus Widgets Svg Quick QuickControls2 Concurrent QuickWidgets Multimedia)
find_package(Qt5 REQUIRED COMPONENTS Core DBus Widgets Svg Quick QuickControls2 Concurrent QuickWidgets Multimedia NetworkAuth)
add_definitions(-DQT_NO_CAST_TO_ASCII -DQT_NO_URL_CAST_FROM_STRING)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
......
......@@ -7,6 +7,7 @@ add_subdirectory(scripts)
add_subdirectory(man)
add_subdirectory(titles)
add_subdirectory(profiles)
add_subdirectory(resourceproviders)
add_subdirectory(shortcuts)
install(FILES
......
INSTALL (FILES
archiveorg.json
freesound.json
pexels_photo.json
pexels_video.json
pixabay_photo.json
DESTINATION ${DATA_INSTALL_DIR}/kdenlive/resourceproviders)
# How To Write Provider Configurations
Intruction written 2021 by Julius Künzel as part of Kdenlive (www.kdenlive.org)
## Overview
Provider configuration files are json files.
Here is an example for [freesound](https://freesound.org)
```json
{
"name": "Freesound",
"homepage": "https://freesound.org",
"type": "sound",
"integration": "buildin",
"downloadOAuth2": true,
"clientkey": "1234",
"api": {
"root": "https://freesound.org/apiv2",
"oauth2": {
"authorizationUrl": "https://freesound.org/apiv2/oauth2/authorize/",
"accessTokenUrl": "https://freesound.org/apiv2/oauth2/access_token/",
"clientId": "9876"
},
"search": {
"req": {
"path": "/search/text/",
"method": "GET",
"params": [
{ "key": "format", "value": "json" },
{ "key": "fields", "value": "id,url,name,description,license,filesize,duration,username,download,previews,images,type" },
{ "key": "page_size", "value": "%perpage%" },
{ "key": "page", "value": "%pagenum%" },
{ "key": "query", "value": "%query%" },
{ "key": "token", "value": "%clientkey%" }
]
},
"res": {
"format": "json",
"resultCount":"count",
"list":"results",
"name":"name",
"filetype":"type",
"id":"id",
"url":"url",
"licenseUrl":"license",
"description": "description",
"author": "username",
"authorUrl": "$https://freesound.org/people/{username}",
"duration": "duration",
"filesize":"filesize",
"downloadUrl": "download",
"previewUrl": "previews.preview-hq-mp3",
"imageUrl": "images.waveform_m"
}
}
}
}
```
## Base Structure
Each provider config files should only specify a certain media type such as `video`. If the provider provids multiple types, create one config file for each.
| Key | Type | Required | Description |
| :------------- | :------------- | :------------- | :------------- |
| name | String | yes | Name of the provider (not translatable!!!) |
| homepage | String | yes | Url pointing to the providers webpage |
| type | String | yes | one of `video`, `image`, `music`, `sound` |
| integration | String | yes | Must be `buildin` as this is the only supported value at the moment |
| clientkey | String | If OAuth2 or `%clientkey%` is used | The client key to access the api. </br>*Kdenlive has some keys build in: `%pixabay_apikey%`, `%freesound_apikey%` and `%pexels_apikey%` will be replaced by a key for the certain provider.* |
| downloadOAuth2 | bool | no | Whether OAuth2 authentification is need to download files
| api | Object | yes | see [Api](#Api) |
## Api
The `api` object describs the api endpoints
| Key | Type | Required | Description |
| :------------- | :------------- | :------------- | :------------- |
| root | String | yes | The apis base url (should *not* end with `/`) |
| oauth2 | Object | If [`downloadOAuth2`](#Base-Structure) is `true` | See [OAuth2](#OAuth2) |
| search | Object | yes | See [Search](#Search) |
| downloadUrls | Object | yes | See [Fetch Download Urls](#Fetch-Download-Urls) |
### OAuth2
| Key | Type | Required | Description |
| :------------- | :------------- | :------------- | :------------- |
| authorizationUrl | String | yes | The url to authorize |
| accessTokenUrl | String | yes | The url to request an access token |
| clientId | String | yes | The clients id |
### Search
The `search` object should hold the two objects `req` and `res`.
#### Request
| Key | Type | Required | Description |
| :------------- | :------------- | :------------- | :------------- |
| path | String | yes | Path to the search endpoint (appended to [`root`](#Api), should start with `/`) |
| method | String | yes | HTTP method. Only `GET` is supported at the moment |
| params | Array of Objects | no | List of HTTP params |
| header | Array of Objects| no | List HTTP headers |
The objects in the arrays in `params` and `header` should contain two fields: `key` and `value`
#### Response
| Key | Type | Required | Description |
| :------------- | :------------- | :------------- | :------------- |
| format | String | yes | Format of the response. Only `json` is supported at the moment |
| resultCount | String | yes | Number of total result |
| list | String | | Name of the key containing the list holding the search results. All of the following fields are relative to a item of this list |
| name | String | no | The items name |
| filetype | String | no | The items filetype |
| id | String | yes | Name of the key in a list element holding the items id |
| url | String | | Url to the item to be opened in a external browser |
| licenseUrl | String | | Url to the license to be opened in a external browser. If you use a [template](#Templates), always use link to the english license version. Kdenlive can generate License names out of links to Creative Commons, Pexels and Pixabay Licenses for all other links the License name is "Unknown License". |
| description | String | no | Description of the item |
| author | String | no | Name of the items author |
| authorUrl | String | no | Link to the items authors page to be opened in a external browser |
| duration | String | no | Duration of the item (for video and audio)|
| width | String | no | Width of the item (for video and image) |
| height | String | no | Height of the item (for video and image) |
| downloadUrl | String | no, if `downloadUrls` or [Fetch Download Urls](#Fetch-Download-Urls) | To be used when there is only one download url (i.e. one file version) for the item |
| downloadUrls | Object | no, if `downloadUrl` or [Fetch Download Urls](#Fetch-Download-Urls) | To be used when there are multiple download url (i.e. one file version) for the item. See description in [table](#Mutliple-Download-Urls) below |
| previewUrl | String | no | Url to preview file of the item |
| imageUrl | String | no | Url to image thumb of the item (for audio e.g. album cover, for video a still)|
##### Mutliple Download Urls
| Key | Type | Required | Description |
| :------------- | :------------- | :------------- | :------------- |
| key | String | yes | Name of the key containing the list holding the files. The following fields are relative to a item of this list |
| url | String | yes | Name of the key in a list element holding the download url |
| name | String | yes | Label for the certain file verison |
###### Example
```json
"downloadUrls": {
"key": "video_files",
"url":"link",
"name":"${quality} {width}x{height}"
}
```
### Fetch Download Urls
Only necessary in special cases (e.g. https://archive.org) when no download urls are provided with the search response i.e. neither `downloadUrl` nor `downloadUrls` can be set in [Search `res`](#Response)
For the `req` object see the description of the [`req` obeject for `search`](#Request)
The `res` object should hold two fileds: `format` (same as in [search response](#Response)) and `downloadUrl` (same as in [search response](#Response)) or `downloadUrls`. The field `downloadUrls` is again similar to the one in [search response](#Response), but has some additional fields:
| Key | Type | Required | Description |
| :------------- | :------------- | :------------- | :------------- |
| isObject | Boolean | no | Whether the list not a normal array but a object and each subobject contains metadata about a file (e.g. `"files": { "file1": { "name": "&" }, "file2": { … }, …}`)|
| format | String | no | Format of the file |
If `isObject` is `true` there is a special case for `format`, `url` and `name`: if they have the value `&` (or `{&}` within a [template](#Templates)) it is replace by the key of the parent object. In the example in the table above this means `name` will be `file1`
#### Example
```json
"downloadUrls": {
"req": {
"path": "/details/%id%",
"method": "GET",
"params": [
{ "key": "output", "value": "json"}
]
},
"res": {
"format": "json",
"downloadUrls": {"key":"files", "isObject":true, "url":"$http://archive.org/download/%id%{&}", "format": "format", "name":"${source} {format} {width}x{height}"}
}
}
```
### Special Keys
Special keys are avaible for the following fields in [Search `res`](#Response): `author`, `authorUrl`, `name`, `filetype`, `description`, `id`, `url`, `licenseUrl`, `imageUrl`, `previewUrl`, `downloadUrl`, `downloadUrls.url` and `downloadUrls.name`.
In [`res` of Fetch Download Urls](#Fetch-Download-Urls) they are avaible for these fields: `downloadUrl`, `downloadUrls.format`,`downloadUrls.url` and `downloadUrls.name`
#### Placeholders
Placeholders are expressions that will be replaced by something.
For `params` and `header` these of placeholders are available.
| Placeholder | Replaced By | Hint |
| :------------- | :------------- | :------------- |
| %query% | The search query the user entered | Only for search |
| %pagenum% | Th number of the page to request results for | Only for search |
| %perpage% | Number of results that should be shown per page | |
| %shortlocale% | Short local like `en-US` (at the moment always `en-US`) | |
| %clientkey% | The clients apikey defined in [`clientkey`](#Base-Structure) | |
| %id% | Id of the item to fetch urls for | Only for Fetch Download Urls |
#### Templates
Templates must always start with `$`. Within a template string you can use keys like this `{username}`.
*NOTE: You can not use the general key like `author`. You must use the key of the response like `username` in the [example for freesound](#Overview)!*
##### Example
If your response looks like
```json
{
"results": [
{
"name": "example",
"files": [
{"picname": "nice-picture", "id": "1234"},
...
]
}
]
}
```
and your config like this
```json
{
...
"api": {
...
"search": {
...
"res" {
...
"downloadUrls": {
"key": "files",
"url":"$https://example.org/files/{picname}-{id}",
"name":"picname"
}
}
}
}
}
```
you will finally get `https://example.org/files/nice-picture-1234` as url.
{
"name": "Internet Archive Movies",
"homepage": "https://archive.org",
"description": "",
"type": "video",
"logoUrl":"",
"integration": "buildin",
"attributionHtml":"",
"apikey":"",
"api": {
"root": "https://archive.org",
"search": {
"req": {
"path": "/advancedsearch.php",
"method": "GET",
"params": [
{ "key": "rows", "value": "%perpage%" },
{ "key": "page", "value": "%pagenum%" },
{ "key": "output", "value": "json"},
{ "key": "fl[]", "value": "creator"},
{ "key": "fl[]", "value": "description"},
{ "key": "fl[]", "value": "identifier"},
{ "key": "fl[]", "value": "licenseurl"},
{ "key": "fl[]", "value": "title"},
{ "key": "q", "value": "(%query%)+AND+mediatype:(movies)" }
]
},
"res": {
"format": "json",
"resultCount":"response.numFound",
"list":"response.docs",
"name": "title",
"id":"identifier",
"url":"$http://archive.org/details/{identifier}",
"licenseUrl":"licenseurl",
"attributionText": "%generateDefault",
"description": "description",
"author": "creator",
"width": "width",
"height": "height",
"imageUrl": "image"
}
},
"downloadUrls": {
"req": {
"path": "/details/%id%",
"method": "GET",
"params": [
{ "key": "output", "value": "json"}
]
},
"res": {
"format": "json",
"downloadUrls": {"key":"files", "isObject":true, "url":"$http://archive.org/download/%id%{&}", "format": "format", "name":"${source} {format} {width}x{height}"}
}
}
}
}
{
"name": "Freesound",
"homepage": "https://freesound.org",
"type": "sound",
"integration": "buildin",
"downloadOAuth2": true,
"clientkey": "%freesound_apikey%",
"api": {
"root": "https://freesound.org/apiv2",
"oauth2": {
"authorizationUrl": "https://freesound.org/apiv2/oauth2/authorize/",
"accessTokenUrl": "https://freesound.org/apiv2/oauth2/access_token/",
"clientId": "fFo1lNyrTSJDp5PAGgKg"
},
"search": {
"req": {
"path": "/search/text/",
"method": "GET",
"params": [
{ "key": "format", "value": "json" },
{ "key": "fields", "value": "id,url,name,description,license,filesize,duration,username,download,previews,images,type" },
{ "key": "filter", "value": "license:(\"Attribution\"+OR+\"Creative+Commons+0\")"},
{ "key": "page_size", "value": "%perpage%" },
{ "key": "page", "value": "%pagenum%" },
{ "key": "query", "value": "%query%" },
{ "key": "token", "value": "%clientkey%" }
]
},
"res": {
"format": "json",
"resultCount":"count",
"list":"results",
"name":"name",
"filetype":"type",
"id":"id",
"url":"url",
"licenseUrl":"license",
"description": "description",
"author": "username",
"authorUrl": "$https://freesound.org/people/{username}",
"duration": "duration",
"filesize":"filesize",
"downloadUrl": "download",
"previewUrl": "previews.preview-hq-mp3",
"imageUrl": "images.waveform_m"
}
}
}
}
{
"name": "Pexels Photos",
"homepage": "https://pexels.com",
"type": "image",
"integration": "buildin",
"clientkey":"%pexels_apikey%",
"api": {
"root": "https://api.pexels.com/v1",
"search": {
"req": {
"path": "/search",
"method": "GET",
"header": [
{ "key": "Authorization", "value": "%clientkey%" }
],
"params": [
{ "key": "locale", "value": "%shortlocale%" },
{ "key": "per_page", "value": "%perpage%" },
{ "key": "page", "value": "%pagenum%" },
{ "key": "query", "value": "%query%" }
]
},
"res": {
"format": "json",
"resultCount":"total_results",
"list":"photos",
"id":"id",
"url":"url",
"licenseUrl":"$https://www.pexels.com/license/",
"author": "photographer",
"authorUrl": "photographer_url",
"width": "width",
"height": "height",
"downloadUrl": "src.original",
"imageUrl": "src.tiny"
}
}
}
}
{
"name": "Pexels Video",
"homepage": "https://pexels.com",
"type": "video",
"integration": "buildin",
"clientkey":"%pexels_apikey%",
"api": {
"root": "https://api.pexels.com/videos",
"search": {
"req": {
"path": "/search",
"method": "GET",
"header": [
{ "key": "Authorization", "value": "%clientkey%" }
],
"params": [
{ "key": "locale", "value": "%shortlocale%" },
{ "key": "per_page", "value": "%perpage%" },
{ "key": "page", "value": "%pagenum%" },
{ "key": "query", "value": "%query%" }
]
},
"res": {
"format": "json",
"resultCount":"total_results",
"list":"videos",
"id":"id",
"url":"url",
"licenseUrl":"$https://www.pexels.com/license/",
"author": "user.name",
"authorUrl": "user.url",
"width": "width",
"height": "height",
"duration": "duration",
"imageUrl": "image",
"downloadUrls": { "key": "video_files", "url":"link", "name":"${quality} {width}x{height}"}
}
}
}
}
{
"name": "Pixabay Photos",
"homepage": "https://pixabay.com/",
"type": "image",
"integration": "buildin",
"clientkey":"%pixabay_apikey%",
"api": {
"root": "https://pixabay.com/api/",
"search": {
"req": {
"path": "",
"method": "GET",
"params": [
{ "key": "per_page", "value": "%perpage%" },
{ "key": "page", "value": "%pagenum%" },
{ "key": "q", "value": "%query%" },
{ "key": "key", "value": "%clientkey%" }
]
},
"res": {
"format": "json",
"resultCount":"total",
"list":"hits",
"id":"id",
"url":"pageURL",
"licenseUrl":"$https://pixabay.com/service/license/",
"author": "user",
"authorUrl": "$https://pixabay.com/users/{user}-{user_id}/",
"width": "imageWidth",
"height": "imageHeight",
"downloadUrl": "largeImageURL",
"imageUrl": "previewURL"
}
}
}
}
......@@ -54,6 +54,7 @@ add_subdirectory(lib)
add_subdirectory(library)
add_subdirectory(mltcontroller)
add_subdirectory(monitor)
add_subdirectory(onlineresources)
add_subdirectory(profiles)
add_subdirectory(project)
add_subdirectory(qml)
......@@ -139,6 +140,7 @@ target_link_libraries(kdenliveLib
Qt5::QuickWidgets
Qt5::Concurrent
Qt5::Multimedia
Qt5::NetworkAuth
${OPENGL_LIBRARIES}
${OPENGLES_LIBRARIES}
${MLT_LIBRARIES}
......@@ -181,14 +183,6 @@ if(KF5_PURPOSE)
target_link_libraries(kdenliveLib KF5::Purpose KF5::PurposeWidgets)
endif()
if(Qt5WebEngineWidgets_FOUND)
message(STATUS "Found Qt5 WebEngineWidgets. You can use your Freesound.org credentials to download files")
target_compile_definitions(kdenliveLib PRIVATE -DQT5_USE_WEBENGINE)
target_link_libraries(kdenliveLib Qt5::WebEngineWidgets qt-oauth-lib)
else()
message(STATUS "Qt5 WebEngineWidgets not found. You cannot use your Freesound.org credentials, only preview files can be downloaded from the Online Resources Widget")
endif()
if(Q_WS_X11)
target_include_directories(kdenliveLib SYSTEM PRIVATE ${X11_Xlib_INCLUDE_PATH})
target_link_libraries(kdenliveLib ${X11_LIBRARIES})
......
<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
<kpartgui name="kdenlive" version="198" translationDomain="kdenlive">
<kpartgui name="kdenlive" version="199" translationDomain="kdenlive">
<MenuBar>
<Menu name="file" >
<Action name="file_save"/>
......@@ -24,7 +24,6 @@
<Action name="add_text_clip" />
<Action name="add_text_template_clip" />
<Action name="create_folder" />
<Action name="download_resource" />
<Menu name="generators" ><text>Generators</text>
</Menu>
<Menu name="subtitles" ><text>Subtitles</text>
......
add_subdirectory(kiss_fft)
add_subdirectory(media_ctrl)
add_subdirectory(qt-oauth-lib)
# Create a static library from oauth2
if(Qt5WebEngineWidgets_FOUND)
ki18n_wrap_ui(login_UI logindialog_ui.ui)
add_library(qt-oauth-lib STATIC oauth2.cpp logindialog.cpp ${login_UI})
target_link_libraries(qt-oauth-lib Qt5::WebEngineWidgets KF5::I18n KF5::ConfigGui)
target_compile_definitions(qt-oauth-lib PRIVATE -DQT5_USE_WEBENGINE)
endif()
/********************************************************************************************************
* Copyright (C) 2015 Roger Morton (ttguy1@gmail.com)
*
* Purpose: implements client access to freesound.org using ver2 of the freesound API.
*
* Based on code at https://code.google.com/p/qt-oauth-lib/
* Which is Qt Library created by Integrated Computer Solutions, Inc. (ICS)
* to provide OAuth2.0 for the Google API.
*
* Licence: GNU Lesser General Public License
* http://www.gnu.org/licenses/lgpl.html
* This version of the GNU Lesser General Public License incorporates the terms
* and conditions of version 3 of the GNU General Public License http://www.gnu.org/licenses/gpl-3.0-standalone.html
* supplemented by the additional permissions listed at http://www.gnu.org/licenses/lgpl.html
*
* Disclaimer of Warranty.
* THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
* EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE
* THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.
* SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR
* OR CORRECTION.
*
* Limitation of Liability.
* IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER,
* OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO
* YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
* OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR
* DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF
* THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*********************************************************************************************************/
#include "logindialog.h"
#include "ui_logindialog_ui.h"
#include <QWebEngineView>
LoginDialog::LoginDialog(QWidget *parent)
: QDialog(parent)
, m_ui(new Ui::LoginDialog)
{
m_ui->setupUi(this);
setAttribute(Qt::WA_DeleteOnClose);
setWindowTitle(i18n("Freesound Login"));
connect(m_ui->CancelButton, &Q