diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..e5e8ccc2 --- /dev/null +++ b/.clang-format @@ -0,0 +1,2 @@ +Language: Cpp +BasedOnStyle: Mozilla diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 00000000..42e4670c --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,6 @@ + +--- +Checks: '*,-fuchsia-*,-google-*,-zircon-*,-abseil-*,-modernize-use-trailing-return-type,-llvm-*' +WarningsAsErrors: '*' +HeaderFilterRegex: '' +FormatStyle: none \ No newline at end of file diff --git a/.cmake-format.yaml b/.cmake-format.yaml new file mode 100644 index 00000000..e7be3399 --- /dev/null +++ b/.cmake-format.yaml @@ -0,0 +1,18 @@ +additional_commands: + foo: + flags: + - BAR + - BAZ + kwargs: + DEPENDS: '*' + HEADERS: '*' + SOURCES: '*' +bullet_char: '*' +dangle_parens: false +enum_char: . +line_ending: unix +line_width: 120 +max_pargs_hwrap: 3 +separate_ctrl_name_with_space: false +separate_fn_name_with_space: false +tab_size: 2 \ No newline at end of file diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml new file mode 100644 index 00000000..f6d9f64b --- /dev/null +++ b/.github/workflows/build_cmake.yml @@ -0,0 +1,67 @@ +name: CMake + +on: [push, pull_request] + +env: + # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) + BUILD_TYPE: RelWithDebInfo + +jobs: + build: + + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest] + + steps: + - uses: actions/checkout@v2 + + - name: Install Dependencies + run: | + sudo apt-get -y -qq update + sudo apt-get -y --no-install-recommends install \ + cmake \ + extra-cmake-modules \ + build-essential \ + qt5-default \ + qt5-qmake \ + qttools5-dev-tools \ + qttools5-dev \ + libqt5dbus5 \ + libqt5network5 \ + libqt5core5a \ + libqt5widgets5 \ + libqt5gui5 \ + libqt5svg5-dev + + - name: Create Build Environment + # Some projects don't allow in-source building, so create a separate build directory + # We'll use this as our working directory for all subsequent commands + run: cmake -E make_directory ${{runner.workspace}}/build + + - name: Configure CMake + # Use a bash shell so we can use the same syntax for environment variable + # access regardless of the host operating system + shell: bash + working-directory: ${{runner.workspace}}/build + # Note the current convention is to use the -S and -B options here to specify source + # and build directories, but this is only available with CMake 3.13 and higher. + # The CMake binaries on the Github Actions machines are (as of this writing) 3.12 + # + # We need to source the profile file to make sure conan is in PATH + run: | + cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE + - name: Build + working-directory: ${{runner.workspace}}/build + shell: bash + # Execute the build. You can specify a specific target with "--target " + run: cmake --build . --config $BUILD_TYPE + + - name: Test + working-directory: ${{runner.workspace}}/build + shell: bash + # Execute tests defined by the CMake configuration. + # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail + run: ctest -C $BUILD_TYPE + diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml new file mode 100644 index 00000000..2b5c36e1 --- /dev/null +++ b/.github/workflows/clang-format.yml @@ -0,0 +1,17 @@ +name: test-clang-format + +on: [push, pull_request] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - uses: DoozyX/clang-format-lint-action@v0.9 + with: + source: './src' + #exclude: './third_party ./external' + extensions: 'h,cpp' + clangFormatVersion: 11 + style: mozilla diff --git a/.gitignore b/.gitignore index a886f32c..b212b0c3 100644 --- a/.gitignore +++ b/.gitignore @@ -49,5 +49,10 @@ stage/ .snapcraft/ flameshot*.tar.bz2 +.vscode/ +build/ +data/flatpak/.flatpak-builder +# NVIM +*~ # End of https://www.gitignore.io/api/snapcraft diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 9d4c8f5e..00000000 --- a/.travis.yml +++ /dev/null @@ -1,98 +0,0 @@ -dist: xenial -sudo: required - -language: cpp - -branches: - only: - - master - -cache: - directories: - - $HOME/.cache - -env: - global: - # Environment variables for packaging - - PRODUCT=flameshot - - VERSION=0.6.0 - - RELEASE=1 - - ARCH=x86_64 - # Dockerfile from https://github.com/flameshotapp/flameshot-docker-images - - DOCKER_REPO=vitzy/flameshot - # Option: wetransfer.com, file.io, 0x0.st, transfer.sh - - UPLOAD_SERVICE=wetransfer.com - -# The actual list of distribution is available on -# https://hub.docker.com/r/vitzy/flameshot/tags/ -matrix: - include: - - os: linux - # 28 - env: OS=fedora DIST=28 EXTEN=rpm - services: docker - - os: linux - # 29 - env: OS=fedora DIST=29 EXTEN=rpm - services: docker - - os: linux - # 30 - env: OS=fedora DIST=30 EXTEN=rpm - services: docker - - os: linux - # 16.04 LTS - env: OS=ubuntu DIST=xenial EXTEN=deb - services: docker - - os: linux - # 18.04 LTS - env: OS=ubuntu DIST=bionic EXTEN=deb - services: docker - - os: linux - # 19.04 - env: OS=ubuntu DIST=disco EXTEN=deb - services: docker - - os: linux - # 8 - env: OS=debian DIST=jessie EXTEN=deb - services: docker - - os: linux - # 9 - env: OS=debian DIST=stretch EXTEN=deb - services: docker - - os: linux - # No docker environment, just for CI build & test - # ubuntu xenial; default Qt version is 5.6.1 - env: OS=ubuntu DIST=xenial EXTEN=other -# - os: osx -# compiler: clang -# osx_image: xcode9.2 - -before_install: - - export ROOT_PATH="$(pwd)" - - chmod +x .travis/*.sh - - chmod +x .travis/services/*.sh - - if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then source .travis/linux_before_install.sh; fi - -install: - - if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then source .travis/linux_install.sh; fi - -script: -# - git submodule update --init --recursive -# - git describe --long - - if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then source .travis/linux_script.sh; fi -# - if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then source .travis/osx_script.sh; fi - -after_success: - - if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then source .travis/linux_after_success.sh; fi - - echo "Download URL is $TEMP_DOWNLOAD_URL ." - -# deploy: -# # Deploy packages to Github Release -# provider: releases -# api_key: "GITHUB ENCYPTED OAUTH TOKEN" -# file_glob: true -# file: dist/*.{deb,rpm,AppImage,dmg} -# skip_cleanup: true -# on: -# tags: true -# branch: master diff --git a/.travis/linux_after_success.sh b/.travis/linux_after_success.sh deleted file mode 100644 index 8d101d33..00000000 --- a/.travis/linux_after_success.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash -- - -set -e - -DIST_PATH=dist - -if [[ "${EXTEN}" == "other" ]]; then - cp "${BUILD_DST_PATH}/flameshot" "${ROOT_PATH}/.travis/services/flameshot_${VERSION}_${ARCH}" - cd "${ROOT_PATH}/.travis/services" - TEMP_DOWNLOAD_URL=$(travis_retry bash \ - "${ROOT_PATH}/.travis/services/${UPLOAD_SERVICE}.sh" \ - flameshot_"${VERSION}_${ARCH}") -else - case "${OS}" in - "ubuntu"|"debian") - cp "${DIST_PATH}/flameshot_${VERSION}_${DIST}_${ARCH}.${EXTEN}" "${ROOT_PATH}/.travis/services/flameshot_${VERSION}_${DIST}_${ARCH}.${EXTEN}" - cd "${ROOT_PATH}/.travis/services" - TEMP_DOWNLOAD_URL=$(travis_retry bash \ - "${ROOT_PATH}/.travis/services/${UPLOAD_SERVICE}.sh" \ - "flameshot_${VERSION}_${DIST}_${ARCH}.${EXTEN}") - ;; - "fedora") - cp "${DIST_PATH}/flameshot_${VERSION}_fedora${DIST}_${ARCH}.${EXTEN}" "${ROOT_PATH}/.travis/services/flameshot_${VERSION}_fedora${DIST}_${ARCH}.${EXTEN}" - cd "${ROOT_PATH}/.travis/services" - TEMP_DOWNLOAD_URL=$(travis_retry bash \ - "${ROOT_PATH}/.travis/services/${UPLOAD_SERVICE}.sh" \ - "flameshot_${VERSION}_fedora${DIST}_${ARCH}.${EXTEN}") - ;; - esac -fi - diff --git a/.travis/linux_before_install.sh b/.travis/linux_before_install.sh deleted file mode 100644 index 68e6cc53..00000000 --- a/.travis/linux_before_install.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash -- - -set -e - -if [[ "${EXTEN}" == "other" ]]; then - travis_retry sudo apt update -fi diff --git a/.travis/linux_install.sh b/.travis/linux_install.sh deleted file mode 100644 index f0006ea1..00000000 --- a/.travis/linux_install.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash -- - -set -e - -if [[ "${EXTEN}" == "other" ]]; then - # Compile-time - travis_retry sudo apt install -y gcc g++ build-essential qt5-default qt5-qmake qttools5-dev-tools - # Run-time - travis_retry sudo apt install -y libqt5dbus5 libqt5network5 libqt5core5a libqt5widgets5 libqt5gui5 libqt5svg5-dev - # Optional - travis_retry sudo apt install -y openssl ca-certificates - # Install fcitx-frontend-qt5 - travis_retry sudo apt install -y fcitx-frontend-qt5 - -fi diff --git a/.travis/linux_script.sh b/.travis/linux_script.sh deleted file mode 100644 index 8b1b29a2..00000000 --- a/.travis/linux_script.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/bash -- - -set -e - -DIST_PATH=dist - -if [[ ! -d "${DIST_PATH}" ]]; then - mkdir "${DIST_PATH}" -fi - -if [[ "${EXTEN}" == "other" ]]; then - project_dir="$(pwd)" - BUILD_DST_PATH=build-test - - qmake --version - mkdir "${BUILD_DST_PATH}" - qmake -makefile DESTDIR="${BUILD_DST_PATH}" "${project_dir}"/flameshot.pro - # Building flameshot - make -j$(nproc) - # Running flameshot tests - make check -j$(nproc) - ls -alhR - -else - travis_retry git clone https://github.com/flameshotapp/packpack.git - travis_retry packpack/packpack - pwd && ls - - case "${OS}" in - "ubuntu"|"debian") - # copy deb to dist path for distribution - cp \ - build/flameshot_*_*.deb \ - "${DIST_PATH}"/flameshot_${VERSION}_${DIST}_${ARCH}.${EXTEN} - ;; - "fedora") - cp \ - build/flameshot-${VERSION}-${RELEASE}.*.${ARCH}.rpm \ - "${DIST_PATH}"/flameshot_${VERSION}_fedora${DIST}_${ARCH}.${EXTEN} - ;; - esac -fi diff --git a/.travis/osx_script.sh b/.travis/osx_script.sh deleted file mode 100644 index 49bf68af..00000000 --- a/.travis/osx_script.sh +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/bash -- - -set -e - -project_dir="$(pwd)" - -brew update > /dev/null -brew install qt -QTDIR=/usr/local/opt/qt -PATH="${QTDIR}"/bin:"${PATH}" -LDFLAGS=-L"${QTDIR}"/lib -CPPFLAGS=-I"${QTDIR}"/include - -# Build your app -cd "${project_dir}" -mkdir dist -mkdir build -cd build -qmake -version -qmake CONFIG-=debug CONFIG+=release CONFIG+=packaging ../flameshot.pro -make -j$(nproc) - -git clone https://github.com/aurelien-rainone/macdeployqtfix.git -pwd -ls - -ls /Users/travis/build/ZetaoYang/flameshot - -# Package DMG from build/flamshot.app directory -"${QTDIR}"/bin/macdeployqt flameshot.app -python \ - "${project_dir}"/build/macdeployqtfix/macdeployqtfix.py \ - flameshot.app/Contents/MacOS/flameshot \ - "${QTDIR}" - -cd "${project_dir}"/build -mkdir -p distrib/Flameshot -cd distrib/Flameshot -mv "${project_dir}"/build/flameshot.app "${project_dir}"/build/distrib/Flameshot/ -cp "${project_dir}"/LICENSE LICENSE -cp "${project_dir}"/README.md README.md -echo "${VERSION}" > version -echo "${TRAVIS_COMMIT}" >> version - -ln -s /Applications ./Applications - -cd .. -hdiutil create -srcfolder ./Flameshot -format UDBZ ./flameshot.dmg -mv flameshot.dmg flameshot_X64_${VERSION}.dmg -mv flameshot_X64_${VERSION}.dmg "${project_dir}"/dist/flameshot_X64_$VERSION.dmg -TEMP_DOWNLOAD_URL=$(curl \ - --upload-file \ - flameshot_X64_$VERSION.dmg \ - "https://transfer.sh/flameshot_X64_$VERSION.dmg") -cd .. diff --git a/.travis/services/0x0.st.sh b/.travis/services/0x0.st.sh deleted file mode 100644 index c2f5ad09..00000000 --- a/.travis/services/0x0.st.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh -#=============================================================== -# File URLs are valid for at least 30 days and up to a year (see below). -# Shortened URLs do not expire. -# Maximum file size: 512.0 MiB -# Blocked file types: application/x-dosexec, application/x-executable -#=============================================================== - -URL="https://0x0.st" - -if [ $# -eq 0 ]; then - echo "Usage: 0x0.st FILE\n" - exit 1 -fi - -FILE=$1 - -if [ ! -f "$FILE" ]; then - echo "File ${FILE} not found" - exit 1 -fi - -RESPONSE=$(curl -# -F "file=@${FILE}" "${URL}") - -echo "${RESPONSE}" # to terminal diff --git a/.travis/services/file.io.sh b/.travis/services/file.io.sh deleted file mode 100644 index ec55d921..00000000 --- a/.travis/services/file.io.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/sh - -#========================================== -# 100 uploads per day, 5GB file size limit for FREE plan. -#========================================== - -URL="https://file.io" -DEFAULT_EXPIRE="14d" # Default to 14 days - -if [ $# -eq 0 ]; then - echo "Usage: file.io FILE [DURATION]\n" - echo "Example: file.io path/to/my/file 1w\n" - exit 1 -fi - -FILE=$1 -EXPIRE=${2:-$DEFAULT_EXPIRE} - -if [ ! -f "$FILE" ]; then - echo "File ${FILE} not found" - exit 1 -fi - -RESPONSE=$(curl -# -F "file=@${FILE}" "${URL}/?expires=${EXPIRE}") - -echo "${RESPONSE}" # to terminal diff --git a/.travis/services/transfer.sh.sh b/.travis/services/transfer.sh.sh deleted file mode 100644 index 082ac8c4..00000000 --- a/.travis/services/transfer.sh.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh - -URL="https://transfer.sh" - -if [ $# -eq 0 ]; then - echo "Usage: transfer.sh FILE\n" - exit 1 -fi - -FILE=$1 - -if [ ! -f "$FILE" ]; then - echo "File ${FILE} not found" - exit 1 -fi - -RESPONSE=$(curl -# -F "file=@${FILE}" "${URL}") - -echo "${RESPONSE}" # to terminal \ No newline at end of file diff --git a/.travis/services/transferwee.py b/.travis/services/transferwee.py deleted file mode 100755 index 3bf4fc30..00000000 --- a/.travis/services/transferwee.py +++ /dev/null @@ -1,330 +0,0 @@ -#!/usr/bin/env python3.7 - -# -# Copyright (c) 2018-2019 Leonardo Taccari -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS -# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - - -""" -Download/upload files via wetransfer.com - -transferwee is a script/module to download/upload files via wetransfer.com. - -It exposes `download' and `upload' subcommands, respectively used to download -files from a `we.tl' or `wetransfer.com/downloads' URLs and upload files that -will be shared via emails or link. -""" - - -from typing import List -import os.path -import urllib.parse -import zlib - -import requests - - -WETRANSFER_API_URL = 'https://wetransfer.com/api/v4/transfers' -WETRANSFER_DOWNLOAD_URL = WETRANSFER_API_URL + '/{transfer_id}/download' -WETRANSFER_UPLOAD_EMAIL_URL = WETRANSFER_API_URL + '/email' -WETRANSFER_UPLOAD_LINK_URL = WETRANSFER_API_URL + '/link' -WETRANSFER_FILES_URL = WETRANSFER_API_URL + '/{transfer_id}/files' -WETRANSFER_PART_PUT_URL = WETRANSFER_FILES_URL + '/{file_id}/part-put-url' -WETRANSFER_FINALIZE_MPP_URL = WETRANSFER_FILES_URL + '/{file_id}/finalize-mpp' -WETRANSFER_FINALIZE_URL = WETRANSFER_API_URL + '/{transfer_id}/finalize' - -WETRANSFER_DEFAULT_CHUNK_SIZE = 5242880 - - -def download_url(url: str) -> str: - """Given a wetransfer.com download URL download return the downloadable URL. - - The URL should be of the form `https://we.tl/' or - `https://wetransfer.com/downloads/'. If it is a short URL (i.e. `we.tl') - the redirect is followed in order to retrieve the corresponding - `wetransfer.com/downloads/' URL. - - The following type of URLs are supported: - - `https://we.tl/`: - received via link upload, via email to the sender and printed by - `upload` action - - `https://wetransfer.com//`: - directly not shared in any ways but the short URLs actually redirect to - them - - `https://wetransfer.com///`: - received via email by recipients when the files are shared via email - upload - - Return the download URL (AKA `direct_link') as a str or None if the URL - could not be parsed. - """ - # Follow the redirect if we have a short URL - if url.startswith('https://we.tl/'): - r = requests.head(url, allow_redirects=True) - url = r.url - - recipient_id = None - params = url.replace('https://wetransfer.com/downloads/', '').split('/') - - if len(params) == 2: - transfer_id, security_hash = params - elif len(params) == 3: - transfer_id, recipient_id, security_hash = params - else: - return None - - j = { - "security_hash": security_hash, - } - if recipient_id: - j["recipient_id"] = recipient_id - r = requests.post(WETRANSFER_DOWNLOAD_URL.format(transfer_id=transfer_id), - json=j) - - j = r.json() - return j.get('direct_link') - - -def download(url: str) -> None: - """Given a `we.tl/' or `wetransfer.com/downloads/' download it. - - First a direct link is retrieved (via download_url()), the filename will - be extracted to it and it will be fetched and stored on the current - working directory. - """ - dl_url = download_url(url) - file = urllib.parse.urlparse(dl_url).path.split('/')[-1] - - r = requests.get(dl_url, stream=True) - with open(file, 'wb') as f: - for chunk in r.iter_content(chunk_size=1024): - f.write(chunk) - - -def _file_name_and_size(file: str) -> dict: - """Given a file, prepare the "name" and "size" dictionary. - - Return a dictionary with "name" and "size" keys. - """ - filename = os.path.basename(file) - filesize = os.path.getsize(file) - - return { - "name": filename, - "size": filesize - } - - -def _prepare_email_upload(filenames: List[str], message: str, - sender: str, recipients: List[str]) -> str: - """Given a list of filenames, message a sender and recipients prepare for - the email upload. - - Return the parsed JSON response. - """ - j = { - "files": [_file_name_and_size(f) for f in filenames], - "from": sender, - "message": message, - "recipients": recipients, - "ui_language": "en", - } - - r = requests.post(WETRANSFER_UPLOAD_EMAIL_URL, json=j) - return r.json() - - -def _prepare_link_upload(filenames: List[str], message: str) -> str: - """Given a list of filenames and a message prepare for the link upload. - - Return the parsed JSON response. - """ - j = { - "files": [_file_name_and_size(f) for f in filenames], - "message": message, - "ui_language": "en", - } - - r = requests.post(WETRANSFER_UPLOAD_LINK_URL, json=j) - return r.json() - - -def _prepare_file_upload(transfer_id: str, file: str) -> str: - """Given a transfer_id and file prepare it for the upload. - - Return the parsed JSON response. - """ - j = _file_name_and_size(file) - r = requests.post(WETRANSFER_FILES_URL.format(transfer_id=transfer_id), - json=j) - return r.json() - - -def _upload_chunks(transfer_id: str, file_id: str, file: str, - default_chunk_size: int = WETRANSFER_DEFAULT_CHUNK_SIZE) -> str: - """Given a transfer_id, file_id and file upload it. - - Return the parsed JSON response. - """ - f = open(file, 'rb') - - chunk_number = 0 - while True: - chunk = f.read(default_chunk_size) - chunk_size = len(chunk) - if chunk_size == 0: - break - chunk_number += 1 - - j = { - "chunk_crc": zlib.crc32(chunk), - "chunk_number": chunk_number, - "chunk_size": chunk_size, - "retries": 0 - } - - r = requests.post( - WETRANSFER_PART_PUT_URL.format(transfer_id=transfer_id, - file_id=file_id), - json=j) - url = r.json().get('url') - r = requests.options(url, - headers={ - 'Origin': 'https://wetransfer.com', - 'Access-Control-Request-Method': 'PUT', - }) - r = requests.put(url, data=chunk) - - j = { - 'chunk_count': chunk_number - } - r = requests.put( - WETRANSFER_FINALIZE_MPP_URL.format(transfer_id=transfer_id, - file_id=file_id), - json=j) - - return r.json() - - -def _finalize_upload(transfer_id: str) -> str: - """Given a transfer_id finalize the upload. - - Return the parsed JSON response. - """ - r = requests.put(WETRANSFER_FINALIZE_URL.format(transfer_id=transfer_id)) - - return r.json() - - -def upload(files: List[str], message: str = '', sender: str = None, - recipients: List[str] = []) -> str: - """Given a list of files upload them and return the corresponding URL. - - Also accepts optional parameters: - - `message': message used as a description of the transfer - - `sender': email address used to receive an ACK if the upload is - successfull. For every download by the recipients an email - will be also sent - - `recipients': list of email addresses of recipients. When the upload - succeed every recipients will receive an email with a link - - If both sender and recipient parameters are passed the email upload will be - used. Otherwise, the link upload will be used. - - Return the short URL of the transfer on success. - """ - - # Check that all files exists - for f in files: - if not os.path.exists(f): - return None - - # Check that there are no duplicates filenames - # (despite possible different dirname()) - filenames = [os.path.basename(f) for f in files] - if len(files) != len(set(filenames)): - return None - - transfer_id = None - if sender and recipients: - # email upload - transfer_id = \ - _prepare_email_upload(filenames, message, sender, recipients)['id'] - else: - # link upload - transfer_id = _prepare_link_upload(filenames, message)['id'] - - for f in files: - file_id = _prepare_file_upload(transfer_id, os.path.basename(f))['id'] - _upload_chunks(transfer_id, file_id, f) - - return _finalize_upload(transfer_id)['shortened_url'] - - -if __name__ == '__main__': - import argparse - - ap = argparse.ArgumentParser( - prog='transferwee', - description='Download/upload files via wetransfer.com' - ) - sp = ap.add_subparsers(dest='action', help='action') - - # download subcommand - dp = sp.add_parser('download', help='download files') - dp.add_argument('-g', action='store_true', - help='only print the direct link (without downloading it)') - dp.add_argument('url', nargs='+', type=str, metavar='url', - help='URL (we.tl/... or wetransfer.com/downloads/...)') - - # upload subcommand - up = sp.add_parser('upload', help='upload files') - up.add_argument('-m', type=str, default='', metavar='message', - help='message description for the transfer') - up.add_argument('-f', type=str, metavar='from', help='sender email') - up.add_argument('-t', nargs='+', type=str, metavar='to', - help='recipient emails') - up.add_argument('files', nargs='+', type=str, metavar='file', - help='files to upload') - - args = ap.parse_args() - - if args.action == 'download': - if args.g: - for u in args.url: - print(download_url(u)) - else: - for u in args.url: - download(u) - exit(0) - - if args.action == 'upload': - print(upload(args.files, args.m, args.f, args.t)) - exit(0) - - # No action selected, print help message - ap.print_help() - exit(1) diff --git a/.travis/services/wetransfer.com.sh b/.travis/services/wetransfer.com.sh deleted file mode 100755 index e730f46d..00000000 --- a/.travis/services/wetransfer.com.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh -#========================================================================================================================= -# WeTransfer is a service to send big or small files from A to B. -# It can transfer any type of file - such as presentations, photos, videos, music or documents - to friends and colleagues. -# You can send files up to 2 GB and they will be available for 7 days, with no registration. - -# API doc: https://developers.wetransfer.com/documentation -# Using transferwee.py: https://github.com/iamleot/transferwee -#========================================================================================================================= - -if [ $# -eq 0 ]; then - echo "Usage: python3 transferwee.py FILE\n" - exit 1 -fi - -FILE=$1 - -if [ ! -f "$FILE" ]; then - echo "File ${FILE} not found" - exit 1 -fi - -RESPONSE=$(python3 transferwee.py upload "${FILE}") - -echo "${RESPONSE}" # to terminal diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..6a307a5e --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,26 @@ +cmake_minimum_required(VERSION 3.13) +#cmake_policy(SET CMP0076 OLD) + +project( + flameshot + VERSION 0.8.0 + LANGUAGES CXX) + +include(cmake/StandardProjectSettings.cmake) + +add_library(project_options INTERFACE) +target_compile_features(project_options INTERFACE cxx_std_17) + +add_library(project_warnings INTERFACE) + +# standard compiler warnings +include(cmake/CompilerWarnings.cmake) +# set_project_warnings(project_warnings) + +# sanitizer options if supported by compiler +include(cmake/Sanitizers.cmake) +# enable_sanitizers(project_options) + +# allow for static analysis options include(cmake/StaticAnalyzers.cmake) + +add_subdirectory(src) diff --git a/README.md b/README.md index 3ddaaae6..c1b2d0d6 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@

- - Flameshot + + Flameshot
Flameshot @@ -16,14 +16,14 @@ Windows Build Status - - Latest Stable Release + + Latest Stable Release - - Total Downloads + + Total Downloads - - License + + License Docs @@ -74,6 +74,9 @@ ## Usage +Execute the command `flameshot` without parameters to launch a running instance of the program without taking actions. +Also adds a tray icon for configuration and management. + Example commands: - Capture with GUI: @@ -88,7 +91,7 @@ Example commands: flameshot gui -p ~/myStuff/captures ``` -- Open GUI with a delay of 2 seconds: +- Capture with GUI after 2 seconds delay (can be useful to take screenshots of mouse hover tooltips, etc.): ```shell flameshot gui -d 2000 @@ -196,7 +199,7 @@ Steps for using the configuration: ```shell cd ~/Desktop - wget https://raw.githubusercontent.com/lupoDharkael/flameshot/master/docs/shortcuts-config/flameshot-shortcuts-kde + wget https://raw.githubusercontent.com/flameshot-org/flameshot/master/docs/shortcuts-config/flameshot-shortcuts-kde ``` 3. Go to _System Settings_ → _Shortcuts_ → _Custom Shortcuts_. 4. If there's one, you'll need to disable an entry for Spectacle, the default KDE screenshot utility first because its shortcuts might collide with Flameshot's ones; so, just uncheck the _Spectacle_ entry. @@ -214,8 +217,6 @@ Steps for using the configuration: - Press Enter or Ctrl + C when you are in a capture mode and you don't have an active selection and the whole desktop will be copied to your clipboard! Pressing Ctrl + S will save your capture in a file! Check the [Shortcuts](#shortcuts) for more information. -- Execute the command `flameshot` without parameters to launch a running instance of the program without taking actions. - ## Installation There are packages available for a few distros: @@ -251,9 +252,9 @@ Also you can open and build/debug the project in a C++ IDE. For example, in Qt C #### Compile-time -- Qt >= 5.3 +- Qt >= 5.9 + Development tools -- GCC >= 4.9.2 +- GCC >= 7.4 - CMake #### Run-time @@ -313,7 +314,7 @@ After installing all the dependencies, finally run the following commands in the ```shell mkdir build cd build -qmake ../ +cmake ../ make ``` @@ -321,23 +322,6 @@ make Simply use `make install` with privileges. -## Packaging - -Having `git` installed is required if you're building Flameshot from a snapshot to have precise version information. - -In order to generate the instructions in the `Makefile` to install the application in `/usr` instead of in `/usr/local` you can pass the `packaging` option to `qmake` (`qmake CONFIG+=packaging`). - -If you want to install in a custom directory you can use the `INSTALL_ROOT` variable. - -**Example**: - -If you want to install Flameshot in `~/myBuilds/test`, you can execute the following to do so: - -```shell -qmake CONFIG+=packaging -make INSTALL_ROOT=~/myBuilds/test install -``` - ## License - The main code is licensed under [GPLv3](LICENSE) - The logo of Flameshot is licensed under [Free Art License v1.3](img/app/flameshotLogoLicense.txt) @@ -353,15 +337,11 @@ Info: If I take code from your project and that implies a relicense to GPLv3, yo If you want to contribute check the [CONTRIBUTING.md](CONTRIBUTING.md) -## Donations -I improve Flameshot in my free time because I want to create something good for everyone to use. -If you want you can donate some bucks with the following options: -- [Paypal](https://www.paypal.me/lupoDharkael) -- bitcoin:1K6oiUKWVjP3x9ZuW9C7NbDfcFkMx3G8ue ## Acknowledgment -I really appreciate those who have shown interest in the early development process: +Thanks to those who have shown interest in the early development process: +- [lupoDharkael](https://github.com/lupoDharkael) - [Cosmo](https://github.com/philpem) - [XerTheSquirrel](https://github.com/XerTheSquirrel) - [The members of Sugus GNU/Linux](https://github.com/SUGUS-GNULinux) diff --git a/appveyor.yml b/appveyor.yml index d2b6560d..960e86f2 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,72 +1,20 @@ -image: Visual Studio 2015 - -version: 0.6.{build}.0 -# Major_Version_Number.Minor_Version_Number.Build_Number.Revision_Number - -branches: - only: - - master +image: + - Visual Studio 2019 +clone_folder: c:\projects\source environment: - COMPILER: msvc - VSVER: 14 - - matrix: - - QT: C:\Qt\5.9\msvc2015_64 - PLATFORM: amd64 - - QT: C:\Qt\5.9\msvc2015 - PLATFORM: x86 -init: - - ps: | - $version = new-object System.Version $env:APPVEYOR_BUILD_VERSION - $packageVersion = "{0}.{1}.{2}" -f $version.Major, $version.Minor, $version.Revision - $env:build_number = $version.Build - $env:flameshot_version = $packageVersion - -# scripts that run after cloning repository -install: - - set PATH=%QT%\bin\;C:\Qt\Tools\QtCreator\bin\;C:\Qt\QtIFW3.0.1\bin\;%PATH% - -# scripts that run before build -before_build: - - call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" %PLATFORM% - # After calling vcvarsall.bat, %PLATFORM% will be X64 or x86 - - qmake --version - - mkdir build - - cd build - - if "%PLATFORM%" EQU "X64" (qmake -r -spec win32-msvc CONFIG+=x86_64 CONFIG-=debug CONFIG+=release ../flameshot.pro) - - if "%PLATFORM%" EQU "x86" (qmake -r -spec win32-msvc CONFIG+=Win32 CONFIG-=debug CONFIG+=release ../flameshot.pro) - -# custom build scripts + Qt5_INSTALL_DIR: 'C:\Qt\5.15.0\msvc2019_64' + PATH: '%Qt5_INSTALL_DIR%\bin;%PATH%' build_script: - - nmake +- cmd: >- -# scripts that run after build -after_build: - # Clone OpenSSL DLLs - - git clone https://github.com/tamlok/openssl-utils.git openssl-utils.git - - mkdir distrib\flameshot - - windeployqt.exe --dir .\distrib\flameshot %APPVEYOR_BUILD_FOLDER%\build\release\flameshot.exe - - copy "%APPVEYOR_BUILD_FOLDER%\build\release\flameshot.exe" "distrib\flameshot\flameshot.exe" - - copy "%APPVEYOR_BUILD_FOLDER%\README.md" "distrib\flameshot\README.md" - - copy "%APPVEYOR_BUILD_FOLDER%\LICENSE" "distrib\flameshot\LICENSE.txt" - - echo %flameshot_version% > "distrib\flameshot\version.txt" - - echo Build:%build_number% >> "distrib\flameshot\version.txt" - - echo %APPVEYOR_REPO_COMMIT% >> "distrib\flameshot\version.txt" - - copy "distrib\flameshot\flameshot.exe" "distrib\flameshot_win_%PLATFORM%.exe" - - copy "%APPVEYOR_BUILD_FOLDER%\build\translations\Internationalization_*.qm" "distrib\flameshot\translations" - # Delete translations\qt_*.qm - - del /F /Q "distrib\flameshot\translations\qt_*.qm" - # Copy OpenSSL DLLs - - if "%PLATFORM%" EQU "X64" (xcopy "openssl-utils.git\win64\*.dll" "distrib\flameshot") - - if "%PLATFORM%" EQU "x86" (xcopy "openssl-utils.git\win32\*.dll" "distrib\flameshot") - - cd distrib - - 7z a flameshot_%flameshot_version%_win_%PLATFORM%.zip flameshot - - appveyor-retry curl --upload-file ./flameshot_%flameshot_version%_win_%PLATFORM%.zip https://transfer.sh/flameshot_%flameshot_version%_win_%PLATFORM%.zip + mkdir build + cd build + + echo %PATH% + + cmake c:\projects\source -G "Visual Studio 16 2019" -DCMAKE_BUILD_TYPE:STRING=Release + + cmake --build . --config "Release" -# artifacts: -# - path: build\distrib\flameshot_win_%PLATFORM%_portable_%flameshot_version%.zip -# name: portable -# - path: build\distrib\flameshot_win_%PLATFORM%.exe -# name: exe_only diff --git a/cmake/CompilerWarnings.cmake b/cmake/CompilerWarnings.cmake new file mode 100644 index 00000000..d933ce30 --- /dev/null +++ b/cmake/CompilerWarnings.cmake @@ -0,0 +1,78 @@ +# from here: +# +# https://github.com/lefticus/cppbestpractices/blob/master/02-Use_the_Tools_Avai lable.md + +function(set_project_warnings project_name) + option(WARNINGS_AS_ERRORS "Treat compiler warnings as errors" TRUE) + + set(MSVC_WARNINGS + /W4 # Baseline reasonable warnings + /w14242 # 'identifier': conversion from 'type1' to 'type1', possible loss of data + /w14254 # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data + /w14263 # 'function': member function does not override any base class virtual member function + /w14265 # 'classname': class has virtual functions, but destructor is not virtual instances of this class may not + # be destructed correctly + /w14287 # 'operator': unsigned/negative constant mismatch + /we4289 # nonstandard extension used: 'variable': loop control variable declared in the for-loop is used outside + # the for-loop scope + /w14296 # 'operator': expression is always 'boolean_value' + /w14311 # 'variable': pointer truncation from 'type1' to 'type2' + /w14545 # expression before comma evaluates to a function which is missing an argument list + /w14546 # function call before comma missing argument list + /w14547 # 'operator': operator before comma has no effect; expected operator with side-effect + /w14549 # 'operator': operator before comma has no effect; did you intend 'operator'? + /w14555 # expression has no effect; expected expression with side- effect + /w14619 # pragma warning: there is no warning number 'number' + /w14640 # Enable warning on thread un-safe static member initialization + /w14826 # Conversion from 'type1' to 'type_2' is sign-extended. This may cause unexpected runtime behavior. + /w14905 # wide string literal cast to 'LPSTR' + /w14906 # string literal cast to 'LPWSTR' + /w14928 # illegal copy-initialization; more than one user-defined conversion has been implicitly applied + /permissive- # standards conformance mode for MSVC compiler. + ) + + set(CLANG_WARNINGS + -Wall + -Wextra # reasonable and standard + -Wshadow # warn the user if a variable declaration shadows one from a parent context + -Wnon-virtual-dtor # warn the user if a class with virtual functions has a non-virtual destructor. This helps + # catch hard to track down memory errors + -Wold-style-cast # warn for c-style casts + -Wcast-align # warn for potential performance problem casts + -Wunused # warn on anything being unused + -Woverloaded-virtual # warn if you overload (not override) a virtual function + -Wpedantic # warn if non-standard C++ is used + -Wconversion # warn on type conversions that may lose data + -Wsign-conversion # warn on sign conversions + -Wnull-dereference # warn if a null dereference is detected + -Wdouble-promotion # warn if float is implicit promoted to double + -Wformat=2 # warn on security issues around functions that format output (ie printf) + ) + + if(WARNINGS_AS_ERRORS) + set(CLANG_WARNINGS ${CLANG_WARNINGS} -Werror) + set(MSVC_WARNINGS ${MSVC_WARNINGS} /WX) + endif() + + set(GCC_WARNINGS + ${CLANG_WARNINGS} + -Wmisleading-indentation # warn if indentation implies blocks where blocks do not exist + -Wduplicated-cond # warn if if / else chain has duplicated conditions + -Wduplicated-branches # warn if if / else branches have duplicated code + -Wlogical-op # warn about logical operations being used where bitwise were probably wanted + -Wuseless-cast # warn if you perform a cast to the same type + ) + + if(MSVC) + set(PROJECT_WARNINGS ${MSVC_WARNINGS}) + elseif(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") + set(PROJECT_WARNINGS ${CLANG_WARNINGS}) + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set(PROJECT_WARNINGS ${GCC_WARNINGS}) + else() + message(AUTHOR_WARNING "No compiler warnings set for '${CMAKE_CXX_COMPILER_ID}' compiler.") + endif() + + target_compile_options(${project_name} INTERFACE ${PROJECT_WARNINGS}) + +endfunction() diff --git a/cmake/Sanitizers.cmake b/cmake/Sanitizers.cmake new file mode 100644 index 00000000..dda0d26c --- /dev/null +++ b/cmake/Sanitizers.cmake @@ -0,0 +1,66 @@ +function(enable_sanitizers project_name) + + if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") + option(ENABLE_COVERAGE "Enable coverage reporting for gcc/clang" FALSE) + + if(ENABLE_COVERAGE) + target_compile_options(${project_name} INTERFACE --coverage -O0 -g) + target_link_libraries(${project_name} INTERFACE --coverage) + endif() + + set(SANITIZERS "") + + option(ENABLE_SANITIZER_ADDRESS "Enable address sanitizer" FALSE) + if(ENABLE_SANITIZER_ADDRESS) + list(APPEND SANITIZERS "address") + endif() + + option(ENABLE_SANITIZER_LEAK "Enable leak sanitizer" FALSE) + if(ENABLE_SANITIZER_LEAK) + list(APPEND SANITIZERS "leak") + endif() + + option(ENABLE_SANITIZER_UNDEFINED_BEHAVIOR "Enable undefined behavior sanitizer" FALSE) + if(ENABLE_SANITIZER_UNDEFINED_BEHAVIOR) + list(APPEND SANITIZERS "undefined") + endif() + + option(ENABLE_SANITIZER_THREAD "Enable thread sanitizer" FALSE) + if(ENABLE_SANITIZER_THREAD) + if("address" IN_LIST SANITIZERS OR "leak" IN_LIST SANITIZERS) + message(WARNING "Thread sanitizer does not work with Address and Leak sanitizer enabled") + else() + list(APPEND SANITIZERS "thread") + endif() + endif() + + option(ENABLE_SANITIZER_MEMORY "Enable memory sanitizer" FALSE) + if(ENABLE_SANITIZER_MEMORY AND CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") + if("address" IN_LIST SANITIZERS + OR "thread" IN_LIST SANITIZERS + OR "leak" IN_LIST SANITIZERS) + message(WARNING "Memory sanitizer does not work with Address, Thread and Leak sanitizer enabled") + else() + list(APPEND SANITIZERS "memory") + endif() + endif() + + list( + JOIN + SANITIZERS + "," + LIST_OF_SANITIZERS) + + endif() + + if(LIST_OF_SANITIZERS) + if(NOT + "${LIST_OF_SANITIZERS}" + STREQUAL + "") + target_compile_options(${project_name} INTERFACE -fsanitize=${LIST_OF_SANITIZERS}) + target_link_libraries(${project_name} INTERFACE -fsanitize=${LIST_OF_SANITIZERS}) + endif() + endif() + +endfunction() \ No newline at end of file diff --git a/cmake/StandardProjectSettings.cmake b/cmake/StandardProjectSettings.cmake new file mode 100644 index 00000000..743b0712 --- /dev/null +++ b/cmake/StandardProjectSettings.cmake @@ -0,0 +1,34 @@ +# Set a default build type if none was specified +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + message(STATUS "Setting build type to 'RelWithDebInfo' as none was specified.") + set(CMAKE_BUILD_TYPE + RelWithDebInfo + CACHE STRING "Choose the type of build." FORCE) + # Set the possible values of build type for cmake-gui, ccmake + set_property( + CACHE CMAKE_BUILD_TYPE + PROPERTY STRINGS + "Debug" + "Release" + "MinSizeRel" + "RelWithDebInfo") +endif() + +# Generate compile_commands.json to make it easier to work with clang based tools +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +option(ENABLE_IPO "Enable Interprocedural Optimization, aka Link Time Optimization (LTO)" OFF) + +if(ENABLE_IPO) + include(CheckIPOSupported) + check_ipo_supported( + RESULT + result + OUTPUT + output) + if(result) + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) + else() + message(SEND_ERROR "IPO is not supported: ${output}") + endif() +endif() \ No newline at end of file diff --git a/cmake/StaticAnalyzers.cmake b/cmake/StaticAnalyzers.cmake new file mode 100644 index 00000000..43964447 --- /dev/null +++ b/cmake/StaticAnalyzers.cmake @@ -0,0 +1,37 @@ +option(ENABLE_CPPCHECK "Enable static analysis with cppcheck" OFF) +option(ENABLE_CLANG_TIDY "Enable static analysis with clang-tidy" OFF) +option(ENABLE_INCLUDE_WHAT_YOU_USE "Enable static analysis with include-what-you-use" OFF) + +if(ENABLE_CPPCHECK) + find_program(CPPCHECK cppcheck) + if(CPPCHECK) + set(CMAKE_CXX_CPPCHECK + ${CPPCHECK} + --suppress=missingInclude + --enable=all + --inline-suppr + --inconclusive + -i + ${CMAKE_SOURCE_DIR}/imgui/lib) + else() + message(SEND_ERROR "cppcheck requested but executable not found") + endif() +endif() + +if(ENABLE_CLANG_TIDY) + find_program(CLANGTIDY clang-tidy) + if(CLANGTIDY) + set(CMAKE_CXX_CLANG_TIDY ${CLANGTIDY} -extra-arg=-Wno-unknown-warning-option) + else() + message(SEND_ERROR "clang-tidy requested but executable not found") + endif() +endif() + +if(ENABLE_INCLUDE_WHAT_YOU_USE) + find_program(INCLUDE_WHAT_YOU_USE include-what-you-use) + if(INCLUDE_WHAT_YOU_USE) + set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE ${INCLUDE_WHAT_YOU_USE}) + else() + message(SEND_ERROR "include-what-you-use requested but executable not found") + endif() +endif() diff --git a/data/dbus/org.flameshot.Flameshot.service.in b/data/dbus/org.flameshot.Flameshot.service.in new file mode 100644 index 00000000..781ffa8a --- /dev/null +++ b/data/dbus/org.flameshot.Flameshot.service.in @@ -0,0 +1,3 @@ +[D-BUS Service] +Name=org.flameshot.Flameshot +Exec=${CMAKE_INSTALL_FULL_BINDIR}/flameshot diff --git a/dbus/org.dharkael.Flameshot.xml b/data/dbus/org.flameshot.Flameshot.xml similarity index 98% rename from dbus/org.dharkael.Flameshot.xml rename to data/dbus/org.flameshot.Flameshot.xml index ab51fbbe..9a4f4860 100644 --- a/dbus/org.dharkael.Flameshot.xml +++ b/data/dbus/org.flameshot.Flameshot.xml @@ -1,6 +1,6 @@ - +