First pass at converting from qmake to cmake.
6
.clang-tidy
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
---
|
||||
Checks: '*,-fuchsia-*,-google-*,-zircon-*,-abseil-*,-modernize-use-trailing-return-type,-llvm-*'
|
||||
WarningsAsErrors: '*'
|
||||
HeaderFilterRegex: ''
|
||||
FormatStyle: none
|
||||
18
.cmake-format.yaml
Normal file
@@ -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
|
||||
2
.gitignore
vendored
@@ -49,6 +49,8 @@ stage/
|
||||
.snapcraft/
|
||||
flameshot*.tar.bz2
|
||||
|
||||
.vscode/
|
||||
build/
|
||||
|
||||
# NVIM
|
||||
*~
|
||||
|
||||
98
.travis.yml
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
#!/bin/bash --
|
||||
|
||||
set -e
|
||||
|
||||
if [[ "${EXTEN}" == "other" ]]; then
|
||||
travis_retry sudo apt update
|
||||
fi
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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 ..
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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/<short_url_id>`:
|
||||
received via link upload, via email to the sender and printed by
|
||||
`upload` action
|
||||
- `https://wetransfer.com/<transfer_id>/<security_hash>`:
|
||||
directly not shared in any ways but the short URLs actually redirect to
|
||||
them
|
||||
- `https://wetransfer.com/<transfer_id>/<recipient_id>/<security_hash>`:
|
||||
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)
|
||||
@@ -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
|
||||
24
CMakeLists.txt
Normal file
@@ -0,0 +1,24 @@
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
|
||||
project(flameshot 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)
|
||||
72
appveyor.yml
@@ -1,72 +0,0 @@
|
||||
image: Visual Studio 2015
|
||||
|
||||
version: 0.6.{build}.0
|
||||
# Major_Version_Number.Minor_Version_Number.Build_Number.Revision_Number
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
||||
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
|
||||
build_script:
|
||||
- nmake
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
# artifacts:
|
||||
# - path: build\distrib\flameshot_win_%PLATFORM%_portable_%flameshot_version%.zip
|
||||
# name: portable
|
||||
# - path: build\distrib\flameshot_win_%PLATFORM%.exe
|
||||
# name: exe_only
|
||||
78
cmake/CompilerWarnings.cmake
Normal file
@@ -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()
|
||||
66
cmake/Sanitizers.cmake
Normal file
@@ -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()
|
||||
34
cmake/StandardProjectSettings.cmake
Normal file
@@ -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()
|
||||
37
cmake/StaticAnalyzers.cmake
Normal file
@@ -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()
|
||||
|
Before Width: | Height: | Size: 119 KiB After Width: | Height: | Size: 119 KiB |
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 223 B After Width: | Height: | Size: 223 B |
|
Before Width: | Height: | Size: 101 B After Width: | Height: | Size: 101 B |
|
Before Width: | Height: | Size: 166 B After Width: | Height: | Size: 166 B |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 469 B After Width: | Height: | Size: 469 B |
|
Before Width: | Height: | Size: 234 B After Width: | Height: | Size: 234 B |
|
Before Width: | Height: | Size: 531 B After Width: | Height: | Size: 531 B |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 245 B After Width: | Height: | Size: 245 B |
|
Before Width: | Height: | Size: 159 B After Width: | Height: | Size: 159 B |
|
Before Width: | Height: | Size: 344 B After Width: | Height: | Size: 344 B |
|
Before Width: | Height: | Size: 244 B After Width: | Height: | Size: 244 B |
|
Before Width: | Height: | Size: 332 B After Width: | Height: | Size: 332 B |
|
Before Width: | Height: | Size: 313 B After Width: | Height: | Size: 313 B |
|
Before Width: | Height: | Size: 360 B After Width: | Height: | Size: 360 B |
|
Before Width: | Height: | Size: 280 B After Width: | Height: | Size: 280 B |
|
Before Width: | Height: | Size: 224 B After Width: | Height: | Size: 224 B |
|
Before Width: | Height: | Size: 190 B After Width: | Height: | Size: 190 B |
|
Before Width: | Height: | Size: 274 B After Width: | Height: | Size: 274 B |
|
Before Width: | Height: | Size: 240 B After Width: | Height: | Size: 240 B |
|
Before Width: | Height: | Size: 266 B After Width: | Height: | Size: 266 B |
|
Before Width: | Height: | Size: 178 B After Width: | Height: | Size: 178 B |
|
Before Width: | Height: | Size: 282 B After Width: | Height: | Size: 282 B |
|
Before Width: | Height: | Size: 242 B After Width: | Height: | Size: 242 B |
|
Before Width: | Height: | Size: 332 B After Width: | Height: | Size: 332 B |
|
Before Width: | Height: | Size: 327 B After Width: | Height: | Size: 327 B |
|
Before Width: | Height: | Size: 321 B After Width: | Height: | Size: 321 B |
|
Before Width: | Height: | Size: 272 B After Width: | Height: | Size: 272 B |
|
Before Width: | Height: | Size: 140 B After Width: | Height: | Size: 140 B |
|
Before Width: | Height: | Size: 194 B After Width: | Height: | Size: 194 B |
|
Before Width: | Height: | Size: 146 B After Width: | Height: | Size: 146 B |
|
Before Width: | Height: | Size: 292 B After Width: | Height: | Size: 292 B |
|
Before Width: | Height: | Size: 207 B After Width: | Height: | Size: 207 B |
|
Before Width: | Height: | Size: 254 B After Width: | Height: | Size: 254 B |
|
Before Width: | Height: | Size: 326 B After Width: | Height: | Size: 326 B |
|
Before Width: | Height: | Size: 218 B After Width: | Height: | Size: 218 B |
|
Before Width: | Height: | Size: 151 B After Width: | Height: | Size: 151 B |
|
Before Width: | Height: | Size: 333 B After Width: | Height: | Size: 333 B |
|
Before Width: | Height: | Size: 335 B After Width: | Height: | Size: 335 B |
|
Before Width: | Height: | Size: 339 B After Width: | Height: | Size: 339 B |
|
Before Width: | Height: | Size: 179 B After Width: | Height: | Size: 179 B |
|
Before Width: | Height: | Size: 159 B After Width: | Height: | Size: 159 B |
|
Before Width: | Height: | Size: 74 B After Width: | Height: | Size: 74 B |
|
Before Width: | Height: | Size: 270 B After Width: | Height: | Size: 270 B |
|
Before Width: | Height: | Size: 175 B After Width: | Height: | Size: 175 B |
|
Before Width: | Height: | Size: 249 B After Width: | Height: | Size: 249 B |
|
Before Width: | Height: | Size: 197 B After Width: | Height: | Size: 197 B |
|
Before Width: | Height: | Size: 218 B After Width: | Height: | Size: 218 B |
|
Before Width: | Height: | Size: 360 B After Width: | Height: | Size: 360 B |
|
Before Width: | Height: | Size: 325 B After Width: | Height: | Size: 325 B |
|
Before Width: | Height: | Size: 251 B After Width: | Height: | Size: 251 B |
|
Before Width: | Height: | Size: 263 B After Width: | Height: | Size: 263 B |
|
Before Width: | Height: | Size: 213 B After Width: | Height: | Size: 213 B |
|
Before Width: | Height: | Size: 175 B After Width: | Height: | Size: 175 B |
|
Before Width: | Height: | Size: 79 B After Width: | Height: | Size: 79 B |
|
Before Width: | Height: | Size: 157 B After Width: | Height: | Size: 157 B |
|
Before Width: | Height: | Size: 62 B After Width: | Height: | Size: 62 B |
|
Before Width: | Height: | Size: 120 B After Width: | Height: | Size: 120 B |