mirror of
https://github.com/qbittorrent/qBittorrent
synced 2025-08-20 21:33:27 -07:00
Merge branch 'master' of https://github.com/qbittorrent/qBittorrent
This commit is contained in:
commit
7fb3962192
322 changed files with 175969 additions and 127574 deletions
|
@ -9,8 +9,8 @@ environment:
|
||||||
REPO_DIR: &REPO_DIR c:\qbittorrent
|
REPO_DIR: &REPO_DIR c:\qbittorrent
|
||||||
CACHE_DIR: &CACHE_DIR c:\qbt_cache
|
CACHE_DIR: &CACHE_DIR c:\qbt_cache
|
||||||
|
|
||||||
QBT_VER_URL: http://builds.shiki.hu/appveyor/version
|
QBT_VER_URL: https://builds.shiki.hu/appveyor/version
|
||||||
QBT_LIB_URL: http://builds.shiki.hu/appveyor/qbt_libraries.7z
|
QBT_LIB_URL: https://builds.shiki.hu/appveyor/qbt_libraries.7z
|
||||||
|
|
||||||
# project directory
|
# project directory
|
||||||
clone_folder: *REPO_DIR
|
clone_folder: *REPO_DIR
|
60
.travis.yml
60
.travis.yml
|
@ -3,7 +3,7 @@ language: cpp
|
||||||
os:
|
os:
|
||||||
- linux
|
- linux
|
||||||
- osx
|
- osx
|
||||||
osx_image: xcode7
|
osx_image: xcode7.3
|
||||||
|
|
||||||
env:
|
env:
|
||||||
matrix:
|
matrix:
|
||||||
|
@ -30,10 +30,10 @@ notifications:
|
||||||
|
|
||||||
# container-based builds
|
# container-based builds
|
||||||
#sudo: false
|
#sudo: false
|
||||||
# TODO: osx builder does not enable cache yet, see: https://github.com/travis-ci/travis-ci/issues/4011
|
cache:
|
||||||
#cache:
|
ccache: true
|
||||||
#directories:
|
directories:
|
||||||
#- $HOME/.ccache
|
- $HOME/hombebrew_cache
|
||||||
|
|
||||||
# opt-in Ubuntu Trusty
|
# opt-in Ubuntu Trusty
|
||||||
sudo: required
|
sudo: required
|
||||||
|
@ -80,12 +80,6 @@ before_install:
|
||||||
- if [ "$gui" = false ]; then qbtconf="$qbtconf --disable-gui" ; fi
|
- if [ "$gui" = false ]; then qbtconf="$qbtconf --disable-gui" ; fi
|
||||||
- |
|
- |
|
||||||
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||||
# ccache
|
|
||||||
#if [ "$TRAVIS_BRANCH" != "$coverity_branch" ]; then
|
|
||||||
#dpkg-query -L ccache && export PATH="/usr/lib/ccache/:$PATH" && export use_ccache=true ;
|
|
||||||
#ccache -V && ccache --show-stats && ccache --zero-stats ;
|
|
||||||
#fi ;
|
|
||||||
|
|
||||||
# setup virtual display for after_success target
|
# setup virtual display for after_success target
|
||||||
if [ "$gui" = true ]; then export "DISPLAY=:99.0" && /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -ac -screen 0 1280x1024x16 ; fi ;
|
if [ "$gui" = true ]; then export "DISPLAY=:99.0" && /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -ac -screen 0 1280x1024x16 ; fi ;
|
||||||
fi
|
fi
|
||||||
|
@ -117,27 +111,61 @@ install:
|
||||||
# Qt
|
# Qt
|
||||||
if [ "$qt" = 4 ]; then sudo apt-get -qq install qt4-default libqt4-dev ; fi ;
|
if [ "$qt" = 4 ]; then sudo apt-get -qq install qt4-default libqt4-dev ; fi ;
|
||||||
if [ "$qt" = 5 ]; then sudo apt-get -qq install qt5-default qtbase5-dev qttools5-dev-tools ; fi ;
|
if [ "$qt" = 5 ]; then sudo apt-get -qq install qt5-default qtbase5-dev qttools5-dev-tools ; fi ;
|
||||||
|
|
||||||
|
# ccache
|
||||||
|
if [ "$TRAVIS_BRANCH" != "$coverity_branch" ]; then
|
||||||
|
dpkg-query -L ccache && export use_ccache=true ;
|
||||||
|
ccache -V && ccache --show-stats && ccache --zero-stats ;
|
||||||
|
fi ;
|
||||||
fi
|
fi
|
||||||
- |
|
- |
|
||||||
if [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
if [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||||
|
mkdir -p "$HOME/hombebrew_cache" ;
|
||||||
|
wget https://builds.shiki.hu/homebrew/version ;
|
||||||
|
if ! cmp --quiet "version" "$HOME/hombebrew_cache/version" ; then
|
||||||
|
echo "Cached files are different from server. Downloading new ones." ;
|
||||||
|
cp "version" $HOME/hombebrew_cache ;
|
||||||
|
cd "$HOME/hombebrew_cache" ;
|
||||||
|
wget https://builds.shiki.hu/homebrew/libtorrent-rasterbar.rb ;
|
||||||
|
wget https://builds.shiki.hu/homebrew/libtorrent-rasterbar-1.0.10.el_capitan.bottle.tar.gz ;
|
||||||
|
fi
|
||||||
|
|
||||||
# dependencies
|
# dependencies
|
||||||
brew update > /dev/null && brew install colormake libtorrent-rasterbar ;
|
brew update > /dev/null ;
|
||||||
|
brew install colormake ccache ;
|
||||||
|
brew outdated "pkg-config" || brew upgrade "pkg-config" ;
|
||||||
|
# Copy custom libtorrent bottle to homebrew's cache so it can find and install it
|
||||||
|
# Also install our custom libtorrent formula by passing the local path to it
|
||||||
|
# These 2 files are restored from Travis' cache.
|
||||||
|
cp "$HOME/hombebrew_cache/libtorrent-rasterbar-1.0.10.el_capitan.bottle.tar.gz" "$(brew --cache)" ;
|
||||||
|
brew install "$HOME/hombebrew_cache/libtorrent-rasterbar.rb" ;
|
||||||
|
|
||||||
# Qt
|
# Qt
|
||||||
if [ "$qt" = 4 ]; then brew install qt ; fi ;
|
if [ "$qt" = 4 ]; then brew install qt && ln -s /usr/local/Cellar/qt/4.8.7_2/plugins /usr/local ; fi ;
|
||||||
if [ "$qt" = 5 ]; then brew install qt5 && brew link --force qt5 ; fi ;
|
if [ "$qt" = 5 ]; then brew install qt5 && brew link --force qt5 && ln -s /usr/local/Cellar/qt5/5.7.0/plugins /usr/local ; fi ;
|
||||||
|
|
||||||
|
# ccache
|
||||||
|
if [ "$TRAVIS_BRANCH" != "$coverity_branch" ]; then
|
||||||
|
export PATH="/usr/local/opt/ccache/libexec:$PATH" && export use_ccache=true ;
|
||||||
|
ccache -V && ccache --show-stats && ccache --zero-stats ;
|
||||||
|
fi ;
|
||||||
fi
|
fi
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- if [ "$TRAVIS_BRANCH" = "$coverity_branch" ]; then exit ; fi # skip usual build when running coverity scan
|
- if [ "$TRAVIS_BRANCH" = "$coverity_branch" ]; then exit ; fi # skip usual build when running coverity scan
|
||||||
- cd "$TRAVIS_BUILD_DIR" && ./bootstrap.sh && ./configure $qbtconf
|
- cd "$TRAVIS_BUILD_DIR" && ./bootstrap.sh && ./configure $qbtconf
|
||||||
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then sed -i "" -e 's/^\(CXXFLAGS.*\)$/\1 -Wno-unused-local-typedefs/' src/Makefile ; fi
|
- |
|
||||||
|
if [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||||
|
sed -i "" -e "s/^\(CC.*&&\).*$/\1 $CC/" src/Makefile ; # workaround for Qt & ccache: https://bugreports.qt.io/browse/QTBUG-31034
|
||||||
|
sed -i "" -e "s/^\(CXX.*&&\).*$/\1 $CXX/" src/Makefile ;
|
||||||
|
sed -i "" -e 's/^\(CXXFLAGS.*\)$/\1 -Wno-unused-local-typedefs -Wno-inconsistent-missing-override/' src/Makefile ;
|
||||||
|
fi
|
||||||
- make && make install
|
- make && make install
|
||||||
|
|
||||||
after_success:
|
after_success:
|
||||||
- if [ "$gui" = true ]; then qbt_exe="qbittorrent" ; else qbt_exe="qbittorrent-nox" ; fi
|
- if [ "$gui" = true ]; then qbt_exe="qbittorrent" ; else qbt_exe="qbittorrent-nox" ; fi
|
||||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then cd "$qbt_path/bin" ; fi
|
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then cd "$qbt_path/bin" ; fi
|
||||||
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then cd "$TRAVIS_BUILD_DIR/src/$qbt_exe.app/Contents/MacOS" ; fi
|
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then cd "$TRAVIS_BUILD_DIR/src/" && macdeployqt "$qbt_exe.app" && cd "$qbt_exe.app/Contents/MacOS" ; fi
|
||||||
- ./$qbt_exe --version
|
- ./$qbt_exe --version
|
||||||
|
|
||||||
after_script:
|
after_script:
|
||||||
|
|
92
5B7CC9A2.asc
Normal file
92
5B7CC9A2.asc
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
Version: GnuPG v2
|
||||||
|
|
||||||
|
mQINBFcNIIwBEACpGHvHW9ku7rwCSc2Dv4gh3MO3HPoP7Ba4RiEKwa7SCbPzc0DL
|
||||||
|
JypV4gNfnrpiO7bWVh5v+otbZTkQeNXWbx6hDUa2e5GCCuJifIu3PxpmMcNJFvvF
|
||||||
|
nk5QRf6dtz4Sm2x6joYprvsEUjyk+wHC016/0g7yhc/w0sclXlpKK+8Pl5DFrf5C
|
||||||
|
i5uljy3oJgl54D2yYAvxu3BrdTVKhLVYADUf1Fl3b5pV7VJwr+9wGuTqkORe1rpi
|
||||||
|
9NGWXUaTmKF8+XAJxlbYIUOZQpQ02clFxz0T7o/+m74N8tK9j7g8H2Q3QwtKi0q1
|
||||||
|
gI48LqI/EuZHIaRz/3pEVISlIpWzGqBL/G4I/UtzJLHyvySsqWXAKllKpk97XX77
|
||||||
|
XxFy3VL3fR7o4IohAj5fD083X8tuBIP2dxmHzxHTWveKBlEV6C4MdtVRow8ia3lu
|
||||||
|
RKLz6PF0hBBpebAP4MWAN8cy4ePBCe9BvyI2+3tPgqtlC2tEZLnRru6mtagPi4sj
|
||||||
|
Yo/iFkSQdTXrxeyrMJh161gsWl16JeAfz4Dq8IBoUA1hXIjfM9FcIv1rCY6Y8JwS
|
||||||
|
TtWMGYtzIcqE71wZxqnJuyFZkgC14NDTLgUwLf8XJOTWlMW9CY+tStjjw+sNoIPf
|
||||||
|
p7YQCmss4p5J8flnxH4xJ8ogOHxENidA+Z/J9mtGjxXIXHavPlO3IEg/DwARAQAB
|
||||||
|
tHFzbGVkZ2VoYW1tZXI5OTkgKFVzZWQgZm9yIHNpZ25pbmcgcUJpdHRvcnJlbnQg
|
||||||
|
c291cmNlIHRhcmJhbGxzIGFuZCBiaW5hcmllcyB2Mi4pIDxzbGVkZ2VoYW1tZXI5
|
||||||
|
OTlAcWJpdHRvcnJlbnQub3JnPokCNwQTAQgAIQUCVw0gjAIbAwULCQgHAgYVCAkK
|
||||||
|
CwIEFgIDAQIeAQIXgAAKCRBuSi0CW3zJojB2D/0bKlelRDQDtWzfRyxrdhe5pgAt
|
||||||
|
x1AsN/Cl7h8zlbAw38bL+jQ2/GmtzwzEqPfQc7IFnbeg0PZ58p7Hikj9h6JEhkyA
|
||||||
|
1qekkriclUmblEwDne3TjPixqgoBfNcDQu74dT08XpM8auFQo31/jJ104903o0O5
|
||||||
|
+CPOPn2KTdwpcSpwAVIj/3H96gZWegJDNpdByJUVbzYCt1erJ6I0ZURKhzU1VTJj
|
||||||
|
ZdEGB2YsvYpt5rsi41IYZZG33jMsPxSDDNJ/MiLXxkn08ZawNET6fnkEJJ37n9Pw
|
||||||
|
82lTZjFEFU+KTMT7dNjIejWCRgHVLgW8sO2lCPqMiFfWymD/N3sFpBO+UI86y5ds
|
||||||
|
hfGFAWcgSq9pVjuW4sbX3PntBnoNd+geDD1Ic4rP3jHRe5HuYGhtHO6xv/r7HeY5
|
||||||
|
HiShCTSSDBJqFmhfjrCo0nISKnzyxgO/rY9vFlwXsKkTyL7s53ONkjwK34WmGnya
|
||||||
|
tXdjBWShzAiTfF5hephfBSszmoBG2C8Jcu6P5n4buBY4RCsEa+6jE0R1vCtmpVwx
|
||||||
|
WrXOeN2kGYMpAkPK1L69Le0FofgUDKlaFMv7KRl4R367xNRukYrsKwVlontJ+Y72
|
||||||
|
X5t1BeRn8VSp0IzhssNXM8a4bTE8lvs889DOS2vgWEHIi0iyIesJYWPs4AKUw4rG
|
||||||
|
EDwWxtTS0a7Rfx3DxLRWc2xlZGdlaGFtbWVyOTk5IChVc2VkIGZvciBzaWduaW5n
|
||||||
|
IGdpdCBjb21taXRzL3RhZ3MvZXRjLikgPGhhbW1lcmVkOTk5QHFiaXR0b3JyZW50
|
||||||
|
Lm9yZz6JAh8EMAEIAAkFAlhie1ICHQAACgkQbkotAlt8yaILIhAAp25o1BbUG2Zk
|
||||||
|
At3cSrTFnZSCA7nEygbSUv1Uek33JZfY0Apw5qEM8lQCMZk+mhdrSQCYUJcQlruN
|
||||||
|
zJcJf4CH+VGE23xkI3Kf0nGp9Cjn/q6b1hLIPe5rimvw5pTAejFtebcYY/ZJIB8Z
|
||||||
|
H1ebuzfqBZ/9k7eYTarZ/ZsgG8YptB0RXBQWOMaSEKwdeo2m7HXHgK3blQiqbuJJ
|
||||||
|
uyPbid01Wus4AVN47/FKgDNswPs8irYZsu5yakgpi2KLycGDtSiN5XFHI4xbC0zM
|
||||||
|
srR7Cz0/fC+klhGcuxbw0V0It7UUIitgCcTPHXkukUU8i2+AGMyKa1HjchsXDdLg
|
||||||
|
DIs6KIurp2ve7znKOz7h1aX8cOBmB/QYeYAx9jRRkePMIRT8V1lRwfvJlJxx1+G3
|
||||||
|
e2gJLjqTN8a08KHHjdY/S0ZFERxSlmOym2uf/y6di1ipDPxo8xvDuS5kDbdZLC0t
|
||||||
|
XijlsH8ONK27KNuWhucG8zHzKQvnPw2qN06SZq4FjbSmAkkuYs56heLEXMzFr75k
|
||||||
|
SE8rUoQQ+ABG9gU46GEvKlZxqSwXgGnb1X6K7h8svjMh/NlAU358p8Sra4Ru5tz4
|
||||||
|
jUu9MoVEw5Lbjcrsnp6/4Kk1Q2ckBNt43nv8/+C7NsC3xi6BrOInuaKHZ4QsTuzJ
|
||||||
|
m1/A4zlKRnUi6T98DXfIYnNuV9NSmAWJAjkEEwEIACMFAlhiemMCGwMHCwkIBwMC
|
||||||
|
AQYVCAIJCgsEFgIDAQIeAQIXgAAKCRBuSi0CW3zJor6yD/9N2U0INx0nYpGkmvah
|
||||||
|
yVG/vw2S6hhKK+03AN+RrtddNRg4aBf/gmOvRWQhAmFnXOBA7fO09wgcljaV5tVb
|
||||||
|
MYyYZvHhK0o2/sli2p/M5N8ZxchRHypjxUSEyG9ZQ06QG5DVhh4HtM8nIN+UcwTV
|
||||||
|
C5QjyoWZvHf+tNroyFeh7zT+w4kX1VxgynTQr5LGdYsrVA3CFyT3zsBWV3dMae23
|
||||||
|
22CHOirsBBLwairHUsWW+BdThT3MkKYpTEV0jkH4OyAXhJYcS5IjjtKQ8UpZE9dw
|
||||||
|
f4saJ0TnXNe7goPRZtH7UjPwfVbtYK4y8QklWUTRxgoBxNwSC5X7Flg+3xXxE/VU
|
||||||
|
U4cehyRkH64i7MJDoFkqh5JtjkgIz+kuTTXb7xR0Wf+JXrGMybZTR8xth2TEMC20
|
||||||
|
1FT5L5+0vH1WRzL7bhlaU3EXyCnoH8sDvMEClZbibbew+rf7fC3tFU41ohUT0HDl
|
||||||
|
zlyfVjRvBHWMTgfpWKBV2m/qP941xTJ9VHxOlAB02XKUZYwFt07CpH+yjMOCOzA4
|
||||||
|
cTPBD3mGRuft0V0BJ8bA5bcTly/GBciRX0Y5oIeHZGgq2czb0sywSYT6mPoQMFNM
|
||||||
|
B+Cwr4pm90r1DMMfW518onF2itwyN/Id0FsWDhsLJHKluBJw52C3OnxCuToVutTm
|
||||||
|
xntqpPVv62LaeVeWQqxIieTJErRQc2xlZGdlaGFtbWVyXzk5OSAoVXNlZCBmb3Ig
|
||||||
|
c2lnbmluZyBnaXQgY29tbWl0cy90YWdzL2V0YykgPGhhbW1lcmVkOTk5QGdtYWls
|
||||||
|
LmNvbT6JAjkEEwEIACMFAlhifeICGwMHCwkIBwMCAQYVCAIJCgsEFgIDAQIeAQIX
|
||||||
|
gAAKCRBuSi0CW3zJolcCD/9xPBNEkFtnhTW89th0TFZnB5oykCQjyefquvQs8KWT
|
||||||
|
C92/1VizHi4ZxDehHWP9IKVWT3ZJthj5ZXBSedyl1tHnwkyrUYBW9roQwtDWPncK
|
||||||
|
pXl/HsE6p3q6EIus+g6YJo4UvYachJFAZATZp1WDBPIswziHGzaL0tndFWZuVM8V
|
||||||
|
QD0tfPQsS1qCDVv6+B1JWZDnA1JzdSG/uzPhL95q/ff6JmNbfSAVedK2PyqYshnC
|
||||||
|
KWBx6Yna/0ColBuDFho8+bDuHPQcM35xyjPosVD7moXQiY4yMAJ+VzwEBaCFleI0
|
||||||
|
RBWw8/+qyoFqfIKwdq8G+7I9LjWpBiN2+uQBZ+OAvsMWyRShLopxt3JluPTtL6xb
|
||||||
|
Ca6dglOdlaOS/A6FK7u05k/8kQMDS5Jq2/rpfTPRl1/weCaJZgfRIBosk1Mon/pR
|
||||||
|
p1zd0abM4t7BcGQpwSkKAmqlKCrWf886EFQT0CJTBo8q7pzgpVraWWPVsmAOdkfU
|
||||||
|
YcKBgz1A2uMSAxypkSzaDZkIVj6I7gwiGk7IMYx1OK7Ev46h/x4Z7kgT0y3DYYOq
|
||||||
|
ggVEKQ+15Krn7bZ35s8vbZdfnVKPSXdCC8jkIMBmGmRX6cgZZ3OXZlrrHht5icgJ
|
||||||
|
5Z2d1M4JUoEZVUr2xNZkkaMk01NAIpGgKvIS6yHuj6vE4GMJ+A/qEW6J60/3YHRe
|
||||||
|
0bkCDQRXDSCMARAAqMIVJizEJp205c546IN75xeYiFszNXcs3768IY8bOoWj+rTw
|
||||||
|
t2wIwtL/3O5K2dG79CSt2H5o6BPKmq43tOO60YW3Yk3m9BB/gnAVqk0QOPr5O8+y
|
||||||
|
eBzdElU8CZh6y6zZMWugSkNmTDm6jZzPhgNjcjrit/dl9+0DGqJQcqoD8WzEWNcW
|
||||||
|
rMHVz9cDewnLSVkwR758mZMaIiL7R10MZ++tNrC0j69UINqx+9z1r1J07+NNnxqS
|
||||||
|
TxVRcbjPYtM9E+tUiVFS2HPWN9ShVDkBAEdoWh90qzRaMiFl2NGNGOD1iHx/xr06
|
||||||
|
RMeGEEXt2vhSlhfMW2YQW+UD2jzlFbARf53v39MUKKscGuIpBhxGw3JCq4l6qLW/
|
||||||
|
bDkgnoXlOhZDmhQm6OpsjAyk9IEdd3ponSc7yYD3mUkJKR9eTaALD5t6TQGyNHak
|
||||||
|
b4UfoXtE2RR78cbPlLIwag7eQ8GsNA+dfjowmOZdojx3ROsHZdGQwb0YFLjuKAus
|
||||||
|
A3TY+lCfbS6kzE2iI2DuaW+3dICcLrYuibbVb0CBNHyD+8KEtczdur/wm0lhqyVJ
|
||||||
|
kGyZKZT8C2cPxywKgy1Rn6F8Yfmj0Lna3nvtaZu0ZUS4/8Lit5PcOso1lSmYBuD6
|
||||||
|
yq+GEAMCnUmn1Pm8eZRMlxxQuTPvyJKQrRDhbtAAr472MSnoJKlS4SfaUF0AEQEA
|
||||||
|
AYkCHwQYAQgACQUCVw0gjAIbDAAKCRBuSi0CW3zJomZDD/9IJmzd5hiEzntlp84p
|
||||||
|
yIJcfyIRe4KImvldAy6T02OSIbF1HzCNnwmqIPob6MOdMZ+KNwMK0htRkrRr/zM0
|
||||||
|
34+lBiWKZt+tVYHu49ioTYXEjAc5qDJE09Sq7HceQnhgE48f1n54XGT5G2w5gw+/
|
||||||
|
a8Qn1SceE44VwXafL3E1gKaOrrsb1UH/AJhp+W4VMu+7bLXu7h1tN6v2PhvCYvBt
|
||||||
|
3zyy8Q8xfJ2x7/D1lbF8ATJAiZ/km9x5bRm7OGRliVYaUe1nyR42fZOj3CBmAR0+
|
||||||
|
lZLgjriqdMXrs+qlBbrmAhkn0XPQXAeaPifKoKIGDAUWIsqDHqM7imMGT+MR9APf
|
||||||
|
Sw8M4enOJWL+HnKpVBEARCEDpaFpJ3u7QRucFybpEhvIymoNftyw+urId2Eg2K33
|
||||||
|
NypeZo3M1K2LC65f2Ta7f/sZcIDUTbgW+m334fgVl1KptDA5DX3U9lTci7mi4uPu
|
||||||
|
AFtbWrB1di4jYrxXYuzFm5g4xTb0Hw3kYIB6WXF+I7i0JaGOTHxPC5X5lIAZrYrk
|
||||||
|
xh+1n1Y1CY+TC8JcTzwORJIbFFm9tD/BHXa4849k4DVvFYCZkhq+/56FKZfoVByh
|
||||||
|
B+x+2GaMlsBm1uPniO4lAakFPpIi0kaap4UVayQ/7ak+BhscAIHZUy6NtgZkuvW3
|
||||||
|
xdpwp07LYo2ilhMI8RnzmtoRmg==
|
||||||
|
=UBeB
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
|
@ -1,5 +1,5 @@
|
||||||
cmake_minimum_required(VERSION 3.2)
|
cmake_minimum_required(VERSION 3.5)
|
||||||
cmake_policy(VERSION 3.2)
|
cmake_policy(VERSION 3.5)
|
||||||
|
|
||||||
project(qBittorrent VERSION 3.4.0.0)
|
project(qBittorrent VERSION 3.4.0.0)
|
||||||
|
|
||||||
|
|
|
@ -29,8 +29,10 @@ class MyOtherClass
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//code
|
//code
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//code
|
//code
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//code
|
//code
|
||||||
};
|
};
|
||||||
|
@ -87,10 +89,14 @@ default:
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### d. single-line blocks (lambdas, initializer lists etc.) ####
|
#### d. Brace enclosed initializers ####
|
||||||
|
Unlike single-line functions, you must not insert spaces between the brackets and concluded expressions.<br/>
|
||||||
|
But you must insert a space between the variable name and initializer.
|
||||||
```c++
|
```c++
|
||||||
{} // empty - space before {
|
Class obj {}; // empty
|
||||||
{ body } // spaces around { and before }
|
Class obj {expr};
|
||||||
|
Class obj {expr1, /*...,*/ exprN};
|
||||||
|
QVariantMap map {{"key1", 5}, {"key2", 10}};
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. If blocks ###
|
### 2. If blocks ###
|
||||||
|
@ -173,11 +179,11 @@ All names should be camelCased.
|
||||||
#### a. Type names and namespaces ####
|
#### a. Type names and namespaces ####
|
||||||
Type names and namespaces start with Upper case letter (except POD types).
|
Type names and namespaces start with Upper case letter (except POD types).
|
||||||
```c++
|
```c++
|
||||||
class ClassName {}
|
class ClassName {};
|
||||||
|
|
||||||
struct StructName {}
|
struct StructName {};
|
||||||
|
|
||||||
enum EnumName {}
|
enum EnumName {};
|
||||||
|
|
||||||
typedef QList<ClassName> SomeList;
|
typedef QList<ClassName> SomeList;
|
||||||
|
|
||||||
|
@ -201,7 +207,40 @@ class MyClass
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 8. Misc.###
|
### 8. Header inclusion order.###
|
||||||
|
The headers should be placed in the following order:
|
||||||
|
1. Module header (in .cpp)
|
||||||
|
2. System/Qt/Boost etc. headers (splitted in subcategories if you have many).
|
||||||
|
3. Application headers, starting from *Base* headers.
|
||||||
|
|
||||||
|
The headers should be ordered alphabetically within each group (subgroup).<br/>
|
||||||
|
<br/>
|
||||||
|
Example:
|
||||||
|
```c++
|
||||||
|
// examplewidget.cpp
|
||||||
|
|
||||||
|
#include "examplewidget.h"
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QList>
|
||||||
|
#include <QString>
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
|
#include <libtorrent/version.hpp>
|
||||||
|
|
||||||
|
#include "base/bittorrent/session.h"
|
||||||
|
#include "base/bittorrent/infohash.h"
|
||||||
|
#include "base/utils/fs.h"
|
||||||
|
#include "base/utils/misc.h"
|
||||||
|
#include "base/utils/string.h"
|
||||||
|
#include "ui_examplewidget.h"
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 9. Misc.###
|
||||||
|
|
||||||
* Line breaks for long lines with operation:
|
* Line breaks for long lines with operation:
|
||||||
|
|
||||||
|
@ -211,47 +250,18 @@ a += "b"
|
||||||
+ "d";
|
+ "d";
|
||||||
```
|
```
|
||||||
|
|
||||||
* Initializers
|
|
||||||
|
|
||||||
We allow brace enclosed initializers only for aggregates and arrays/containers.<br />
|
|
||||||
Brace enclosed initializer MUST be used with equality sign if it follows the variable declaration.<br />
|
|
||||||
Brace enclosed initializer MUST be additionally enclosed in parentheses if it is used in constructor initialization list.<br />
|
|
||||||
Some valid use cases:
|
|
||||||
```c++
|
|
||||||
// aggregate
|
|
||||||
Person john = { "John", "Smith", 21 };
|
|
||||||
Person *john = new Person { "John", "Smith", 21 };
|
|
||||||
|
|
||||||
// array
|
|
||||||
int array[] = { 1, 2, 3, 4 };
|
|
||||||
|
|
||||||
// container
|
|
||||||
QHash<QString, QString> map = {
|
|
||||||
{ "key1", "value1" },
|
|
||||||
{ "key2", "value2" }
|
|
||||||
);
|
|
||||||
|
|
||||||
// member array
|
|
||||||
SomeClass::SomeClass(BaseClass *parent)
|
|
||||||
: BaseClass(parent)
|
|
||||||
, m_someArrayMember({ 1, 2, 3, 4 })
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// return from function
|
|
||||||
Person getPersonByName(const QString &name)
|
|
||||||
{
|
|
||||||
// do something
|
|
||||||
return { name, surname, age };
|
|
||||||
}
|
|
||||||
|
|
||||||
// function argument
|
|
||||||
doSomething({ name, surname, age }, someOtherArg);
|
|
||||||
```
|
|
||||||
|
|
||||||
* **auto** keyword
|
* **auto** keyword
|
||||||
|
|
||||||
We allow the use of the **auto** keyword only where it doesn't break the readability of the code (i.e. either we can gather enough information about the type from the right part of the expression, or we do not need to know the exact type), or where it is strictly necessary (for example, to compute the type of a lambda, etc.).<br />
|
We allow the use of the **auto** keyword only where it is strictly necessary
|
||||||
|
(for example, to declare a lambda object, etc.), or where it **enhances** the readability of the code.
|
||||||
|
Declarations for which one can gather enough information about the object interface (type) from its name
|
||||||
|
or the usage pattern (an iterator or a loop variable are good examples of clear patterns)
|
||||||
|
or the right part of the expression nicely fit here.<br/>
|
||||||
|
<br/>
|
||||||
|
When weighing whether to use an auto-typed variable please think about potential reviewers of your code,
|
||||||
|
who will read it as a plain diff (on github.com, for instance). Please make sure that such reviewers can
|
||||||
|
understand the code completely and without excessive effort.<br/>
|
||||||
|
<br/>
|
||||||
Some valid use cases:
|
Some valid use cases:
|
||||||
```c++
|
```c++
|
||||||
template <typename List>
|
template <typename List>
|
||||||
|
@ -274,9 +284,17 @@ auto spinBox = static_cast<QSpinBox*>(sender());
|
||||||
|
|
||||||
* Space around operations eg `a = b + c` or `a=b+c`:
|
* Space around operations eg `a = b + c` or `a=b+c`:
|
||||||
|
|
||||||
Before and after the assignment there should be a space. One exception could be: for loops.
|
Before and after the assignment and other binary (and ternary) operators there should be a space.<br/>
|
||||||
|
There should not be a space between increment/decrement and its operand.<br/>
|
||||||
|
Some valid use cases:
|
||||||
```c++
|
```c++
|
||||||
for (int a=0; a<b; ++b) {
|
a += 20;
|
||||||
|
a = (b <= MAX_B ? b : MAX_B);
|
||||||
|
++a;
|
||||||
|
b--;
|
||||||
|
|
||||||
|
for (int a = 0; a < b; ++b) {
|
||||||
|
// code
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -286,5 +304,5 @@ for (int a=0; a<b; ++b) {
|
||||||
|
|
||||||
* Method definitions aren't allowed in header files
|
* Method definitions aren't allowed in header files
|
||||||
|
|
||||||
### 9. Not covered above###
|
###10. Not covered above###
|
||||||
If something isn't covered above, just follow the same style the file you are editing has. If that particular detail isn't present in the file you are editing, then use whatever the rest of the project uses.
|
If something isn't covered above, just follow the same style the file you are editing has. If that particular detail isn't present in the file you are editing, then use whatever the rest of the project uses.
|
72
COPYING
72
COPYING
|
@ -12,15 +12,15 @@ exception statement from your version.
|
||||||
|
|
||||||
----------
|
----------
|
||||||
|
|
||||||
GNU GENERAL PUBLIC LICENSE
|
GNU GENERAL PUBLIC LICENSE
|
||||||
Version 2, June 1991
|
Version 2, June 1991
|
||||||
|
|
||||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
of this license document, but changing it is not allowed.
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
Preamble
|
Preamble
|
||||||
|
|
||||||
The licenses for most software are designed to take away your
|
The licenses for most software are designed to take away your
|
||||||
freedom to share and change it. By contrast, the GNU General Public
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
@ -70,7 +70,7 @@ patent must be licensed for everyone's free use or not licensed at all.
|
||||||
The precise terms and conditions for copying, distribution and
|
The precise terms and conditions for copying, distribution and
|
||||||
modification follow.
|
modification follow.
|
||||||
|
|
||||||
GNU GENERAL PUBLIC LICENSE
|
GNU GENERAL PUBLIC LICENSE
|
||||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
0. This License applies to any program or other work which contains
|
0. This License applies to any program or other work which contains
|
||||||
|
@ -269,7 +269,7 @@ make exceptions for this. Our decision will be guided by the two goals
|
||||||
of preserving the free status of all derivatives of our free software and
|
of preserving the free status of all derivatives of our free software and
|
||||||
of promoting the sharing and reuse of software generally.
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
NO WARRANTY
|
NO WARRANTY
|
||||||
|
|
||||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
@ -291,64 +291,4 @@ 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
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
POSSIBILITY OF SUCH DAMAGES.
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
How to Apply These Terms to Your New Programs
|
|
||||||
|
|
||||||
If you develop a new program, and you want it to be of the greatest
|
|
||||||
possible use to the public, the best way to achieve this is to make it
|
|
||||||
free software which everyone can redistribute and change under these terms.
|
|
||||||
|
|
||||||
To do so, attach the following notices to the program. It is safest
|
|
||||||
to attach them to the start of each source file to most effectively
|
|
||||||
convey the exclusion of warranty; and each file should have at least
|
|
||||||
the "copyright" line and a pointer to where the full notice is found.
|
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) <year> <name of author>
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
|
||||||
|
|
||||||
If the program is interactive, make it output a short notice like this
|
|
||||||
when it starts in an interactive mode:
|
|
||||||
|
|
||||||
Gnomovision version 69, Copyright (C) year name of author
|
|
||||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
|
||||||
This is free software, and you are welcome to redistribute it
|
|
||||||
under certain conditions; type `show c' for details.
|
|
||||||
|
|
||||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
|
||||||
parts of the General Public License. Of course, the commands you use may
|
|
||||||
be called something other than `show w' and `show c'; they could even be
|
|
||||||
mouse-clicks or menu items--whatever suits your program.
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or your
|
|
||||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
|
||||||
necessary. Here is a sample; alter the names:
|
|
||||||
|
|
||||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
|
||||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
|
||||||
|
|
||||||
<signature of Ty Coon>, 1 April 1989
|
|
||||||
Ty Coon, President of Vice
|
|
||||||
|
|
||||||
This General Public License does not permit incorporating your program into
|
|
||||||
proprietary programs. If your program is a subroutine library, you may
|
|
||||||
consider it more useful to permit linking proprietary applications with the
|
|
||||||
library. If this is what you want to do, use the GNU Library General
|
|
||||||
Public License instead of this License.
|
|
||||||
|
|
|
@ -27,6 +27,13 @@ qbittorrent
|
||||||
|
|
||||||
will install and execute qBittorrent hopefully without any problem.
|
will install and execute qBittorrent hopefully without any problem.
|
||||||
|
|
||||||
|
### Public key:
|
||||||
|
Starting from v3.3.4 all source tarballs and binaries are signed.<br />
|
||||||
|
The key currently used is 4096R/[5B7CC9A2](https://pgp.mit.edu/pks/lookup?op=get&search=0x6E4A2D025B7CC9A2) with fingerprint `D8F3DA77AAC6741053599C136E4A2D025B7CC9A2`.<br />
|
||||||
|
You can also download it from [here](https://github.com/qbittorrent/qBittorrent/raw/master/5B7CC9A2.asc).<br />
|
||||||
|
**PREVIOUSLY** the following key was used to sign the v3.3.4 source tarballs and v3.3.4 Windows installer **only**: 4096R/[520EC6F6](https://pgp.mit.edu/pks/lookup?op=get&search=0xA1ACCAE4520EC6F6) with fingerprint `F4A5FD201B117B1C2AB590E2A1ACCAE4520EC6F6`.<br />
|
||||||
|
|
||||||
|
### Misc:
|
||||||
For more information please visit:
|
For more information please visit:
|
||||||
http://www.qbittorrent.org
|
http://www.qbittorrent.org
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/bin/bash
|
#!/bin/sh
|
||||||
|
|
||||||
aclocal -I m4
|
aclocal -I m4
|
||||||
autoconf
|
autoconf
|
||||||
|
|
|
@ -91,3 +91,16 @@ find_package_handle_standard_args(LibtorrentRasterbar DEFAULT_MSG
|
||||||
mark_as_advanced(LibtorrentRasterbar_INCLUDE_DIR LibtorrentRasterbar_LIBRARY
|
mark_as_advanced(LibtorrentRasterbar_INCLUDE_DIR LibtorrentRasterbar_LIBRARY
|
||||||
LibtorrentRasterbar_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES
|
LibtorrentRasterbar_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES
|
||||||
LibtorrentRasterbar_ENCRYPTION_INDEX)
|
LibtorrentRasterbar_ENCRYPTION_INDEX)
|
||||||
|
|
||||||
|
if (LibtorrentRasterbar_FOUND AND NOT TARGET LibtorrentRasterbar::LibTorrent)
|
||||||
|
add_library(LibtorrentRasterbar::LibTorrent UNKNOWN IMPORTED)
|
||||||
|
|
||||||
|
set_target_properties(LibtorrentRasterbar::LibTorrent PROPERTIES
|
||||||
|
IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
|
||||||
|
IMPORTED_LOCATION "${LibtorrentRasterbar_LIBRARY}"
|
||||||
|
INTERFACE_INCLUDE_DIRECTORIES "${LibtorrentRasterbar_INCLUDE_DIRS}"
|
||||||
|
INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${LibtorrentRasterbar_INCLUDE_DIRS}"
|
||||||
|
INTERFACE_LINK_LIBRARIES "${LibtorrentRasterbar_LIBRARIES}"
|
||||||
|
INTERFACE_COMPILE_OPTIONS "${LibtorrentRasterbar_DEFINITIONS}"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
|
@ -79,3 +79,16 @@ ELSE (QTSINGLEAPPLICATION_FOUND)
|
||||||
ENDIF (QTSINGLEAPPLICATION_FOUND)
|
ENDIF (QTSINGLEAPPLICATION_FOUND)
|
||||||
|
|
||||||
MARK_AS_ADVANCED(QTSINGLEAPPLICATION_INCLUDE_DIR QTSINGLEAPPLICATION_LIBRARY)
|
MARK_AS_ADVANCED(QTSINGLEAPPLICATION_INCLUDE_DIR QTSINGLEAPPLICATION_LIBRARY)
|
||||||
|
|
||||||
|
if(NOT TARGET QtSingleApplication::QtSingleApplication)
|
||||||
|
add_library(QtSingleApplication::QtSingleApplication UNKNOWN IMPORTED)
|
||||||
|
set_target_properties(QtSingleApplication::QtSingleApplication PROPERTIES
|
||||||
|
INTERFACE_INCLUDE_DIRECTORIES "${QTSINGLEAPPLICATION_INCLUDE_DIR}"
|
||||||
|
INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${QTSINGLEAPPLICATION_INCLUDE_DIR}"
|
||||||
|
)
|
||||||
|
if(EXISTS "${QTSINGLEAPPLICATION_LIBRARY}")
|
||||||
|
set_target_properties(QtSingleApplication::QtSingleApplication PROPERTIES
|
||||||
|
IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
|
||||||
|
IMPORTED_LOCATION "${QTSINGLEAPPLICATION_LIBRARY}")
|
||||||
|
endif()
|
||||||
|
endif(NOT TARGET QtSingleApplication::QtSingleApplication)
|
||||||
|
|
17
cmake/Modules/QbtTargetSources.cmake
Normal file
17
cmake/Modules/QbtTargetSources.cmake
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
# a helper function which appends source to the main qBt target
|
||||||
|
# the target name is read from QBT_TARGET_NAME variable
|
||||||
|
# sources file names are relative to the the ${qbt_executable_SOURCE_DIR}
|
||||||
|
|
||||||
|
function (qbt_target_sources)
|
||||||
|
set (_sources_rel "")
|
||||||
|
foreach (_source IN ITEMS ${ARGN})
|
||||||
|
if (IS_ABSOLUTE "${_source}")
|
||||||
|
set(source_abs "${_source}")
|
||||||
|
else()
|
||||||
|
get_filename_component(_source_abs "${_source}" ABSOLUTE)
|
||||||
|
endif()
|
||||||
|
file (RELATIVE_PATH _source_rel "${qbt_executable_SOURCE_DIR}" "${_source_abs}")
|
||||||
|
list (APPEND _sources_rel "${_source_rel}")
|
||||||
|
endforeach()
|
||||||
|
target_sources (${QBT_TARGET_NAME} PRIVATE "${_sources_rel}")
|
||||||
|
endfunction (qbt_target_sources)
|
|
@ -29,16 +29,17 @@ set(Boost_USE_STATIC_LIBS True)
|
||||||
# with usual unix subdirectories (bin, lib, include)
|
# with usual unix subdirectories (bin, lib, include)
|
||||||
# if so, we just need to set CMAKE_SYSTEM_PREFIX_PATH
|
# if so, we just need to set CMAKE_SYSTEM_PREFIX_PATH
|
||||||
# If it is not the case, individual paths need to be specified manually (see below)
|
# If it is not the case, individual paths need to be specified manually (see below)
|
||||||
set(COMMON_INSTALL_PREFIX "c:/usr")
|
set(COMMON_INSTALL_PREFIX "c:/usr" CACHE PATH "Prefix used to install all the required libraries")
|
||||||
list(APPEND CMAKE_SYSTEM_PREFIX_PATH "${COMMON_INSTALL_PREFIX}")
|
list(APPEND CMAKE_SYSTEM_PREFIX_PATH "${COMMON_INSTALL_PREFIX}")
|
||||||
|
|
||||||
# If two version of Qt are installed, separate prefixes are needed most likely
|
# If two version of Qt are installed, separate prefixes are needed most likely
|
||||||
set(QT4_INSTALL_PREFIX "${COMMON_INSTALL_PREFIX}/lib/qt4")
|
set(QT4_INSTALL_PREFIX "${COMMON_INSTALL_PREFIX}/lib/qt4" CACHE PATH "Prefix where Qt4 is installed")
|
||||||
set(QT5_INSTALL_PREFIX "${COMMON_INSTALL_PREFIX}/lib/qt5")
|
set(QT5_INSTALL_PREFIX "${COMMON_INSTALL_PREFIX}/lib/qt5" CACHE PATH "Prefix where Qt5 is installed")
|
||||||
|
|
||||||
# it is safe to set Qt dirs even if their files are directly in the prefix
|
# it is safe to set Qt dirs even if their files are directly in the prefix
|
||||||
# Qt4
|
# Qt4
|
||||||
if(NOT QT5)
|
if(NOT QT5)
|
||||||
|
# for qt 4 we need qmake, Qt5 provides cmake config files
|
||||||
LIST(APPEND CMAKE_PROGRAM_PATH "${QT4_INSTALL_PREFIX}/bin/")
|
LIST(APPEND CMAKE_PROGRAM_PATH "${QT4_INSTALL_PREFIX}/bin/")
|
||||||
endif(NOT QT5)
|
endif(NOT QT5)
|
||||||
|
|
||||||
|
|
12
conf.pri.in
12
conf.pri.in
|
@ -6,8 +6,16 @@ DATADIR = @EXPAND_DATADIR@
|
||||||
MANPREFIX = @EXPAND_MANDIR@
|
MANPREFIX = @EXPAND_MANDIR@
|
||||||
|
|
||||||
QMAKE_CXXFLAGS += @QBT_CONF_EXTRA_CFLAGS@
|
QMAKE_CXXFLAGS += @QBT_CONF_EXTRA_CFLAGS@
|
||||||
INCLUDEPATH += @QBT_CONF_INCLUDES@
|
|
||||||
LIBS += @LDFLAGS@ @LIBS@
|
EXTERNAL_INCLUDES = @QBT_CONF_INCLUDES@
|
||||||
|
EXTERNAL_INCLUDES -= $$QMAKE_DEFAULT_INCDIRS
|
||||||
|
# added /usr/local/include due to Qt 5.7.0 bug on macOS
|
||||||
|
macx: EXTERNAL_INCLUDES += "/usr/local/include"
|
||||||
|
INCLUDEPATH += $$EXTERNAL_INCLUDES
|
||||||
|
|
||||||
|
EXTERNAL_LIBS = @LDFLAGS@ @LIBS@
|
||||||
|
EXTERNAL_LIBS -= $$QMAKE_DEFAULT_LIBDIRS
|
||||||
|
LIBS += $$EXTERNAL_LIBS
|
||||||
|
|
||||||
CONFIG += @QBT_ADD_CONFIG@
|
CONFIG += @QBT_ADD_CONFIG@
|
||||||
CONFIG -= @QBT_REMOVE_CONFIG@
|
CONFIG -= @QBT_REMOVE_CONFIG@
|
||||||
|
|
13
configure
vendored
13
configure
vendored
|
@ -4257,6 +4257,17 @@ else
|
||||||
$as_echo "no" >&6; }
|
$as_echo "no" >&6; }
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OS is macOS" >&5
|
||||||
|
$as_echo_n "checking whether OS is macOS... " >&6; }
|
||||||
|
if expr "$host_os" : ".*darwin.*" > /dev/null; then :
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||||
|
$as_echo "yes" >&6; }
|
||||||
|
enable_qt_dbus=no
|
||||||
|
else
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||||
|
$as_echo "no" >&6; }
|
||||||
|
fi
|
||||||
|
|
||||||
# Require 0.23 pkg-config
|
# Require 0.23 pkg-config
|
||||||
|
|
||||||
|
|
||||||
|
@ -5090,7 +5101,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
|
||||||
int
|
int
|
||||||
main ()
|
main ()
|
||||||
{
|
{
|
||||||
boost::system::system_category
|
boost::system::error_category *a = 0;
|
||||||
;
|
;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,6 +67,12 @@ AS_IF([expr "$host_os" : ".*freebsd.*" > /dev/null],
|
||||||
LIBS="-lexecinfo $LIBS"],
|
LIBS="-lexecinfo $LIBS"],
|
||||||
[AC_MSG_RESULT([no])])
|
[AC_MSG_RESULT([no])])
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([whether OS is macOS])
|
||||||
|
AS_IF([expr "$host_os" : ".*darwin.*" > /dev/null],
|
||||||
|
[AC_MSG_RESULT([yes])
|
||||||
|
enable_qt_dbus=no],
|
||||||
|
[AC_MSG_RESULT([no])])
|
||||||
|
|
||||||
# Require 0.23 pkg-config
|
# Require 0.23 pkg-config
|
||||||
PKG_PROG_PKG_CONFIG([0.23])
|
PKG_PROG_PKG_CONFIG([0.23])
|
||||||
AS_IF([test "x$PKG_CONFIG" = "x"],
|
AS_IF([test "x$PKG_CONFIG" = "x"],
|
||||||
|
|
0
dist/mac/CMakeLists.txt
vendored
Normal file
0
dist/mac/CMakeLists.txt
vendored
Normal file
2
dist/mac/bundle.cmake
vendored
Normal file
2
dist/mac/bundle.cmake
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
include(BundleUtilities)
|
||||||
|
fixup_bundle("$ENV{DESTDIR}/${CMAKE_INSTALL_PREFIX}/qbittorrent.app" "" "")
|
BIN
dist/qt-translations/qt_ar.qm
vendored
BIN
dist/qt-translations/qt_ar.qm
vendored
Binary file not shown.
BIN
dist/qt-translations/qt_ca.qm
vendored
BIN
dist/qt-translations/qt_ca.qm
vendored
Binary file not shown.
BIN
dist/qt-translations/qt_cs.qm
vendored
BIN
dist/qt-translations/qt_cs.qm
vendored
Binary file not shown.
BIN
dist/qt-translations/qt_da.qm
vendored
BIN
dist/qt-translations/qt_da.qm
vendored
Binary file not shown.
BIN
dist/qt-translations/qt_de.qm
vendored
BIN
dist/qt-translations/qt_de.qm
vendored
Binary file not shown.
BIN
dist/qt-translations/qt_es.qm
vendored
BIN
dist/qt-translations/qt_es.qm
vendored
Binary file not shown.
BIN
dist/qt-translations/qt_fa.qm
vendored
Normal file
BIN
dist/qt-translations/qt_fa.qm
vendored
Normal file
Binary file not shown.
BIN
dist/qt-translations/qt_fi.qm
vendored
BIN
dist/qt-translations/qt_fi.qm
vendored
Binary file not shown.
BIN
dist/qt-translations/qt_fr.qm
vendored
BIN
dist/qt-translations/qt_fr.qm
vendored
Binary file not shown.
BIN
dist/qt-translations/qt_gl.qm
vendored
BIN
dist/qt-translations/qt_gl.qm
vendored
Binary file not shown.
BIN
dist/qt-translations/qt_he.qm
vendored
BIN
dist/qt-translations/qt_he.qm
vendored
Binary file not shown.
BIN
dist/qt-translations/qt_hu.qm
vendored
BIN
dist/qt-translations/qt_hu.qm
vendored
Binary file not shown.
BIN
dist/qt-translations/qt_it.qm
vendored
BIN
dist/qt-translations/qt_it.qm
vendored
Binary file not shown.
BIN
dist/qt-translations/qt_ja.qm
vendored
BIN
dist/qt-translations/qt_ja.qm
vendored
Binary file not shown.
BIN
dist/qt-translations/qt_ko.qm
vendored
BIN
dist/qt-translations/qt_ko.qm
vendored
Binary file not shown.
BIN
dist/qt-translations/qt_lt.qm
vendored
BIN
dist/qt-translations/qt_lt.qm
vendored
Binary file not shown.
BIN
dist/qt-translations/qt_pl.qm
vendored
BIN
dist/qt-translations/qt_pl.qm
vendored
Binary file not shown.
BIN
dist/qt-translations/qt_pt.qm
vendored
BIN
dist/qt-translations/qt_pt.qm
vendored
Binary file not shown.
BIN
dist/qt-translations/qt_ru.qm
vendored
BIN
dist/qt-translations/qt_ru.qm
vendored
Binary file not shown.
BIN
dist/qt-translations/qt_sk.qm
vendored
BIN
dist/qt-translations/qt_sk.qm
vendored
Binary file not shown.
BIN
dist/qt-translations/qt_sl.qm
vendored
Normal file
BIN
dist/qt-translations/qt_sl.qm
vendored
Normal file
Binary file not shown.
BIN
dist/qt-translations/qt_sv.qm
vendored
BIN
dist/qt-translations/qt_sv.qm
vendored
Binary file not shown.
BIN
dist/qt-translations/qt_uk.qm
vendored
BIN
dist/qt-translations/qt_uk.qm
vendored
Binary file not shown.
BIN
dist/qt-translations/qt_zh_CN.qm
vendored
BIN
dist/qt-translations/qt_zh_CN.qm
vendored
Binary file not shown.
BIN
dist/qt-translations/qt_zh_TW.qm
vendored
BIN
dist/qt-translations/qt_zh_TW.qm
vendored
Binary file not shown.
BIN
dist/qt-translations/qtbase_ca.qm
vendored
Normal file
BIN
dist/qt-translations/qtbase_ca.qm
vendored
Normal file
Binary file not shown.
BIN
dist/qt-translations/qtbase_cs.qm
vendored
Normal file
BIN
dist/qt-translations/qtbase_cs.qm
vendored
Normal file
Binary file not shown.
BIN
dist/qt-translations/qtbase_de.qm
vendored
Normal file
BIN
dist/qt-translations/qtbase_de.qm
vendored
Normal file
Binary file not shown.
BIN
dist/qt-translations/qtbase_fi.qm
vendored
Normal file
BIN
dist/qt-translations/qtbase_fi.qm
vendored
Normal file
Binary file not shown.
BIN
dist/qt-translations/qtbase_fr.qm
vendored
Normal file
BIN
dist/qt-translations/qtbase_fr.qm
vendored
Normal file
Binary file not shown.
BIN
dist/qt-translations/qtbase_he.qm
vendored
Normal file
BIN
dist/qt-translations/qtbase_he.qm
vendored
Normal file
Binary file not shown.
BIN
dist/qt-translations/qtbase_hu.qm
vendored
Normal file
BIN
dist/qt-translations/qtbase_hu.qm
vendored
Normal file
Binary file not shown.
BIN
dist/qt-translations/qtbase_it.qm
vendored
Normal file
BIN
dist/qt-translations/qtbase_it.qm
vendored
Normal file
Binary file not shown.
BIN
dist/qt-translations/qtbase_ja.qm
vendored
Normal file
BIN
dist/qt-translations/qtbase_ja.qm
vendored
Normal file
Binary file not shown.
BIN
dist/qt-translations/qtbase_ko.qm
vendored
Normal file
BIN
dist/qt-translations/qtbase_ko.qm
vendored
Normal file
Binary file not shown.
BIN
dist/qt-translations/qtbase_lv.qm
vendored
Normal file
BIN
dist/qt-translations/qtbase_lv.qm
vendored
Normal file
Binary file not shown.
BIN
dist/qt-translations/qtbase_pl.qm
vendored
Normal file
BIN
dist/qt-translations/qtbase_pl.qm
vendored
Normal file
Binary file not shown.
BIN
dist/qt-translations/qtbase_ru.qm
vendored
Normal file
BIN
dist/qt-translations/qtbase_ru.qm
vendored
Normal file
Binary file not shown.
BIN
dist/qt-translations/qtbase_sk.qm
vendored
Normal file
BIN
dist/qt-translations/qtbase_sk.qm
vendored
Normal file
Binary file not shown.
BIN
dist/qt-translations/qtbase_uk.qm
vendored
Normal file
BIN
dist/qt-translations/qtbase_uk.qm
vendored
Normal file
Binary file not shown.
29
dist/windows/README.txt
vendored
29
dist/windows/README.txt
vendored
|
@ -1,12 +1,12 @@
|
||||||
TRANSLATORS:
|
TRANSLATORS:
|
||||||
|
|
||||||
1. Use an editor that has NSIS syntax highlighting(eg Notepad++/Geany). This will
|
1. Use an editor that has NSIS syntax highlighting(eg Notepad++/Geany). This will
|
||||||
make your life easier.
|
make your life easier.
|
||||||
2. Open the relevant .nsi file that exists in the folder named
|
2. Open the relevant .nsi file that exists in the folder named
|
||||||
"installer-translations"
|
"installer-translations"
|
||||||
3. Lines starting with ";" are considered comments. These include the
|
3. Lines starting with ";" are considered comments. These include the
|
||||||
english message to help you with the translation.
|
english message to help you with the translation.
|
||||||
4. Edit only the part inside the quotation marks(""). Unless you know
|
4. Edit only the part inside the quotation marks(""). Unless you know
|
||||||
what you are doing.
|
what you are doing.
|
||||||
5. Save the files with utf8 encoding and BOM.
|
5. Save the files with utf8 encoding and BOM.
|
||||||
6. Submit your changes: 1) as a pull request to the official git repo or
|
6. Submit your changes: 1) as a pull request to the official git repo or
|
||||||
|
@ -16,17 +16,13 @@ TRANSLATORS:
|
||||||
PACKAGERS:
|
PACKAGERS:
|
||||||
|
|
||||||
You will need NSIS and upx to make the installer. You need a unicode version of NSIS.
|
You will need NSIS and upx to make the installer. You need a unicode version of NSIS.
|
||||||
I tested with NSIS 3.0a0.
|
I tested with NSIS 3.0 (final).
|
||||||
|
|
||||||
1. Open the options.nsi file in an editor and change line that contains
|
1. Open the options.nsi file in an editor and change line that contains
|
||||||
"!define PROG_VERSION "3.0.3"" to the version of qbittorrent you just built.
|
"!define PROG_VERSION "3.0.3"" to the version of qbittorrent you just built.
|
||||||
2. Extract the plugins found in the folder "nsis plugins" into your
|
2. Extract the plugins found in the folder "nsis plugins" into your
|
||||||
NSIS's unicode Plugin directory(usually C:\Program Files\NSIS\Plugins\x86-unicode).
|
NSIS's unicode Plugin directory(usually C:\Program Files\NSIS\Plugins\x86-unicode).
|
||||||
Only the *.dll files are needed. Don't use the .dll from UAC.zip, use the one from "UAC Unicode.zip".
|
Only the *.dll files are needed. Use the unicode version of the dlls.
|
||||||
NOTE: To build the unicode version of UAC with MSVC2008 you need:
|
|
||||||
a) the sources from UAC.zip
|
|
||||||
b) apply the util.cpp.diff from "UAC Unicode.zip" to util.cpp
|
|
||||||
c) in a msvc command prompt issue: cl.exe /O1s /GS- /GR- /EHs-c- /Zl /LD /DUNICODE RunAs.cpp uac.cpp util.cpp /link kernel32.lib user32.lib shell32.lib advapi32.lib ole32.lib /DLL /MANIFEST:NO /OUT:uac.dll
|
|
||||||
3. The script you need to compile is "qbittorrent.nsi". It includes all other necessary scripts.
|
3. The script you need to compile is "qbittorrent.nsi". It includes all other necessary scripts.
|
||||||
4. The script expects the following file tree:
|
4. The script expects the following file tree:
|
||||||
|
|
||||||
|
@ -53,10 +49,11 @@ qbittorrent.exe
|
||||||
qbittorrent.nsi
|
qbittorrent.nsi
|
||||||
qt.conf
|
qt.conf
|
||||||
translations.nsi
|
translations.nsi
|
||||||
|
UAC.nsh
|
||||||
uninstaller.nsi
|
uninstaller.nsi
|
||||||
|
|
||||||
|
|
||||||
5. "license.txt" is a text file that contains the text rendered
|
5. "license.txt" is a text file that contains the text rendered
|
||||||
from src\gui\gpl.html or the text contained in COPYING
|
from src\gui\gpl.html or the text contained in COPYING
|
||||||
6. "qbittorrent.exe" is the compiled binary file.
|
6. "qbittorrent.exe" is the compiled binary file.
|
||||||
|
|
||||||
|
@ -64,7 +61,7 @@ SCRIPT HACKERS:
|
||||||
|
|
||||||
If you add any new LangString variable to the scripts you NEED to provide
|
If you add any new LangString variable to the scripts you NEED to provide
|
||||||
"translations" of it to all the .nsi files inside "installer-translations.
|
"translations" of it to all the .nsi files inside "installer-translations.
|
||||||
You can always leave the english string but you have to use all the LANG_<lang name>
|
You can always leave the english string but you have to use all the LANG_<lang name>
|
||||||
for the given variable. Otherwise, if the user chooses a language that you
|
for the given variable. Otherwise, if the user chooses a language that you
|
||||||
haven't provided a LANG_<lang name> for your variable then your string will be empty.
|
haven't provided a LANG_<lang name> for your variable then your string will be empty.
|
||||||
Don't worry though, NSIS throws warnings for this when compiling the scripts.
|
Don't worry though, NSIS throws warnings for this when compiling the scripts.
|
||||||
|
|
2
dist/windows/UAC.nsh
vendored
2
dist/windows/UAC.nsh
vendored
|
@ -228,6 +228,8 @@ pop $_LOGICLIB_TEMP
|
||||||
!undef _UAC_ParseDefineFlags_orin_this
|
!undef _UAC_ParseDefineFlags_orin_this
|
||||||
!ifdef _UAC_ParseDefineFlags_orin_f1
|
!ifdef _UAC_ParseDefineFlags_orin_f1
|
||||||
!undef _UAC_ParseDefineFlags_orin_f1
|
!undef _UAC_ParseDefineFlags_orin_f1
|
||||||
|
!endif
|
||||||
|
!ifdef _UAC_ParseDefineFlags_orin_f2
|
||||||
!undef _UAC_ParseDefineFlags_orin_f2
|
!undef _UAC_ParseDefineFlags_orin_f2
|
||||||
!endif
|
!endif
|
||||||
!macroend
|
!macroend
|
||||||
|
|
|
@ -17,7 +17,7 @@ LangString inst_firewallinfo ${LANG_PORTUGUESE} "Adicionando regra à firewall d
|
||||||
;LangString inst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before installing."
|
;LangString inst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before installing."
|
||||||
LangString inst_warning ${LANG_PORTUGUESE} "O qBittorrent está a ser executado. Feche a aplicação antes de instalar esta versão."
|
LangString inst_warning ${LANG_PORTUGUESE} "O qBittorrent está a ser executado. Feche a aplicação antes de instalar esta versão."
|
||||||
;LangString inst_uninstall_question ${LANG_ENGLISH} "A previous installation was detected. It will be uninstalled without deleting user settings."
|
;LangString inst_uninstall_question ${LANG_ENGLISH} "A previous installation was detected. It will be uninstalled without deleting user settings."
|
||||||
LangString inst_uninstall_question ${LANG_PORTUGUESE} "A previous installation was detected. It will be uninstalled without deleting user settings."
|
LangString inst_uninstall_question ${LANG_PORTUGUESE} "Uma antiga instalação foi encontrada.Essa mesma será desinstalada sem apagar as definições do usuário."
|
||||||
;LangString inst_unist ${LANG_ENGLISH} "Uninstalling previous version."
|
;LangString inst_unist ${LANG_ENGLISH} "Uninstalling previous version."
|
||||||
LangString inst_unist ${LANG_PORTUGUESE} "A desinstalar versão anterior."
|
LangString inst_unist ${LANG_PORTUGUESE} "A desinstalar versão anterior."
|
||||||
;LangString launch_qbt ${LANG_ENGLISH} "Launch qBittorrent."
|
;LangString launch_qbt ${LANG_ENGLISH} "Launch qBittorrent."
|
||||||
|
|
|
@ -17,7 +17,7 @@ LangString inst_firewallinfo ${LANG_PORTUGUESEBR} "Adicionando regra no firewall
|
||||||
;LangString inst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before installing."
|
;LangString inst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before installing."
|
||||||
LangString inst_warning ${LANG_PORTUGUESEBR} "qBittorrent está rodando. Por favor feche a aplicação antes de instalar."
|
LangString inst_warning ${LANG_PORTUGUESEBR} "qBittorrent está rodando. Por favor feche a aplicação antes de instalar."
|
||||||
;LangString inst_uninstall_question ${LANG_ENGLISH} "A previous installation was detected. It will be uninstalled without deleting user settings."
|
;LangString inst_uninstall_question ${LANG_ENGLISH} "A previous installation was detected. It will be uninstalled without deleting user settings."
|
||||||
LangString inst_uninstall_question ${LANG_PORTUGUESEBR} "A previous installation was detected. It will be uninstalled without deleting user settings."
|
LangString inst_uninstall_question ${LANG_PORTUGUESEBR} "Uma instalação anterior foi detectada. Ela será desistalada sem deletar as configurações de usuário."
|
||||||
;LangString inst_unist ${LANG_ENGLISH} "Uninstalling previous version."
|
;LangString inst_unist ${LANG_ENGLISH} "Uninstalling previous version."
|
||||||
LangString inst_unist ${LANG_PORTUGUESEBR} "Desinstalando versão anterior."
|
LangString inst_unist ${LANG_PORTUGUESEBR} "Desinstalando versão anterior."
|
||||||
;LangString launch_qbt ${LANG_ENGLISH} "Launch qBittorrent."
|
;LangString launch_qbt ${LANG_ENGLISH} "Launch qBittorrent."
|
||||||
|
|
44
dist/windows/installer-translations/turkish.nsi
vendored
44
dist/windows/installer-translations/turkish.nsi
vendored
|
@ -1,51 +1,51 @@
|
||||||
;Installer strings
|
;Installer strings
|
||||||
|
|
||||||
;LangString inst_qbt_req ${LANG_ENGLISH} "qBittorrent (required)"
|
;LangString inst_qbt_req ${LANG_ENGLISH} "qBittorrent (required)"
|
||||||
LangString inst_qbt_req ${LANG_TURKISH} "qBittorrent (required)"
|
LangString inst_qbt_req ${LANG_TURKISH} "qBittorrent (zorunlu)"
|
||||||
;LangString inst_dekstop ${LANG_ENGLISH} "Create Desktop Shortcut"
|
;LangString inst_dekstop ${LANG_ENGLISH} "Create Desktop Shortcut"
|
||||||
LangString inst_dekstop ${LANG_TURKISH} "Create Desktop Shortcut"
|
LangString inst_dekstop ${LANG_TURKISH} "Masaüstü Kısayolu oluştur"
|
||||||
;LangString inst_startmenu ${LANG_ENGLISH} "Create Start Menu Shortcut"
|
;LangString inst_startmenu ${LANG_ENGLISH} "Create Start Menu Shortcut"
|
||||||
LangString inst_startmenu ${LANG_TURKISH} "Create Start Menu Shortcut"
|
LangString inst_startmenu ${LANG_TURKISH} "Başlangıç Menüsü Kısayolu oluştur"
|
||||||
;LangString inst_torrent ${LANG_ENGLISH} "Open .torrent files with qBittorrent"
|
;LangString inst_torrent ${LANG_ENGLISH} "Open .torrent files with qBittorrent"
|
||||||
LangString inst_torrent ${LANG_TURKISH} "Open .torrent files with qBittorrent"
|
LangString inst_torrent ${LANG_TURKISH} ".torrent dosyalarını qBittorrent ile aç"
|
||||||
;LangString inst_magnet ${LANG_ENGLISH} "Open magnet links with qBittorrent"
|
;LangString inst_magnet ${LANG_ENGLISH} "Open magnet links with qBittorrent"
|
||||||
LangString inst_magnet ${LANG_TURKISH} "Open magnet links with qBittorrent"
|
LangString inst_magnet ${LANG_TURKISH} "Magnet bağlantılarını qBittorrent ile aç"
|
||||||
;LangString inst_firewall ${LANG_ENGLISH} "Add Windows Firewall rule"
|
;LangString inst_firewall ${LANG_ENGLISH} "Add Windows Firewall rule"
|
||||||
LangString inst_firewall ${LANG_TURKISH} "Add Windows Firewall rule"
|
LangString inst_firewall ${LANG_TURKISH} "Windows Güvenlik Duvarı kuralı ekle"
|
||||||
;LangString inst_firewallinfo ${LANG_ENGLISH} "Adding Windows Firewall rule"
|
;LangString inst_firewallinfo ${LANG_ENGLISH} "Adding Windows Firewall rule"
|
||||||
LangString inst_firewallinfo ${LANG_TURKISH} "Adding Windows Firewall rule"
|
LangString inst_firewallinfo ${LANG_TURKISH} "Windows Güvenlik Duvarı kuralı ekleniyor"
|
||||||
;LangString inst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before installing."
|
;LangString inst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before installing."
|
||||||
LangString inst_warning ${LANG_TURKISH} "qBittorrent is running. Please close the application before installing."
|
LangString inst_warning ${LANG_TURKISH} "qBittorrent çalışıyor. Lütfen yüklemeden önce uygulamayı kapatın."
|
||||||
;LangString inst_uninstall_question ${LANG_ENGLISH} "A previous installation was detected. It will be uninstalled without deleting user settings."
|
;LangString inst_uninstall_question ${LANG_ENGLISH} "A previous installation was detected. It will be uninstalled without deleting user settings."
|
||||||
LangString inst_uninstall_question ${LANG_TURKISH} "A previous installation was detected. It will be uninstalled without deleting user settings."
|
LangString inst_uninstall_question ${LANG_TURKISH} "Önceki bir kurulum algılandı. Kullanıcı ayarları silinmeden kaldırılacaktır."
|
||||||
;LangString inst_unist ${LANG_ENGLISH} "Uninstalling previous version."
|
;LangString inst_unist ${LANG_ENGLISH} "Uninstalling previous version."
|
||||||
LangString inst_unist ${LANG_TURKISH} "Uninstalling previous version."
|
LangString inst_unist ${LANG_TURKISH} "Önceki sürüm kaldırılıyor."
|
||||||
;LangString launch_qbt ${LANG_ENGLISH} "Launch qBittorrent."
|
;LangString launch_qbt ${LANG_ENGLISH} "Launch qBittorrent."
|
||||||
LangString launch_qbt ${LANG_TURKISH} "Launch qBittorrent."
|
LangString launch_qbt ${LANG_TURKISH} "qBittorrent'i çalıştır."
|
||||||
|
|
||||||
|
|
||||||
;------------------------------------
|
;------------------------------------
|
||||||
;Uninstaller strings
|
;Uninstaller strings
|
||||||
|
|
||||||
;LangString remove_files ${LANG_ENGLISH} "Remove files"
|
;LangString remove_files ${LANG_ENGLISH} "Remove files"
|
||||||
LangString remove_files ${LANG_TURKISH} "Remove files"
|
LangString remove_files ${LANG_TURKISH} "Dosyaları kaldır"
|
||||||
;LangString remove_shortcuts ${LANG_ENGLISH} "Remove shortcuts"
|
;LangString remove_shortcuts ${LANG_ENGLISH} "Remove shortcuts"
|
||||||
LangString remove_shortcuts ${LANG_TURKISH} "Remove shortcuts"
|
LangString remove_shortcuts ${LANG_TURKISH} "Kısayolları kaldır"
|
||||||
;LangString remove_associations ${LANG_ENGLISH} "Remove file associations"
|
;LangString remove_associations ${LANG_ENGLISH} "Remove file associations"
|
||||||
LangString remove_associations ${LANG_TURKISH} "Remove file associations"
|
LangString remove_associations ${LANG_TURKISH} "Dosya ilişkilendirmelerini kaldır"
|
||||||
;LangString remove_registry ${LANG_ENGLISH} "Remove registry keys"
|
;LangString remove_registry ${LANG_ENGLISH} "Remove registry keys"
|
||||||
LangString remove_registry ${LANG_TURKISH} "Remove registry keys"
|
LangString remove_registry ${LANG_TURKISH} "Kayıt defteri anahtarlarını kaldır"
|
||||||
;LangString remove_conf ${LANG_ENGLISH} "Remove configuration files"
|
;LangString remove_conf ${LANG_ENGLISH} "Remove configuration files"
|
||||||
LangString remove_conf ${LANG_TURKISH} "Remove configuration files"
|
LangString remove_conf ${LANG_TURKISH} "Yapılandırma dosyalarını kaldır"
|
||||||
;LangString remove_firewall ${LANG_ENGLISH} "Remove Windows Firewall rule"
|
;LangString remove_firewall ${LANG_ENGLISH} "Remove Windows Firewall rule"
|
||||||
LangString remove_firewall ${LANG_TURKISH} "Remove Windows Firewall rule"
|
LangString remove_firewall ${LANG_TURKISH} "Windows Güvenlik Duvarı kuralını kaldır"
|
||||||
;LangString remove_firewallinfo ${LANG_ENGLISH} "Removing Windows Firewall rule"
|
;LangString remove_firewallinfo ${LANG_ENGLISH} "Removing Windows Firewall rule"
|
||||||
LangString remove_firewallinfo ${LANG_TURKISH} "Removing Windows Firewall rule"
|
LangString remove_firewallinfo ${LANG_TURKISH} "Windows Güvenlik Duvarı kuralı kaldırılıyor"
|
||||||
;LangString remove_cache ${LANG_ENGLISH} "Remove torrents and cached data"
|
;LangString remove_cache ${LANG_ENGLISH} "Remove torrents and cached data"
|
||||||
LangString remove_cache ${LANG_TURKISH} "Remove torrents and cached data"
|
LangString remove_cache ${LANG_TURKISH} "Torrentleri ve önbelleklenen verileri kaldır"
|
||||||
;LangString uninst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before uninstalling."
|
;LangString uninst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before uninstalling."
|
||||||
LangString uninst_warning ${LANG_TURKISH} "qBittorrent is running. Please close the application before uninstalling."
|
LangString uninst_warning ${LANG_TURKISH} "qBittorrent çalışıyor. Lütfen kaldırmadan önce uygulamayı kapatın."
|
||||||
;LangString uninst_tor_warn ${LANG_ENGLISH} "Not removing .torrent association. It is associated with:"
|
;LangString uninst_tor_warn ${LANG_ENGLISH} "Not removing .torrent association. It is associated with:"
|
||||||
LangString uninst_tor_warn ${LANG_TURKISH} "Not removing .torrent association. It is associated with:"
|
LangString uninst_tor_warn ${LANG_TURKISH} ".torrent ilişkilendirmesi kaldırılmıyor. Şununla ilişkilendirildi:"
|
||||||
;LangString uninst_mag_warn ${LANG_ENGLISH} "Not removing magnet association. It is associated with:"
|
;LangString uninst_mag_warn ${LANG_ENGLISH} "Not removing magnet association. It is associated with:"
|
||||||
LangString uninst_mag_warn ${LANG_TURKISH} "Not removing magnet association. It is associated with:"
|
LangString uninst_mag_warn ${LANG_TURKISH} "Magnet ilişkilendirmesi kaldırılmıyor. Şununla ilişkilendirildi:"
|
||||||
|
|
21
dist/windows/installer.nsi
vendored
21
dist/windows/installer.nsi
vendored
|
@ -30,12 +30,13 @@ Section $(inst_qbt_req) ;"qBittorrent (required)"
|
||||||
File "qbittorrent.pdb"
|
File "qbittorrent.pdb"
|
||||||
File "qt.conf"
|
File "qt.conf"
|
||||||
File /oname=translations\qt_ar.qm "translations\qt_ar.qm"
|
File /oname=translations\qt_ar.qm "translations\qt_ar.qm"
|
||||||
|
File /oname=translations\qt_bg.qm "translations\qt_bg.qm"
|
||||||
File /oname=translations\qt_ca.qm "translations\qt_ca.qm"
|
File /oname=translations\qt_ca.qm "translations\qt_ca.qm"
|
||||||
File /oname=translations\qt_cs.qm "translations\qt_cs.qm"
|
File /oname=translations\qt_cs.qm "translations\qt_cs.qm"
|
||||||
File /oname=translations\qt_da.qm "translations\qt_da.qm"
|
File /oname=translations\qt_da.qm "translations\qt_da.qm"
|
||||||
File /oname=translations\qt_de.qm "translations\qt_de.qm"
|
File /oname=translations\qt_de.qm "translations\qt_de.qm"
|
||||||
File /oname=translations\qt_en.qm "translations\qt_en.qm"
|
|
||||||
File /oname=translations\qt_es.qm "translations\qt_es.qm"
|
File /oname=translations\qt_es.qm "translations\qt_es.qm"
|
||||||
|
File /oname=translations\qt_eu.qm "translations\qt_eu.qm"
|
||||||
File /oname=translations\qt_fa.qm "translations\qt_fa.qm"
|
File /oname=translations\qt_fa.qm "translations\qt_fa.qm"
|
||||||
File /oname=translations\qt_fi.qm "translations\qt_fi.qm"
|
File /oname=translations\qt_fi.qm "translations\qt_fi.qm"
|
||||||
File /oname=translations\qt_fr.qm "translations\qt_fr.qm"
|
File /oname=translations\qt_fr.qm "translations\qt_fr.qm"
|
||||||
|
@ -46,15 +47,33 @@ Section $(inst_qbt_req) ;"qBittorrent (required)"
|
||||||
File /oname=translations\qt_ja.qm "translations\qt_ja.qm"
|
File /oname=translations\qt_ja.qm "translations\qt_ja.qm"
|
||||||
File /oname=translations\qt_ko.qm "translations\qt_ko.qm"
|
File /oname=translations\qt_ko.qm "translations\qt_ko.qm"
|
||||||
File /oname=translations\qt_lt.qm "translations\qt_lt.qm"
|
File /oname=translations\qt_lt.qm "translations\qt_lt.qm"
|
||||||
|
File /oname=translations\qt_nl.qm "translations\qt_nl.qm"
|
||||||
File /oname=translations\qt_pl.qm "translations\qt_pl.qm"
|
File /oname=translations\qt_pl.qm "translations\qt_pl.qm"
|
||||||
File /oname=translations\qt_pt.qm "translations\qt_pt.qm"
|
File /oname=translations\qt_pt.qm "translations\qt_pt.qm"
|
||||||
|
File /oname=translations\qt_pt_BR.qm "translations\qt_pt_BR.qm"
|
||||||
File /oname=translations\qt_ru.qm "translations\qt_ru.qm"
|
File /oname=translations\qt_ru.qm "translations\qt_ru.qm"
|
||||||
File /oname=translations\qt_sk.qm "translations\qt_sk.qm"
|
File /oname=translations\qt_sk.qm "translations\qt_sk.qm"
|
||||||
File /oname=translations\qt_sl.qm "translations\qt_sl.qm"
|
File /oname=translations\qt_sl.qm "translations\qt_sl.qm"
|
||||||
File /oname=translations\qt_sv.qm "translations\qt_sv.qm"
|
File /oname=translations\qt_sv.qm "translations\qt_sv.qm"
|
||||||
|
File /oname=translations\qt_tr.qm "translations\qt_tr.qm"
|
||||||
File /oname=translations\qt_uk.qm "translations\qt_uk.qm"
|
File /oname=translations\qt_uk.qm "translations\qt_uk.qm"
|
||||||
File /oname=translations\qt_zh_CN.qm "translations\qt_zh_CN.qm"
|
File /oname=translations\qt_zh_CN.qm "translations\qt_zh_CN.qm"
|
||||||
File /oname=translations\qt_zh_TW.qm "translations\qt_zh_TW.qm"
|
File /oname=translations\qt_zh_TW.qm "translations\qt_zh_TW.qm"
|
||||||
|
File /oname=translations\qtbase_ca.qm "translations\qtbase_ca.qm"
|
||||||
|
File /oname=translations\qtbase_cs.qm "translations\qtbase_cs.qm"
|
||||||
|
File /oname=translations\qtbase_de.qm "translations\qtbase_de.qm"
|
||||||
|
File /oname=translations\qtbase_fi.qm "translations\qtbase_fi.qm"
|
||||||
|
File /oname=translations\qtbase_fr.qm "translations\qtbase_fr.qm"
|
||||||
|
File /oname=translations\qtbase_he.qm "translations\qtbase_he.qm"
|
||||||
|
File /oname=translations\qtbase_hu.qm "translations\qtbase_hu.qm"
|
||||||
|
File /oname=translations\qtbase_it.qm "translations\qtbase_it.qm"
|
||||||
|
File /oname=translations\qtbase_ja.qm "translations\qtbase_ja.qm"
|
||||||
|
File /oname=translations\qtbase_ko.qm "translations\qtbase_ko.qm"
|
||||||
|
File /oname=translations\qtbase_lv.qm "translations\qtbase_lv.qm"
|
||||||
|
File /oname=translations\qtbase_pl.qm "translations\qtbase_pl.qm"
|
||||||
|
File /oname=translations\qtbase_ru.qm "translations\qtbase_ru.qm"
|
||||||
|
File /oname=translations\qtbase_sk.qm "translations\qtbase_sk.qm"
|
||||||
|
File /oname=translations\qtbase_uk.qm "translations\qtbase_uk.qm"
|
||||||
|
|
||||||
; Write the installation path into the registry
|
; Write the installation path into the registry
|
||||||
WriteRegStr HKLM "Software\qBittorrent" "InstallLocation" "$INSTDIR"
|
WriteRegStr HKLM "Software\qBittorrent" "InstallLocation" "$INSTDIR"
|
||||||
|
|
BIN
dist/windows/nsis plugins/UAC Unicode.zip
vendored
BIN
dist/windows/nsis plugins/UAC Unicode.zip
vendored
Binary file not shown.
BIN
dist/windows/nsis plugins/UAC.zip
vendored
BIN
dist/windows/nsis plugins/UAC.zip
vendored
Binary file not shown.
2
dist/windows/qt.conf
vendored
2
dist/windows/qt.conf
vendored
|
@ -2,4 +2,4 @@
|
||||||
Translations = translations
|
Translations = translations
|
||||||
|
|
||||||
[Platforms]
|
[Platforms]
|
||||||
WindowsArguments = dpiawareness=1
|
WindowsArguments = dpiawareness=0
|
||||||
|
|
21
dist/windows/uninstaller.nsi
vendored
21
dist/windows/uninstaller.nsi
vendored
|
@ -6,12 +6,13 @@
|
||||||
Delete "$INSTDIR\qbittorrent.pdb"
|
Delete "$INSTDIR\qbittorrent.pdb"
|
||||||
Delete "$INSTDIR\qt.conf"
|
Delete "$INSTDIR\qt.conf"
|
||||||
Delete "$INSTDIR\translations\qt_ar.qm"
|
Delete "$INSTDIR\translations\qt_ar.qm"
|
||||||
|
Delete "$INSTDIR\translations\qt_bg.qm"
|
||||||
Delete "$INSTDIR\translations\qt_ca.qm"
|
Delete "$INSTDIR\translations\qt_ca.qm"
|
||||||
Delete "$INSTDIR\translations\qt_cs.qm"
|
Delete "$INSTDIR\translations\qt_cs.qm"
|
||||||
Delete "$INSTDIR\translations\qt_da.qm"
|
Delete "$INSTDIR\translations\qt_da.qm"
|
||||||
Delete "$INSTDIR\translations\qt_de.qm"
|
Delete "$INSTDIR\translations\qt_de.qm"
|
||||||
Delete "$INSTDIR\translations\qt_en.qm"
|
|
||||||
Delete "$INSTDIR\translations\qt_es.qm"
|
Delete "$INSTDIR\translations\qt_es.qm"
|
||||||
|
Delete "$INSTDIR\translations\qt_eu.qm"
|
||||||
Delete "$INSTDIR\translations\qt_fa.qm"
|
Delete "$INSTDIR\translations\qt_fa.qm"
|
||||||
Delete "$INSTDIR\translations\qt_fi.qm"
|
Delete "$INSTDIR\translations\qt_fi.qm"
|
||||||
Delete "$INSTDIR\translations\qt_fr.qm"
|
Delete "$INSTDIR\translations\qt_fr.qm"
|
||||||
|
@ -22,15 +23,33 @@
|
||||||
Delete "$INSTDIR\translations\qt_ja.qm"
|
Delete "$INSTDIR\translations\qt_ja.qm"
|
||||||
Delete "$INSTDIR\translations\qt_ko.qm"
|
Delete "$INSTDIR\translations\qt_ko.qm"
|
||||||
Delete "$INSTDIR\translations\qt_lt.qm"
|
Delete "$INSTDIR\translations\qt_lt.qm"
|
||||||
|
Delete "$INSTDIR\translations\qt_nl.qm"
|
||||||
Delete "$INSTDIR\translations\qt_pl.qm"
|
Delete "$INSTDIR\translations\qt_pl.qm"
|
||||||
|
Delete "$INSTDIR\translations\qt_pt_BR.qm"
|
||||||
Delete "$INSTDIR\translations\qt_pt.qm"
|
Delete "$INSTDIR\translations\qt_pt.qm"
|
||||||
Delete "$INSTDIR\translations\qt_ru.qm"
|
Delete "$INSTDIR\translations\qt_ru.qm"
|
||||||
Delete "$INSTDIR\translations\qt_sk.qm"
|
Delete "$INSTDIR\translations\qt_sk.qm"
|
||||||
Delete "$INSTDIR\translations\qt_sl.qm"
|
Delete "$INSTDIR\translations\qt_sl.qm"
|
||||||
Delete "$INSTDIR\translations\qt_sv.qm"
|
Delete "$INSTDIR\translations\qt_sv.qm"
|
||||||
|
Delete "$INSTDIR\translations\qt_tr.qm"
|
||||||
Delete "$INSTDIR\translations\qt_uk.qm"
|
Delete "$INSTDIR\translations\qt_uk.qm"
|
||||||
Delete "$INSTDIR\translations\qt_zh_CN.qm"
|
Delete "$INSTDIR\translations\qt_zh_CN.qm"
|
||||||
Delete "$INSTDIR\translations\qt_zh_TW.qm"
|
Delete "$INSTDIR\translations\qt_zh_TW.qm"
|
||||||
|
Delete "$INSTDIR\translations\qtbase_ca.qm"
|
||||||
|
Delete "$INSTDIR\translations\qtbase_cs.qm"
|
||||||
|
Delete "$INSTDIR\translations\qtbase_de.qm"
|
||||||
|
Delete "$INSTDIR\translations\qtbase_fi.qm"
|
||||||
|
Delete "$INSTDIR\translations\qtbase_fr.qm"
|
||||||
|
Delete "$INSTDIR\translations\qtbase_he.qm"
|
||||||
|
Delete "$INSTDIR\translations\qtbase_hu.qm"
|
||||||
|
Delete "$INSTDIR\translations\qtbase_it.qm"
|
||||||
|
Delete "$INSTDIR\translations\qtbase_ja.qm"
|
||||||
|
Delete "$INSTDIR\translations\qtbase_ko.qm"
|
||||||
|
Delete "$INSTDIR\translations\qtbase_lv.qm"
|
||||||
|
Delete "$INSTDIR\translations\qtbase_pl.qm"
|
||||||
|
Delete "$INSTDIR\translations\qtbase_ru.qm"
|
||||||
|
Delete "$INSTDIR\translations\qtbase_sk.qm"
|
||||||
|
Delete "$INSTDIR\translations\qtbase_uk.qm"
|
||||||
Delete "$INSTDIR\uninst.exe"
|
Delete "$INSTDIR\uninst.exe"
|
||||||
|
|
||||||
; Remove directories used
|
; Remove directories used
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
# and this notice are preserved. This file is offered as-is, without any
|
# and this notice are preserved. This file is offered as-is, without any
|
||||||
# warranty.
|
# warranty.
|
||||||
|
|
||||||
#serial 17
|
#serial 18
|
||||||
|
|
||||||
AC_DEFUN([AX_BOOST_SYSTEM],
|
AC_DEFUN([AX_BOOST_SYSTEM],
|
||||||
[
|
[
|
||||||
|
@ -68,9 +68,10 @@ AC_DEFUN([AX_BOOST_SYSTEM],
|
||||||
ax_cv_boost_system,
|
ax_cv_boost_system,
|
||||||
[AC_LANG_PUSH([C++])
|
[AC_LANG_PUSH([C++])
|
||||||
CXXFLAGS_SAVE=$CXXFLAGS
|
CXXFLAGS_SAVE=$CXXFLAGS
|
||||||
|
CXXFLAGS=
|
||||||
|
|
||||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include <boost/system/error_code.hpp>]],
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include <boost/system/error_code.hpp>]],
|
||||||
[[boost::system::system_category]])],
|
[[boost::system::error_category *a = 0;]])],
|
||||||
ax_cv_boost_system=yes, ax_cv_boost_system=no)
|
ax_cv_boost_system=yes, ax_cv_boost_system=no)
|
||||||
CXXFLAGS=$CXXFLAGS_SAVE
|
CXXFLAGS=$CXXFLAGS_SAVE
|
||||||
AC_LANG_POP([C++])
|
AC_LANG_POP([C++])
|
||||||
|
|
20
macxconf.pri
20
macxconf.pri
|
@ -34,6 +34,8 @@ qt_translations.files = \
|
||||||
$$QT_LANG_PATH/qt_da.qm \
|
$$QT_LANG_PATH/qt_da.qm \
|
||||||
$$QT_LANG_PATH/qt_de.qm \
|
$$QT_LANG_PATH/qt_de.qm \
|
||||||
$$QT_LANG_PATH/qt_es.qm \
|
$$QT_LANG_PATH/qt_es.qm \
|
||||||
|
$$QT_LANG_PATH/qt_eu.qm \
|
||||||
|
$$QT_LANG_PATH/qt_fa.qm \
|
||||||
$$QT_LANG_PATH/qt_fi.qm \
|
$$QT_LANG_PATH/qt_fi.qm \
|
||||||
$$QT_LANG_PATH/qt_fr.qm \
|
$$QT_LANG_PATH/qt_fr.qm \
|
||||||
$$QT_LANG_PATH/qt_gl.qm \
|
$$QT_LANG_PATH/qt_gl.qm \
|
||||||
|
@ -49,11 +51,27 @@ qt_translations.files = \
|
||||||
$$QT_LANG_PATH/qt_pt_BR.qm \
|
$$QT_LANG_PATH/qt_pt_BR.qm \
|
||||||
$$QT_LANG_PATH/qt_ru.qm \
|
$$QT_LANG_PATH/qt_ru.qm \
|
||||||
$$QT_LANG_PATH/qt_sk.qm \
|
$$QT_LANG_PATH/qt_sk.qm \
|
||||||
|
$$QT_LANG_PATH/qt_sl.qm \
|
||||||
$$QT_LANG_PATH/qt_sv.qm \
|
$$QT_LANG_PATH/qt_sv.qm \
|
||||||
$$QT_LANG_PATH/qt_tr.qm \
|
$$QT_LANG_PATH/qt_tr.qm \
|
||||||
$$QT_LANG_PATH/qt_uk.qm \
|
$$QT_LANG_PATH/qt_uk.qm \
|
||||||
$$QT_LANG_PATH/qt_zh_CN.qm \
|
$$QT_LANG_PATH/qt_zh_CN.qm \
|
||||||
$$QT_LANG_PATH/qt_zh_TW.qm
|
$$QT_LANG_PATH/qt_zh_TW.qm \
|
||||||
|
$$QT_LANG_PATH/qtbase_ca.qm \
|
||||||
|
$$QT_LANG_PATH/qtbase_cs.qm \
|
||||||
|
$$QT_LANG_PATH/qtbase_de.qm \
|
||||||
|
$$QT_LANG_PATH/qtbase_fi.qm \
|
||||||
|
$$QT_LANG_PATH/qtbase_fr.qm \
|
||||||
|
$$QT_LANG_PATH/qtbase_he.qm \
|
||||||
|
$$QT_LANG_PATH/qtbase_hu.qm \
|
||||||
|
$$QT_LANG_PATH/qtbase_it.qm \
|
||||||
|
$$QT_LANG_PATH/qtbase_ja.qm \
|
||||||
|
$$QT_LANG_PATH/qtbase_ko.qm \
|
||||||
|
$$QT_LANG_PATH/qtbase_lv.qm \
|
||||||
|
$$QT_LANG_PATH/qtbase_pl.qm \
|
||||||
|
$$QT_LANG_PATH/qtbase_ru.qm \
|
||||||
|
$$QT_LANG_PATH/qtbase_sk.qm \
|
||||||
|
$$QT_LANG_PATH/qtbase_uk.qm
|
||||||
QMAKE_BUNDLE_DATA += qt_translations
|
QMAKE_BUNDLE_DATA += qt_translations
|
||||||
|
|
||||||
ICON = $$DIST_PATH/qbittorrent_mac.icns
|
ICON = $$DIST_PATH/qbittorrent_mac.icns
|
||||||
|
|
|
@ -3,15 +3,9 @@ set(CMAKE_CXX_STANDARD "11")
|
||||||
add_definitions(-DBOOST_NO_CXX11_RVALUE_REFERENCES)
|
add_definitions(-DBOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||||
|
|
||||||
include(MacroLinkQtComponents)
|
include(MacroLinkQtComponents)
|
||||||
|
include(QbtTargetSources)
|
||||||
|
|
||||||
find_package(LibtorrentRasterbar REQUIRED)
|
find_package(LibtorrentRasterbar REQUIRED)
|
||||||
include_directories(SYSTEM ${LibtorrentRasterbar_INCLUDE_DIRS})
|
|
||||||
add_compile_options(${LibtorrentRasterbar_DEFINITIONS})
|
|
||||||
|
|
||||||
# Boost
|
|
||||||
set(Boost_USE_MULTITHREADED ON)
|
|
||||||
find_package(Boost 1.35 REQUIRED COMPONENTS system)
|
|
||||||
include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
|
|
||||||
|
|
||||||
# Qt
|
# Qt
|
||||||
if (QT5)
|
if (QT5)
|
||||||
|
@ -88,16 +82,22 @@ set(QBT_USES_QT5 ${QT5})
|
||||||
|
|
||||||
configure_file(config.h.cmakein ${CMAKE_CURRENT_BINARY_DIR}/config.h)
|
configure_file(config.h.cmakein ${CMAKE_CURRENT_BINARY_DIR}/config.h)
|
||||||
|
|
||||||
|
if (GUI)
|
||||||
|
set(QBT_TARGET_NAME qbittorrent)
|
||||||
|
else (GUI)
|
||||||
|
set(QBT_TARGET_NAME qbittorrent-nox)
|
||||||
|
endif (GUI)
|
||||||
|
|
||||||
add_subdirectory(base)
|
|
||||||
|
|
||||||
if (SYSTEM_QTSINGLEAPPLICATION)
|
if (SYSTEM_QTSINGLEAPPLICATION)
|
||||||
find_package(QtSingleApplication REQUIRED)
|
find_package(QtSingleApplication REQUIRED)
|
||||||
include_directories(${QTSINGLEAPPLICATION_INCLUDE_DIR})
|
|
||||||
else (SYSTEM_QTSINGLEAPPLICATION)
|
else (SYSTEM_QTSINGLEAPPLICATION)
|
||||||
include_directories(app/qtsingleapplication)
|
add_subdirectory(app/qtsingleapplication)
|
||||||
endif (SYSTEM_QTSINGLEAPPLICATION)
|
endif (SYSTEM_QTSINGLEAPPLICATION)
|
||||||
|
|
||||||
|
add_subdirectory(app)
|
||||||
|
add_subdirectory(base)
|
||||||
|
|
||||||
if (GUI)
|
if (GUI)
|
||||||
add_subdirectory(gui)
|
add_subdirectory(gui)
|
||||||
endif (GUI)
|
endif (GUI)
|
||||||
|
@ -106,4 +106,3 @@ if (WEBUI)
|
||||||
add_subdirectory(webui)
|
add_subdirectory(webui)
|
||||||
endif (WEBUI)
|
endif (WEBUI)
|
||||||
|
|
||||||
add_subdirectory(app)
|
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
|
project(qbt_executable)
|
||||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
set(QBT_APP_HEADERS
|
set(QBT_APP_HEADERS
|
||||||
application.h
|
application.h
|
||||||
|
filelogger.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(QBT_APP_SOURCES
|
set(QBT_APP_SOURCES
|
||||||
application.cpp
|
application.cpp
|
||||||
|
filelogger.cpp
|
||||||
main.cpp
|
main.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -84,39 +87,93 @@ list(APPEND QBT_APP_HEADERS upgrade.h)
|
||||||
list(APPEND QBT_TARGET_LIBRARIES qbt_base)
|
list(APPEND QBT_TARGET_LIBRARIES qbt_base)
|
||||||
|
|
||||||
if (GUI)
|
if (GUI)
|
||||||
set(QBT_TARGET_NAME qbittorrent)
|
|
||||||
list(APPEND QBT_TARGET_LIBRARIES qbt_searchengine qbt_gui)
|
list(APPEND QBT_TARGET_LIBRARIES qbt_searchengine qbt_gui)
|
||||||
include_directories(../gui
|
include_directories(../gui
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/../gui
|
${CMAKE_CURRENT_BINARY_DIR}/../gui
|
||||||
)
|
)
|
||||||
else (GUI)
|
|
||||||
set(QBT_TARGET_NAME qbittorrent-nox)
|
|
||||||
endif (GUI)
|
endif (GUI)
|
||||||
|
|
||||||
if (WEBUI)
|
if (WEBUI)
|
||||||
list(APPEND QBT_TARGET_LIBRARIES qbt_webui)
|
list(APPEND QBT_TARGET_LIBRARIES qbt_webui)
|
||||||
endif (WEBUI)
|
endif (WEBUI)
|
||||||
|
|
||||||
|
# we have to include resources into the bundle
|
||||||
|
if (APPLE)
|
||||||
|
set(OSX_RES_SRC_DIR "${qBittorrent_SOURCE_DIR}/dist/mac")
|
||||||
|
list(APPEND QBT_APP_RESOURCE_SOURCE
|
||||||
|
"${OSX_RES_SRC_DIR}/qt.conf"
|
||||||
|
"${OSX_RES_SRC_DIR}/qBitTorrentDocument.icns"
|
||||||
|
"${OSX_RES_SRC_DIR}/qbittorrent_mac.icns")
|
||||||
|
set_source_files_properties(
|
||||||
|
"${OSX_RES_SRC_DIR}/qt.conf"
|
||||||
|
"${OSX_RES_SRC_DIR}/qBitTorrentDocument.icns"
|
||||||
|
"${OSX_RES_SRC_DIR}/qbittorrent_mac.icns"
|
||||||
|
PROPERTIES
|
||||||
|
MACOSX_PACKAGE_LOCATION Resources)
|
||||||
|
set(QT_TR_DIR "${qBittorrent_SOURCE_DIR}/dist/qt-translations")
|
||||||
|
set(QT_TRANSLATIONS
|
||||||
|
${QT_TR_DIR}/qt_ar.qm
|
||||||
|
${QT_TR_DIR}/qt_bg.qm
|
||||||
|
${QT_TR_DIR}/qt_ca.qm
|
||||||
|
${QT_TR_DIR}/qt_cs.qm
|
||||||
|
${QT_TR_DIR}/qt_da.qm
|
||||||
|
${QT_TR_DIR}/qt_de.qm
|
||||||
|
${QT_TR_DIR}/qt_es.qm
|
||||||
|
${QT_TR_DIR}/qt_eu.qm
|
||||||
|
${QT_TR_DIR}/qt_fi.qm
|
||||||
|
${QT_TR_DIR}/qt_fr.qm
|
||||||
|
${QT_TR_DIR}/qt_gl.qm
|
||||||
|
${QT_TR_DIR}/qt_he.qm
|
||||||
|
${QT_TR_DIR}/qt_hu.qm
|
||||||
|
${QT_TR_DIR}/qt_it.qm
|
||||||
|
${QT_TR_DIR}/qt_ja.qm
|
||||||
|
${QT_TR_DIR}/qt_ko.qm
|
||||||
|
${QT_TR_DIR}/qt_lt.qm
|
||||||
|
${QT_TR_DIR}/qt_nl.qm
|
||||||
|
${QT_TR_DIR}/qt_pl.qm
|
||||||
|
${QT_TR_DIR}/qt_pt.qm
|
||||||
|
${QT_TR_DIR}/qt_pt_BR.qm
|
||||||
|
${QT_TR_DIR}/qt_ru.qm
|
||||||
|
${QT_TR_DIR}/qt_sk.qm
|
||||||
|
${QT_TR_DIR}/qt_sv.qm
|
||||||
|
${QT_TR_DIR}/qt_tr.qm
|
||||||
|
${QT_TR_DIR}/qt_uk.qm
|
||||||
|
${QT_TR_DIR}/qt_zh_CN.qm
|
||||||
|
${QT_TR_DIR}/qt_zh_TW.qm
|
||||||
|
)
|
||||||
|
list(APPEND QBT_APP_RESOURCE_SOURCE ${QT_TRANSLATIONS})
|
||||||
|
set_source_files_properties(${QT_TRANSLATIONS}
|
||||||
|
PROPERTIES MACOSX_PACKAGE_LOCATION translations)
|
||||||
|
endif (APPLE)
|
||||||
|
|
||||||
add_executable(${QBT_TARGET_NAME} ${QBT_APP_HEADERS} ${QBT_APP_SOURCES} ${QBT_QM_FILES} ${QBT_APP_RESOURCE_SOURCE})
|
add_executable(${QBT_TARGET_NAME} ${QBT_APP_HEADERS} ${QBT_APP_SOURCES} ${QBT_QM_FILES} ${QBT_APP_RESOURCE_SOURCE})
|
||||||
set_target_properties(${QBT_TARGET_NAME} PROPERTIES AUTOUIC True)
|
set_target_properties(${QBT_TARGET_NAME}
|
||||||
|
PROPERTIES
|
||||||
|
AUTOUIC True
|
||||||
|
AUTORCC True
|
||||||
|
MACOSX_BUNDLE True
|
||||||
|
)
|
||||||
|
|
||||||
if (GUI)
|
if (GUI AND WIN32)
|
||||||
if (WIN32)
|
set_target_properties(${QBT_TARGET_NAME} PROPERTIES WIN32_EXECUTABLE True)
|
||||||
set_target_properties(${QBT_TARGET_NAME} PROPERTIES WIN32_EXECUTABLE True)
|
endif (GUI AND WIN32)
|
||||||
endif (WIN32)
|
|
||||||
if (APPLE)
|
|
||||||
set_target_properties(${QBT_TARGET_NAME} PROPERTIES MACOSX_BUNDLE True)
|
|
||||||
endif (APPLE)
|
|
||||||
endif (GUI)
|
|
||||||
|
|
||||||
target_link_libraries(${QBT_TARGET_NAME} ${QBT_TARGET_LIBRARIES})
|
target_link_libraries(${QBT_TARGET_NAME} ${QBT_TARGET_LIBRARIES} QtSingleApplication::QtSingleApplication)
|
||||||
|
|
||||||
if (SYSTEM_QTSINGLEAPPLICATION)
|
if (APPLE)
|
||||||
target_link_libraries(${QBT_TARGET_NAME} ${QTSINGLEAPPLICATION_LIBRARIES})
|
set(qbt_BUNDLE_NAME "${CMAKE_PROJECT_NAME}")
|
||||||
else (SYSTEM_QTSINGLEAPPLICATION)
|
set_target_properties(${QBT_TARGET_NAME} PROPERTIES
|
||||||
add_subdirectory(qtsingleapplication)
|
MACOSX_BUNDLE_BUNDLE_NAME "${qbt_BUNDLE_NAME}"
|
||||||
target_link_libraries(${QBT_TARGET_NAME} qtsingleapplication)
|
MACOSX_BUNDLE_INFO_PLIST ${qBittorrent_SOURCE_DIR}/dist/mac/Info.plist
|
||||||
endif (SYSTEM_QTSINGLEAPPLICATION)
|
)
|
||||||
|
endif (APPLE)
|
||||||
|
|
||||||
# installation
|
# installation
|
||||||
install(TARGETS ${QBT_TARGET_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime)
|
install(TARGETS ${QBT_TARGET_NAME}
|
||||||
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||||
|
BUNDLE DESTINATION .
|
||||||
|
COMPONENT runtime)
|
||||||
|
|
||||||
|
if (APPLE)
|
||||||
|
install(SCRIPT ${OSX_RES_SRC_DIR}/bundle.cmake)
|
||||||
|
endif (APPLE)
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include <QLibraryInfo>
|
#include <QLibraryInfo>
|
||||||
#include <QSysInfo>
|
#include <QSysInfo>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
|
#include <QAtomicInt>
|
||||||
|
|
||||||
#ifndef DISABLE_GUI
|
#ifndef DISABLE_GUI
|
||||||
#include "gui/guiiconprovider.h"
|
#include "gui/guiiconprovider.h"
|
||||||
|
@ -48,7 +49,7 @@
|
||||||
#endif // Q_OS_MAC
|
#endif // Q_OS_MAC
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "addnewtorrentdialog.h"
|
#include "addnewtorrentdialog.h"
|
||||||
#include "shutdownconfirm.h"
|
#include "shutdownconfirmdlg.h"
|
||||||
#else // DISABLE_GUI
|
#else // DISABLE_GUI
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#endif // DISABLE_GUI
|
#endif // DISABLE_GUI
|
||||||
|
@ -69,6 +70,7 @@
|
||||||
#include "base/net/smtp.h"
|
#include "base/net/smtp.h"
|
||||||
#include "base/net/downloadmanager.h"
|
#include "base/net/downloadmanager.h"
|
||||||
#include "base/net/geoipmanager.h"
|
#include "base/net/geoipmanager.h"
|
||||||
|
#include "base/net/proxyconfigurationmanager.h"
|
||||||
#include "base/bittorrent/session.h"
|
#include "base/bittorrent/session.h"
|
||||||
#include "base/bittorrent/torrenthandle.h"
|
#include "base/bittorrent/torrenthandle.h"
|
||||||
|
|
||||||
|
@ -96,9 +98,7 @@ namespace
|
||||||
Application::Application(const QString &id, int &argc, char **argv)
|
Application::Application(const QString &id, int &argc, char **argv)
|
||||||
: BaseApplication(id, argc, argv)
|
: BaseApplication(id, argc, argv)
|
||||||
, m_running(false)
|
, m_running(false)
|
||||||
#ifndef DISABLE_GUI
|
, m_shutdownAct(ShutdownDialogAction::Exit)
|
||||||
, m_shutdownAct(ShutdownAction::None)
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
Logger::initInstance();
|
Logger::initInstance();
|
||||||
SettingsStorage::initInstance();
|
SettingsStorage::initInstance();
|
||||||
|
@ -132,6 +132,13 @@ Application::Application(const QString &id, int &argc, char **argv)
|
||||||
Logger::instance()->addMessage(tr("qBittorrent %1 started", "qBittorrent v3.2.0alpha started").arg(VERSION));
|
Logger::instance()->addMessage(tr("qBittorrent %1 started", "qBittorrent v3.2.0alpha started").arg(VERSION));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef DISABLE_GUI
|
||||||
|
QPointer<MainWindow> Application::mainWindow()
|
||||||
|
{
|
||||||
|
return m_window;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool Application::isFileLoggerEnabled() const
|
bool Application::isFileLoggerEnabled() const
|
||||||
{
|
{
|
||||||
return settings()->loadValue(KEY_FILELOGGER_ENABLED, true).toBool();
|
return settings()->loadValue(KEY_FILELOGGER_ENABLED, true).toBool();
|
||||||
|
@ -236,6 +243,50 @@ void Application::processMessage(const QString &message)
|
||||||
m_paramsQueue.append(params);
|
m_paramsQueue.append(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Application::runExternalProgram(BitTorrent::TorrentHandle *const torrent) const
|
||||||
|
{
|
||||||
|
QString program = Preferences::instance()->getAutoRunProgram();
|
||||||
|
program.replace("%N", torrent->name());
|
||||||
|
program.replace("%L", torrent->category());
|
||||||
|
program.replace("%F", Utils::Fs::toNativePath(torrent->contentPath()));
|
||||||
|
program.replace("%R", Utils::Fs::toNativePath(torrent->rootPath()));
|
||||||
|
program.replace("%D", Utils::Fs::toNativePath(torrent->savePath()));
|
||||||
|
program.replace("%C", QString::number(torrent->filesCount()));
|
||||||
|
program.replace("%Z", QString::number(torrent->totalSize()));
|
||||||
|
program.replace("%T", torrent->currentTracker());
|
||||||
|
program.replace("%I", torrent->hash());
|
||||||
|
|
||||||
|
Logger *logger = Logger::instance();
|
||||||
|
logger->addMessage(tr("Torrent: %1, running external program, command: %2").arg(torrent->name()).arg(program));
|
||||||
|
|
||||||
|
#if defined(Q_OS_UNIX)
|
||||||
|
QProcess::startDetached(QLatin1String("/bin/sh"), {QLatin1String("-c"), program});
|
||||||
|
#elif defined(Q_OS_WIN) // test cmd: `echo "%F" > "c:\ab ba.txt"`
|
||||||
|
program.prepend(QLatin1String("\"")).append(QLatin1String("\""));
|
||||||
|
program.prepend(Utils::Misc::windowsSystemPath() + QLatin1String("\\cmd.exe /C "));
|
||||||
|
const int cmdMaxLength = 32768; // max length (incl. terminate char) for `lpCommandLine` in `CreateProcessW()`
|
||||||
|
if ((program.size() + 1) > cmdMaxLength) {
|
||||||
|
logger->addMessage(tr("Torrent: %1, run external program command too long (length > %2), execution failed.").arg(torrent->name()).arg(cmdMaxLength), Log::CRITICAL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
STARTUPINFOW si = {0};
|
||||||
|
si.cb = sizeof(si);
|
||||||
|
PROCESS_INFORMATION pi = {0};
|
||||||
|
|
||||||
|
WCHAR *arg = new WCHAR[program.size() + 1];
|
||||||
|
program.toWCharArray(arg);
|
||||||
|
arg[program.size()] = L'\0';
|
||||||
|
if (CreateProcessW(NULL, arg, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) {
|
||||||
|
CloseHandle(pi.hProcess);
|
||||||
|
CloseHandle(pi.hThread);
|
||||||
|
}
|
||||||
|
delete[] arg;
|
||||||
|
#else
|
||||||
|
QProcess::startDetached(program);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void Application::sendNotificationEmail(BitTorrent::TorrentHandle *const torrent)
|
void Application::sendNotificationEmail(BitTorrent::TorrentHandle *const torrent)
|
||||||
{
|
{
|
||||||
// Prepare mail content
|
// Prepare mail content
|
||||||
|
@ -260,75 +311,58 @@ void Application::torrentFinished(BitTorrent::TorrentHandle *const torrent)
|
||||||
Preferences *const pref = Preferences::instance();
|
Preferences *const pref = Preferences::instance();
|
||||||
|
|
||||||
// AutoRun program
|
// AutoRun program
|
||||||
if (pref->isAutoRunEnabled()) {
|
if (pref->isAutoRunEnabled())
|
||||||
QString program = pref->getAutoRunProgram();
|
runExternalProgram(torrent);
|
||||||
|
|
||||||
program.replace("%N", torrent->name());
|
|
||||||
program.replace("%L", torrent->category());
|
|
||||||
program.replace("%F", Utils::Fs::toNativePath(torrent->contentPath()));
|
|
||||||
program.replace("%R", Utils::Fs::toNativePath(torrent->rootPath()));
|
|
||||||
program.replace("%D", Utils::Fs::toNativePath(torrent->savePath()));
|
|
||||||
program.replace("%C", QString::number(torrent->filesCount()));
|
|
||||||
program.replace("%Z", QString::number(torrent->totalSize()));
|
|
||||||
program.replace("%T", torrent->currentTracker());
|
|
||||||
program.replace("%I", torrent->hash());
|
|
||||||
|
|
||||||
QProcess::startDetached(program);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mail notification
|
// Mail notification
|
||||||
if (pref->isMailNotificationEnabled())
|
if (pref->isMailNotificationEnabled()) {
|
||||||
|
Logger::instance()->addMessage(tr("Torrent: %1, sending mail notification").arg(torrent->name()));
|
||||||
sendNotificationEmail(torrent);
|
sendNotificationEmail(torrent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::allTorrentsFinished()
|
void Application::allTorrentsFinished()
|
||||||
{
|
{
|
||||||
#ifndef DISABLE_GUI
|
|
||||||
Preferences *const pref = Preferences::instance();
|
Preferences *const pref = Preferences::instance();
|
||||||
|
bool isExit = pref->shutdownqBTWhenDownloadsComplete();
|
||||||
|
bool isShutdown = pref->shutdownWhenDownloadsComplete();
|
||||||
|
bool isSuspend = pref->suspendWhenDownloadsComplete();
|
||||||
|
bool isHibernate = pref->hibernateWhenDownloadsComplete();
|
||||||
|
|
||||||
bool will_shutdown = (pref->shutdownWhenDownloadsComplete()
|
bool haveAction = isExit || isShutdown || isSuspend || isHibernate;
|
||||||
|| pref->shutdownqBTWhenDownloadsComplete()
|
if (!haveAction) return;
|
||||||
|| pref->suspendWhenDownloadsComplete()
|
|
||||||
|| pref->hibernateWhenDownloadsComplete());
|
|
||||||
|
|
||||||
// Auto-Shutdown
|
ShutdownDialogAction action = ShutdownDialogAction::Exit;
|
||||||
if (will_shutdown) {
|
if (isSuspend)
|
||||||
bool suspend = pref->suspendWhenDownloadsComplete();
|
action = ShutdownDialogAction::Suspend;
|
||||||
bool hibernate = pref->hibernateWhenDownloadsComplete();
|
else if (isHibernate)
|
||||||
bool shutdown = pref->shutdownWhenDownloadsComplete();
|
action = ShutdownDialogAction::Hibernate;
|
||||||
|
else if (isShutdown)
|
||||||
|
action = ShutdownDialogAction::Shutdown;
|
||||||
|
|
||||||
// Confirm shutdown
|
#ifndef DISABLE_GUI
|
||||||
ShutdownAction action = ShutdownAction::None;
|
// ask confirm
|
||||||
if (suspend)
|
if ((action == ShutdownDialogAction::Exit) && (pref->dontConfirmAutoExit())) {
|
||||||
action = ShutdownAction::Suspend;
|
// do nothing & skip confirm
|
||||||
else if (hibernate)
|
}
|
||||||
action = ShutdownAction::Hibernate;
|
else {
|
||||||
else if (shutdown)
|
if (!ShutdownConfirmDlg::askForConfirmation(action)) return;
|
||||||
action = ShutdownAction::Shutdown;
|
|
||||||
|
|
||||||
if ((action == ShutdownAction::None) && (!pref->dontConfirmAutoExit())) {
|
|
||||||
if (!ShutdownConfirmDlg::askForConfirmation(action))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else { //exit and shutdown
|
|
||||||
if (!ShutdownConfirmDlg::askForConfirmation(action))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Actually shut down
|
|
||||||
if (suspend || hibernate || shutdown) {
|
|
||||||
qDebug("Preparing for auto-shutdown because all downloads are complete!");
|
|
||||||
// Disabling it for next time
|
|
||||||
pref->setShutdownWhenDownloadsComplete(false);
|
|
||||||
pref->setSuspendWhenDownloadsComplete(false);
|
|
||||||
pref->setHibernateWhenDownloadsComplete(false);
|
|
||||||
// Make sure preferences are synced before exiting
|
|
||||||
m_shutdownAct = action;
|
|
||||||
}
|
|
||||||
qDebug("Exiting the application");
|
|
||||||
exit();
|
|
||||||
}
|
}
|
||||||
#endif // DISABLE_GUI
|
#endif // DISABLE_GUI
|
||||||
|
|
||||||
|
// Actually shut down
|
||||||
|
if (action != ShutdownDialogAction::Exit) {
|
||||||
|
qDebug("Preparing for auto-shutdown because all downloads are complete!");
|
||||||
|
// Disabling it for next time
|
||||||
|
pref->setShutdownWhenDownloadsComplete(false);
|
||||||
|
pref->setSuspendWhenDownloadsComplete(false);
|
||||||
|
pref->setHibernateWhenDownloadsComplete(false);
|
||||||
|
// Make sure preferences are synced before exiting
|
||||||
|
m_shutdownAct = action;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug("Exiting the application");
|
||||||
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Application::sendParams(const QStringList ¶ms)
|
bool Application::sendParams(const QStringList ¶ms)
|
||||||
|
@ -362,6 +396,7 @@ void Application::processParams(const QStringList ¶ms)
|
||||||
|
|
||||||
int Application::exec(const QStringList ¶ms)
|
int Application::exec(const QStringList ¶ms)
|
||||||
{
|
{
|
||||||
|
Net::ProxyConfigurationManager::initInstance();
|
||||||
Net::DownloadManager::initInstance();
|
Net::DownloadManager::initInstance();
|
||||||
#ifdef DISABLE_GUI
|
#ifdef DISABLE_GUI
|
||||||
IconProvider::initInstance();
|
IconProvider::initInstance();
|
||||||
|
@ -371,7 +406,7 @@ int Application::exec(const QStringList ¶ms)
|
||||||
|
|
||||||
BitTorrent::Session::initInstance();
|
BitTorrent::Session::initInstance();
|
||||||
connect(BitTorrent::Session::instance(), SIGNAL(torrentFinished(BitTorrent::TorrentHandle *const)), SLOT(torrentFinished(BitTorrent::TorrentHandle *const)));
|
connect(BitTorrent::Session::instance(), SIGNAL(torrentFinished(BitTorrent::TorrentHandle *const)), SLOT(torrentFinished(BitTorrent::TorrentHandle *const)));
|
||||||
connect(BitTorrent::Session::instance(), SIGNAL(allTorrentsFinished()), SLOT(allTorrentsFinished()));
|
connect(BitTorrent::Session::instance(), SIGNAL(allTorrentsFinished()), SLOT(allTorrentsFinished()), Qt::QueuedConnection);
|
||||||
|
|
||||||
#ifndef DISABLE_COUNTRIES_RESOLUTION
|
#ifndef DISABLE_COUNTRIES_RESOLUTION
|
||||||
Net::GeoIPManager::initInstance();
|
Net::GeoIPManager::initInstance();
|
||||||
|
@ -548,11 +583,9 @@ void Application::cleanup()
|
||||||
#ifndef DISABLE_GUI
|
#ifndef DISABLE_GUI
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
// cleanup() can be called multiple times during shutdown. We only need it once.
|
// cleanup() can be called multiple times during shutdown. We only need it once.
|
||||||
static bool alreadyDone = false;
|
static QAtomicInt alreadyDone;
|
||||||
|
if (!alreadyDone.testAndSetAcquire(0, 1))
|
||||||
if (alreadyDone)
|
|
||||||
return;
|
return;
|
||||||
alreadyDone = true;
|
|
||||||
#endif // Q_OS_WIN
|
#endif // Q_OS_WIN
|
||||||
|
|
||||||
// Hide the window and not leave it on screen as
|
// Hide the window and not leave it on screen as
|
||||||
|
@ -590,11 +623,13 @@ void Application::cleanup()
|
||||||
Net::GeoIPManager::freeInstance();
|
Net::GeoIPManager::freeInstance();
|
||||||
#endif
|
#endif
|
||||||
Net::DownloadManager::freeInstance();
|
Net::DownloadManager::freeInstance();
|
||||||
|
Net::ProxyConfigurationManager::freeInstance();
|
||||||
Preferences::freeInstance();
|
Preferences::freeInstance();
|
||||||
SettingsStorage::freeInstance();
|
SettingsStorage::freeInstance();
|
||||||
delete m_fileLogger;
|
delete m_fileLogger;
|
||||||
Logger::freeInstance();
|
Logger::freeInstance();
|
||||||
IconProvider::freeInstance();
|
IconProvider::freeInstance();
|
||||||
|
|
||||||
#ifndef DISABLE_GUI
|
#ifndef DISABLE_GUI
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
typedef BOOL (WINAPI *PSHUTDOWNBRDESTROY)(HWND);
|
typedef BOOL (WINAPI *PSHUTDOWNBRDESTROY)(HWND);
|
||||||
|
@ -604,9 +639,10 @@ void Application::cleanup()
|
||||||
shutdownBRDestroy((HWND)m_window->effectiveWinId());
|
shutdownBRDestroy((HWND)m_window->effectiveWinId());
|
||||||
#endif // Q_OS_WIN
|
#endif // Q_OS_WIN
|
||||||
delete m_window;
|
delete m_window;
|
||||||
if (m_shutdownAct != ShutdownAction::None) {
|
#endif // DISABLE_GUI
|
||||||
|
|
||||||
|
if (m_shutdownAct != ShutdownDialogAction::Exit) {
|
||||||
qDebug() << "Sending computer shutdown/suspend/hibernate signal...";
|
qDebug() << "Sending computer shutdown/suspend/hibernate signal...";
|
||||||
Utils::Misc::shutdownComputer(m_shutdownAct);
|
Utils::Misc::shutdownComputer(m_shutdownAct);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,6 +76,10 @@ public:
|
||||||
int exec(const QStringList ¶ms);
|
int exec(const QStringList ¶ms);
|
||||||
bool sendParams(const QStringList ¶ms);
|
bool sendParams(const QStringList ¶ms);
|
||||||
|
|
||||||
|
#ifndef DISABLE_GUI
|
||||||
|
QPointer<MainWindow> mainWindow();
|
||||||
|
#endif
|
||||||
|
|
||||||
// FileLogger properties
|
// FileLogger properties
|
||||||
bool isFileLoggerEnabled() const;
|
bool isFileLoggerEnabled() const;
|
||||||
void setFileLoggerEnabled(bool value);
|
void setFileLoggerEnabled(bool value);
|
||||||
|
@ -111,10 +115,10 @@ private slots:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_running;
|
bool m_running;
|
||||||
|
ShutdownDialogAction m_shutdownAct;
|
||||||
|
|
||||||
#ifndef DISABLE_GUI
|
#ifndef DISABLE_GUI
|
||||||
QPointer<MainWindow> m_window;
|
QPointer<MainWindow> m_window;
|
||||||
ShutdownAction m_shutdownAct;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef DISABLE_WEBUI
|
#ifndef DISABLE_WEBUI
|
||||||
|
@ -130,6 +134,7 @@ private:
|
||||||
|
|
||||||
void initializeTranslation();
|
void initializeTranslation();
|
||||||
void processParams(const QStringList ¶ms);
|
void processParams(const QStringList ¶ms);
|
||||||
|
void runExternalProgram(BitTorrent::TorrentHandle *const torrent) const;
|
||||||
void sendNotificationEmail(BitTorrent::TorrentHandle *const torrent);
|
void sendNotificationEmail(BitTorrent::TorrentHandle *const torrent);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -135,6 +135,12 @@ int main(int argc, char *argv[])
|
||||||
// We must save it here because QApplication constructor may change it
|
// We must save it here because QApplication constructor may change it
|
||||||
bool isOneArg = (argc == 2);
|
bool isOneArg = (argc == 2);
|
||||||
|
|
||||||
|
#ifdef Q_OS_MAC
|
||||||
|
// On macOS 10.12 Sierra, Apple changed the behaviour of CFPreferencesSetValue() https://bugreports.qt.io/browse/QTBUG-56344
|
||||||
|
// Due to this, we have to move from native plist to IniFormat
|
||||||
|
macMigratePlists();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Create Application
|
// Create Application
|
||||||
QString appId = QLatin1String("qBittorrent-") + Utils::Misc::getUserIDString();
|
QString appId = QLatin1String("qBittorrent-") + Utils::Misc::getUserIDString();
|
||||||
QScopedPointer<Application> app(new Application(appId, argc, argv));
|
QScopedPointer<Application> app(new Application(appId, argc, argv));
|
||||||
|
@ -230,6 +236,17 @@ int main(int argc, char *argv[])
|
||||||
qputenv("QT_BEARER_POLL_TIMEOUT", QByteArray::number(-1));
|
qputenv("QT_BEARER_POLL_TIMEOUT", QByteArray::number(-1));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(Q_OS_MAC)
|
||||||
|
{
|
||||||
|
// Since Apple made difficult for users to set PATH, we set here for convenience.
|
||||||
|
// Users are supposed to install Homebrew Python for search function.
|
||||||
|
// For more info see issue #5571.
|
||||||
|
QByteArray path = "/usr/local/bin:";
|
||||||
|
path += qgetenv("PATH");
|
||||||
|
qputenv("PATH", path.constData());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef DISABLE_GUI
|
#ifndef DISABLE_GUI
|
||||||
if (!upgrade()) return EXIT_FAILURE;
|
if (!upgrade()) return EXIT_FAILURE;
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
project(qtsingleapplication)
|
||||||
|
|
||||||
set(QBT_QTSINGLEAPPLICATION_HEADERS
|
set(QBT_QTSINGLEAPPLICATION_HEADERS
|
||||||
qtlocalpeer.h
|
qtlocalpeer.h
|
||||||
)
|
)
|
||||||
|
@ -15,6 +17,7 @@ else (GUI)
|
||||||
endif (GUI)
|
endif (GUI)
|
||||||
|
|
||||||
add_library(qtsingleapplication ${QBT_QTSINGLEAPPLICATION_HEADERS} ${QBT_QTSINGLEAPPLICATION_SOURCES})
|
add_library(qtsingleapplication ${QBT_QTSINGLEAPPLICATION_HEADERS} ${QBT_QTSINGLEAPPLICATION_SOURCES})
|
||||||
|
target_include_directories(qtsingleapplication INTERFACE "${qtsingleapplication_SOURCE_DIR}")
|
||||||
|
|
||||||
if (QT4_FOUND)
|
if (QT4_FOUND)
|
||||||
target_link_libraries(qtsingleapplication Qt4::QtNetwork)
|
target_link_libraries(qtsingleapplication Qt4::QtNetwork)
|
||||||
|
@ -30,3 +33,4 @@ if (GUI)
|
||||||
endif(QT4_FOUND)
|
endif(QT4_FOUND)
|
||||||
endif (GUI)
|
endif (GUI)
|
||||||
|
|
||||||
|
add_library(QtSingleApplication::QtSingleApplication ALIAS qtsingleapplication)
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <dbghelp.h>
|
#include <dbghelp.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <QDir>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
#include <cxxabi.h>
|
#include <cxxabi.h>
|
||||||
|
@ -41,6 +42,9 @@ namespace straceWin
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
void demangle(QString& str);
|
void demangle(QString& str);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
QString getSourcePathAndLineNumber(HANDLE hProcess, DWORD64 addr);
|
||||||
|
bool makeRelativePath(const QString& dir, QString& file);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
|
@ -108,6 +112,65 @@ BOOL CALLBACK straceWin::EnumModulesCB(LPCSTR ModuleName, DWORD64 BaseOfDll, PVO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cuts off leading 'dir' path from 'file' path, otherwise leaves it unchanged
|
||||||
|
* returns true if 'dir' is an ancestor of 'file', otherwise - false
|
||||||
|
*/
|
||||||
|
bool straceWin::makeRelativePath(const QString& dir, QString& file)
|
||||||
|
{
|
||||||
|
QString d = QDir::toNativeSeparators(QDir(dir).absolutePath());
|
||||||
|
QString f = QDir::toNativeSeparators(QFileInfo(file).absoluteFilePath());
|
||||||
|
|
||||||
|
// append separator at the end of dir
|
||||||
|
QChar separator = QDir::separator();
|
||||||
|
if (!d.isEmpty() && (d[d.length() - 1] != separator))
|
||||||
|
d += separator;
|
||||||
|
|
||||||
|
if (f.startsWith(d, Qt::CaseInsensitive)) {
|
||||||
|
f.remove(0, d.length());
|
||||||
|
file.swap(f);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString straceWin::getSourcePathAndLineNumber(HANDLE hProcess, DWORD64 addr)
|
||||||
|
{
|
||||||
|
IMAGEHLP_LINE64 line = {0};
|
||||||
|
line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
|
||||||
|
DWORD dwDisplacement = 0;
|
||||||
|
|
||||||
|
if (SymGetLineFromAddr64(hProcess, addr, &dwDisplacement, &line)) {
|
||||||
|
QString path(line.FileName);
|
||||||
|
|
||||||
|
#if defined STACKTRACE_WIN_PROJECT_PATH || defined STACKTRACE_WIN_MAKEFILE_PATH
|
||||||
|
|
||||||
|
#define STACKTRACE_WIN_QUOTE(x) #x
|
||||||
|
#define STACKTRACE_WIN_STRING(x) STACKTRACE_WIN_QUOTE(x)
|
||||||
|
|
||||||
|
//prune leading project directory path or build target directory path
|
||||||
|
|
||||||
|
bool success = false;
|
||||||
|
#ifdef STACKTRACE_WIN_PROJECT_PATH
|
||||||
|
QString projectPath(STACKTRACE_WIN_STRING(STACKTRACE_WIN_PROJECT_PATH));
|
||||||
|
success = makeRelativePath(projectPath, path);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef STACKTRACE_WIN_MAKEFILE_PATH
|
||||||
|
if (!success) {
|
||||||
|
QString targetPath(STACKTRACE_WIN_STRING(STACKTRACE_WIN_MAKEFILE_PATH));
|
||||||
|
makeRelativePath(targetPath, path);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
return QString("%1 : %2").arg(path).arg(line.LineNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined( _M_IX86 ) && defined(Q_CC_MSVC)
|
#if defined( _M_IX86 ) && defined(Q_CC_MSVC)
|
||||||
// Disable global optimization and ignore /GS waning caused by
|
// Disable global optimization and ignore /GS waning caused by
|
||||||
|
@ -221,11 +284,16 @@ const QString straceWin::getBacktrace()
|
||||||
fileName = fileName.mid(slashPos + 1);
|
fileName = fileName.mid(slashPos + 1);
|
||||||
}
|
}
|
||||||
QString funcName;
|
QString funcName;
|
||||||
|
QString sourceFile;
|
||||||
if(SymFromAddr(hProcess, ihsf.InstructionOffset, &dwDisplacement, pSymbol)) {
|
if(SymFromAddr(hProcess, ihsf.InstructionOffset, &dwDisplacement, pSymbol)) {
|
||||||
funcName = QString(pSymbol->Name);
|
funcName = QString(pSymbol->Name);
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
demangle(funcName);
|
demangle(funcName);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// now ihsf.InstructionOffset points to the instruction that follows CALL instuction
|
||||||
|
// decrease the query address by one byte to point somewhere in the CALL instruction byte sequence
|
||||||
|
sourceFile = getSourcePathAndLineNumber(hProcess, ihsf.InstructionOffset - 1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
funcName = QString("0x%1").arg(ihsf.InstructionOffset, 8, 16, QLatin1Char('0'));
|
funcName = QString("0x%1").arg(ihsf.InstructionOffset, 8, 16, QLatin1Char('0'));
|
||||||
|
@ -248,6 +316,9 @@ const QString straceWin::getBacktrace()
|
||||||
.arg(funcName)
|
.arg(funcName)
|
||||||
#ifndef __MINGW32__
|
#ifndef __MINGW32__
|
||||||
.arg(params.join(", "));
|
.arg(params.join(", "));
|
||||||
|
|
||||||
|
if (!sourceFile.isEmpty())
|
||||||
|
debugLine += QString("[ %1 ]").arg(sourceFile);
|
||||||
#else
|
#else
|
||||||
;
|
;
|
||||||
#endif
|
#endif
|
||||||
|
@ -262,6 +333,8 @@ const QString straceWin::getBacktrace()
|
||||||
//logStream << "\n\nList of linked Modules:\n";
|
//logStream << "\n\nList of linked Modules:\n";
|
||||||
//EnumModulesContext modulesContext(hProcess, logStream);
|
//EnumModulesContext modulesContext(hProcess, logStream);
|
||||||
//SymEnumerateModules64(hProcess, EnumModulesCB, (PVOID)&modulesContext);
|
//SymEnumerateModules64(hProcess, EnumModulesCB, (PVOID)&modulesContext);
|
||||||
|
SymCleanup(hProcess);
|
||||||
|
|
||||||
logStream << "```";
|
logStream << "```";
|
||||||
return log;
|
return log;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,24 +29,31 @@
|
||||||
#ifndef UPGRADE_H
|
#ifndef UPGRADE_H
|
||||||
#define UPGRADE_H
|
#define UPGRADE_H
|
||||||
|
|
||||||
#include <libtorrent/lazy_entry.hpp>
|
#include <libtorrent/version.hpp>
|
||||||
#include <libtorrent/entry.hpp>
|
#if LIBTORRENT_VERSION_NUM >= 10100
|
||||||
|
#include <libtorrent/bdecode.hpp>
|
||||||
|
#endif
|
||||||
#include <libtorrent/bencode.hpp>
|
#include <libtorrent/bencode.hpp>
|
||||||
|
#include <libtorrent/entry.hpp>
|
||||||
|
#if LIBTORRENT_VERSION_NUM < 10100
|
||||||
|
#include <libtorrent/lazy_entry.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include <QString>
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QRegExp>
|
|
||||||
#ifndef DISABLE_GUI
|
#ifndef DISABLE_GUI
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#endif
|
#endif
|
||||||
|
#include <QRegExp>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
#include "base/logger.h"
|
#include "base/logger.h"
|
||||||
#include "base/utils/fs.h"
|
#include "base/utils/fs.h"
|
||||||
#include "base/utils/misc.h"
|
#include "base/utils/misc.h"
|
||||||
#include "base/utils/string.h"
|
#include "base/utils/string.h"
|
||||||
#include "base/qinisettings.h"
|
|
||||||
#include "base/preferences.h"
|
#include "base/preferences.h"
|
||||||
|
#include "base/qinisettings.h"
|
||||||
|
|
||||||
bool userAcceptsUpgrade()
|
bool userAcceptsUpgrade()
|
||||||
{
|
{
|
||||||
|
@ -86,10 +93,16 @@ bool upgradeResumeFile(const QString &filepath, const QVariantHash &oldTorrent =
|
||||||
QByteArray data = file1.readAll();
|
QByteArray data = file1.readAll();
|
||||||
file1.close();
|
file1.close();
|
||||||
|
|
||||||
libtorrent::lazy_entry fastOld;
|
|
||||||
libtorrent::error_code ec;
|
libtorrent::error_code ec;
|
||||||
libtorrent::lazy_bdecode(data.constData(), data.constData() + data.size(), fastOld, ec);
|
#if LIBTORRENT_VERSION_NUM < 10100
|
||||||
if (ec || (fastOld.type() != libtorrent::lazy_entry::dict_t)) return false;
|
libtorrent::lazy_entry fastOld;
|
||||||
|
libtorrent::lazy_bdecode(data.constData(), data.constData() + data.size(), fastOld, ec);
|
||||||
|
if (ec || (fastOld.type() != libtorrent::lazy_entry::dict_t)) return false;
|
||||||
|
#else
|
||||||
|
libtorrent::bdecode_node fastOld;
|
||||||
|
libtorrent::bdecode(data.constData(), data.constData() + data.size(), fastOld, ec);
|
||||||
|
if (ec || (fastOld.type() != libtorrent::bdecode_node::dict_t)) return false;
|
||||||
|
#endif
|
||||||
|
|
||||||
libtorrent::entry fastNew;
|
libtorrent::entry fastNew;
|
||||||
fastNew = fastOld;
|
fastNew = fastOld;
|
||||||
|
@ -143,7 +156,12 @@ bool upgrade(bool ask = true)
|
||||||
upgradeResumeFile(backupFolderDir.absoluteFilePath(backupFile));
|
upgradeResumeFile(backupFolderDir.absoluteFilePath(backupFile));
|
||||||
// ****************************************************************************************
|
// ****************************************************************************************
|
||||||
|
|
||||||
|
#ifdef Q_OS_MAC
|
||||||
|
// native .plist
|
||||||
|
QSettings *oldResumeSettings = new QSettings("qBittorrent", "qBittorrent-resume");
|
||||||
|
#else
|
||||||
QIniSettings *oldResumeSettings = new QIniSettings("qBittorrent", "qBittorrent-resume");
|
QIniSettings *oldResumeSettings = new QIniSettings("qBittorrent", "qBittorrent-resume");
|
||||||
|
#endif
|
||||||
QString oldResumeFilename = oldResumeSettings->fileName();
|
QString oldResumeFilename = oldResumeSettings->fileName();
|
||||||
QVariantHash oldResumeData = oldResumeSettings->value("torrents").toHash();
|
QVariantHash oldResumeData = oldResumeSettings->value("torrents").toHash();
|
||||||
delete oldResumeSettings;
|
delete oldResumeSettings;
|
||||||
|
@ -210,4 +228,34 @@ bool upgrade(bool ask = true)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Q_OS_MAC
|
||||||
|
void migratePlistToIni(const QString &application)
|
||||||
|
{
|
||||||
|
QIniSettings iniFile("qBittorrent", application);
|
||||||
|
if (!iniFile.allKeys().isEmpty()) return; // We copy the contents of plist, only if inifile does not exist(is empty).
|
||||||
|
|
||||||
|
QSettings *plistFile = new QSettings("qBittorrent", application);
|
||||||
|
plistFile->setFallbacksEnabled(false);
|
||||||
|
const QStringList plist = plistFile->allKeys();
|
||||||
|
if (!plist.isEmpty()) {
|
||||||
|
foreach (const QString &key, plist)
|
||||||
|
iniFile.setValue(key, plistFile->value(key));
|
||||||
|
plistFile->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString plistPath = plistFile->fileName();
|
||||||
|
delete plistFile;
|
||||||
|
Utils::Fs::forceRemove(plistPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
void macMigratePlists()
|
||||||
|
{
|
||||||
|
migratePlistToIni("qBittorrent-data");
|
||||||
|
migratePlistToIni("qBittorrent-rss");
|
||||||
|
migratePlistToIni("qBittorrent");
|
||||||
|
}
|
||||||
|
#endif // Q_OS_MAC
|
||||||
|
|
||||||
|
|
||||||
#endif // UPGRADE_H
|
#endif // UPGRADE_H
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
find_package(ZLIB REQUIRED)
|
find_package(ZLIB REQUIRED)
|
||||||
include_directories(SYSTEM ${ZLIB_INCLUDE_DIRS})
|
|
||||||
|
|
||||||
set(QBT_BASE_HEADERS
|
set(QBT_BASE_HEADERS
|
||||||
bittorrent/cachestatus.h
|
bittorrent/cachestatus.h
|
||||||
|
@ -31,6 +30,7 @@ net/downloadmanager.h
|
||||||
net/geoipmanager.h
|
net/geoipmanager.h
|
||||||
net/portforwarder.h
|
net/portforwarder.h
|
||||||
net/private/geoipdatabase.h
|
net/private/geoipdatabase.h
|
||||||
|
net/proxyconfigurationmanager.h
|
||||||
net/reverseresolution.h
|
net/reverseresolution.h
|
||||||
net/smtp.h
|
net/smtp.h
|
||||||
rss/private/rssparser.h
|
rss/private/rssparser.h
|
||||||
|
@ -47,12 +47,14 @@ utils/misc.h
|
||||||
utils/string.h
|
utils/string.h
|
||||||
filesystemwatcher.h
|
filesystemwatcher.h
|
||||||
iconprovider.h
|
iconprovider.h
|
||||||
|
indexrange.h
|
||||||
logger.h
|
logger.h
|
||||||
preferences.h
|
preferences.h
|
||||||
qinisettings.h
|
qinisettings.h
|
||||||
scanfoldersmodel.h
|
scanfoldersmodel.h
|
||||||
searchengine.h
|
searchengine.h
|
||||||
settingsstorage.h
|
settingsstorage.h
|
||||||
|
torrentfileguard.h
|
||||||
torrentfilter.h
|
torrentfilter.h
|
||||||
tristatebool.h
|
tristatebool.h
|
||||||
types.h
|
types.h
|
||||||
|
@ -87,6 +89,7 @@ net/downloadmanager.cpp
|
||||||
net/geoipmanager.cpp
|
net/geoipmanager.cpp
|
||||||
net/portforwarder.cpp
|
net/portforwarder.cpp
|
||||||
net/private/geoipdatabase.cpp
|
net/private/geoipdatabase.cpp
|
||||||
|
net/proxyconfigurationmanager.cpp
|
||||||
net/reverseresolution.cpp
|
net/reverseresolution.cpp
|
||||||
net/smtp.cpp
|
net/smtp.cpp
|
||||||
rss/private/rssparser.cpp
|
rss/private/rssparser.cpp
|
||||||
|
@ -108,12 +111,13 @@ preferences.cpp
|
||||||
scanfoldersmodel.cpp
|
scanfoldersmodel.cpp
|
||||||
searchengine.cpp
|
searchengine.cpp
|
||||||
settingsstorage.cpp
|
settingsstorage.cpp
|
||||||
|
torrentfileguard.cpp
|
||||||
torrentfilter.cpp
|
torrentfilter.cpp
|
||||||
tristatebool.cpp
|
tristatebool.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(qbt_base STATIC ${QBT_BASE_HEADERS} ${QBT_BASE_SOURCES})
|
add_library(qbt_base STATIC ${QBT_BASE_HEADERS} ${QBT_BASE_SOURCES})
|
||||||
target_link_libraries(qbt_base ${ZLIB_LIBRARIES} ${LibtorrentRasterbar_LIBRARIES})
|
target_link_libraries(qbt_base ZLIB::ZLIB LibtorrentRasterbar::LibTorrent)
|
||||||
target_link_qt_components(qbt_base Core Network Xml)
|
target_link_qt_components(qbt_base Core Network Xml)
|
||||||
if (QT4_FOUND)
|
if (QT4_FOUND)
|
||||||
if (GUI)
|
if (GUI)
|
||||||
|
@ -124,3 +128,13 @@ else (QT4_FOUND)
|
||||||
target_link_libraries(qbt_base Qt5::Gui Qt5::Widgets)
|
target_link_libraries(qbt_base Qt5::Gui Qt5::Widgets)
|
||||||
endif (GUI)
|
endif (GUI)
|
||||||
endif (QT4_FOUND)
|
endif (QT4_FOUND)
|
||||||
|
|
||||||
|
if (DBUS)
|
||||||
|
target_link_qt_components(qbt_base DBus)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (APPLE)
|
||||||
|
find_library(IOKit_LIBRARY IOKit)
|
||||||
|
find_library(Carbon_LIBRARY Carbon)
|
||||||
|
target_link_libraries(qbt_base ${Carbon_LIBRARY} ${IOKit_LIBRARY})
|
||||||
|
endif (APPLE)
|
||||||
|
|
|
@ -5,7 +5,9 @@ HEADERS += \
|
||||||
$$PWD/qinisettings.h \
|
$$PWD/qinisettings.h \
|
||||||
$$PWD/logger.h \
|
$$PWD/logger.h \
|
||||||
$$PWD/settingsstorage.h \
|
$$PWD/settingsstorage.h \
|
||||||
|
$$PWD/settingvalue.h \
|
||||||
$$PWD/preferences.h \
|
$$PWD/preferences.h \
|
||||||
|
$$PWD/indexrange.h \
|
||||||
$$PWD/iconprovider.h \
|
$$PWD/iconprovider.h \
|
||||||
$$PWD/http/irequesthandler.h \
|
$$PWD/http/irequesthandler.h \
|
||||||
$$PWD/http/connection.h \
|
$$PWD/http/connection.h \
|
||||||
|
@ -19,6 +21,7 @@ HEADERS += \
|
||||||
$$PWD/net/downloadhandler.h \
|
$$PWD/net/downloadhandler.h \
|
||||||
$$PWD/net/geoipmanager.h \
|
$$PWD/net/geoipmanager.h \
|
||||||
$$PWD/net/portforwarder.h \
|
$$PWD/net/portforwarder.h \
|
||||||
|
$$PWD/net/proxyconfigurationmanager.h \
|
||||||
$$PWD/net/reverseresolution.h \
|
$$PWD/net/reverseresolution.h \
|
||||||
$$PWD/net/smtp.h \
|
$$PWD/net/smtp.h \
|
||||||
$$PWD/net/private/geoipdatabase.h \
|
$$PWD/net/private/geoipdatabase.h \
|
||||||
|
@ -51,6 +54,7 @@ HEADERS += \
|
||||||
$$PWD/utils/misc.h \
|
$$PWD/utils/misc.h \
|
||||||
$$PWD/utils/string.h \
|
$$PWD/utils/string.h \
|
||||||
$$PWD/unicodestrings.h \
|
$$PWD/unicodestrings.h \
|
||||||
|
$$PWD/torrentfileguard.h \
|
||||||
$$PWD/torrentfilter.h \
|
$$PWD/torrentfilter.h \
|
||||||
$$PWD/scanfoldersmodel.h \
|
$$PWD/scanfoldersmodel.h \
|
||||||
$$PWD/searchengine.h
|
$$PWD/searchengine.h
|
||||||
|
@ -72,6 +76,7 @@ SOURCES += \
|
||||||
$$PWD/net/downloadhandler.cpp \
|
$$PWD/net/downloadhandler.cpp \
|
||||||
$$PWD/net/geoipmanager.cpp \
|
$$PWD/net/geoipmanager.cpp \
|
||||||
$$PWD/net/portforwarder.cpp \
|
$$PWD/net/portforwarder.cpp \
|
||||||
|
$$PWD/net/proxyconfigurationmanager.cpp \
|
||||||
$$PWD/net/reverseresolution.cpp \
|
$$PWD/net/reverseresolution.cpp \
|
||||||
$$PWD/net/smtp.cpp \
|
$$PWD/net/smtp.cpp \
|
||||||
$$PWD/net/private/geoipdatabase.cpp \
|
$$PWD/net/private/geoipdatabase.cpp \
|
||||||
|
@ -103,6 +108,7 @@ SOURCES += \
|
||||||
$$PWD/utils/gzip.cpp \
|
$$PWD/utils/gzip.cpp \
|
||||||
$$PWD/utils/misc.cpp \
|
$$PWD/utils/misc.cpp \
|
||||||
$$PWD/utils/string.cpp \
|
$$PWD/utils/string.cpp \
|
||||||
|
$$PWD/torrentfileguard.cpp \
|
||||||
$$PWD/torrentfilter.cpp \
|
$$PWD/torrentfilter.cpp \
|
||||||
$$PWD/scanfoldersmodel.cpp \
|
$$PWD/scanfoldersmodel.cpp \
|
||||||
$$PWD/searchengine.cpp
|
$$PWD/searchengine.cpp
|
||||||
|
|
|
@ -68,7 +68,6 @@ bool InfoHash::isValid() const
|
||||||
return m_valid;
|
return m_valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
InfoHash::operator libtorrent::sha1_hash() const
|
InfoHash::operator libtorrent::sha1_hash() const
|
||||||
{
|
{
|
||||||
return m_nativeHash;
|
return m_nativeHash;
|
||||||
|
|
|
@ -31,13 +31,13 @@
|
||||||
#include <QTime>
|
#include <QTime>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
|
|
||||||
|
#include "base/bittorrent/session.h"
|
||||||
#include "base/preferences.h"
|
#include "base/preferences.h"
|
||||||
#include "bandwidthscheduler.h"
|
#include "bandwidthscheduler.h"
|
||||||
|
|
||||||
BandwidthScheduler::BandwidthScheduler(QObject *parent)
|
BandwidthScheduler::BandwidthScheduler(QObject *parent)
|
||||||
: QTimer(parent)
|
: QTimer(parent)
|
||||||
{
|
{
|
||||||
Q_ASSERT(Preferences::instance()->isSchedulerEnabled());
|
|
||||||
// Single shot, we call start() again manually
|
// Single shot, we call start() again manually
|
||||||
setSingleShot(true);
|
setSingleShot(true);
|
||||||
// Connect Signals/Slots
|
// Connect Signals/Slots
|
||||||
|
@ -47,8 +47,7 @@ BandwidthScheduler::BandwidthScheduler(QObject *parent)
|
||||||
void BandwidthScheduler::start()
|
void BandwidthScheduler::start()
|
||||||
{
|
{
|
||||||
const Preferences* const pref = Preferences::instance();
|
const Preferences* const pref = Preferences::instance();
|
||||||
Q_ASSERT(pref->isSchedulerEnabled());
|
bool alt_bw_enabled = BitTorrent::Session::instance()->isAltGlobalSpeedLimitEnabled();
|
||||||
bool alt_bw_enabled = pref->isAltBandwidthEnabled();
|
|
||||||
|
|
||||||
QTime start = pref->getSchedulerStartTime();
|
QTime start = pref->getSchedulerStartTime();
|
||||||
QTime end = pref->getSchedulerEndTime();
|
QTime end = pref->getSchedulerEndTime();
|
||||||
|
|
|
@ -55,10 +55,10 @@ FilterParserThread::~FilterParserThread()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parser for eMule ip filter in DAT format
|
// Parser for eMule ip filter in DAT format
|
||||||
int FilterParserThread::parseDATFilterFile(QString m_filePath, libt::ip_filter &filter)
|
int FilterParserThread::parseDATFilterFile(QString filePath, libt::ip_filter &filter)
|
||||||
{
|
{
|
||||||
int ruleCount = 0;
|
int ruleCount = 0;
|
||||||
QFile file(m_filePath);
|
QFile file(filePath);
|
||||||
if (!file.exists()) return ruleCount;
|
if (!file.exists()) return ruleCount;
|
||||||
|
|
||||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||||
|
@ -149,10 +149,10 @@ int FilterParserThread::parseDATFilterFile(QString m_filePath, libt::ip_filter &
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parser for PeerGuardian ip filter in p2p format
|
// Parser for PeerGuardian ip filter in p2p format
|
||||||
int FilterParserThread::parseP2PFilterFile(QString m_filePath, libt::ip_filter &filter)
|
int FilterParserThread::parseP2PFilterFile(QString filePath, libt::ip_filter &filter)
|
||||||
{
|
{
|
||||||
int ruleCount = 0;
|
int ruleCount = 0;
|
||||||
QFile file(m_filePath);
|
QFile file(filePath);
|
||||||
if (!file.exists()) return ruleCount;
|
if (!file.exists()) return ruleCount;
|
||||||
|
|
||||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||||
|
@ -257,10 +257,10 @@ int FilterParserThread::getlineInStream(QDataStream &stream, std::string &name,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parser for PeerGuardian ip filter in p2p format
|
// Parser for PeerGuardian ip filter in p2p format
|
||||||
int FilterParserThread::parseP2BFilterFile(QString m_filePath, libt::ip_filter &filter)
|
int FilterParserThread::parseP2BFilterFile(QString filePath, libt::ip_filter &filter)
|
||||||
{
|
{
|
||||||
int ruleCount = 0;
|
int ruleCount = 0;
|
||||||
QFile file(m_filePath);
|
QFile file(filePath);
|
||||||
if (!file.exists()) return ruleCount;
|
if (!file.exists()) return ruleCount;
|
||||||
|
|
||||||
if (!file.open(QIODevice::ReadOnly)) {
|
if (!file.open(QIODevice::ReadOnly)) {
|
||||||
|
@ -369,7 +369,7 @@ int FilterParserThread::parseP2BFilterFile(QString m_filePath, libt::ip_filter &
|
||||||
// * eMule IP list (DAT): http://wiki.phoenixlabs.org/wiki/DAT_Format
|
// * eMule IP list (DAT): http://wiki.phoenixlabs.org/wiki/DAT_Format
|
||||||
// * PeerGuardian Text (P2P): http://wiki.phoenixlabs.org/wiki/P2P_Format
|
// * PeerGuardian Text (P2P): http://wiki.phoenixlabs.org/wiki/P2P_Format
|
||||||
// * PeerGuardian Binary (P2B): http://wiki.phoenixlabs.org/wiki/P2B_Format
|
// * PeerGuardian Binary (P2B): http://wiki.phoenixlabs.org/wiki/P2B_Format
|
||||||
void FilterParserThread::processFilterFile(QString _filePath)
|
void FilterParserThread::processFilterFile(QString filePath)
|
||||||
{
|
{
|
||||||
if (isRunning()) {
|
if (isRunning()) {
|
||||||
// Already parsing a filter, m_abort first
|
// Already parsing a filter, m_abort first
|
||||||
|
@ -378,30 +378,37 @@ void FilterParserThread::processFilterFile(QString _filePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
m_abort = false;
|
m_abort = false;
|
||||||
m_filePath = _filePath;
|
m_filePath = filePath;
|
||||||
// Run it
|
// Run it
|
||||||
start();
|
start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FilterParserThread::processFilterList(libt::session *s, const QStringList &IPs)
|
|
||||||
{
|
|
||||||
// First, import current filter
|
|
||||||
libt::ip_filter filter = s->get_ip_filter();
|
|
||||||
foreach (const QString &ip, IPs) {
|
|
||||||
qDebug("Manual ban of peer %s", ip.toLocal8Bit().constData());
|
|
||||||
boost::system::error_code ec;
|
|
||||||
libt::address addr = libt::address::from_string(ip.toLocal8Bit().constData(), ec);
|
|
||||||
Q_ASSERT(!ec);
|
|
||||||
if (!ec)
|
|
||||||
filter.add_rule(addr, addr, libt::ip_filter::blocked);
|
|
||||||
}
|
|
||||||
|
|
||||||
s->set_ip_filter(filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString FilterParserThread::cleanupIPAddress(QString _ip)
|
QString FilterParserThread::cleanupIPAddress(QString _ip)
|
||||||
{
|
{
|
||||||
QHostAddress ip(_ip.trimmed());
|
_ip = _ip.trimmed();
|
||||||
|
|
||||||
|
// Emule .DAT files contain leading zeroes in IPv4 addresses
|
||||||
|
// eg 001.009.106.186
|
||||||
|
// We need to remove them because both QHostAddress and Boost.Asio fail to parse them.
|
||||||
|
QStringList octets = _ip.split('.', QString::SkipEmptyParts);
|
||||||
|
if (octets.size() == 4) {
|
||||||
|
QString octet; // it is faster to not recreate this object in the loop
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
octet = octets[i];
|
||||||
|
if ((octet[0] == QChar('0')) && (octet.count() > 1)) {
|
||||||
|
if ((octet[1] == QChar('0')) && (octet.count() > 2))
|
||||||
|
octet.remove(0, 2);
|
||||||
|
else
|
||||||
|
octet.remove(0, 1);
|
||||||
|
|
||||||
|
octets[i] = octet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_ip = octets.join(".");
|
||||||
|
}
|
||||||
|
|
||||||
|
QHostAddress ip(_ip);
|
||||||
if (ip.isNull()) return QString();
|
if (ip.isNull()) return QString();
|
||||||
|
|
||||||
return ip.toString();
|
return ip.toString();
|
||||||
|
|
|
@ -54,8 +54,7 @@ public:
|
||||||
int parseP2PFilterFile(QString filePath, libtorrent::ip_filter &filter);
|
int parseP2PFilterFile(QString filePath, libtorrent::ip_filter &filter);
|
||||||
int getlineInStream(QDataStream &stream, std::string &name, char delim);
|
int getlineInStream(QDataStream &stream, std::string &name, char delim);
|
||||||
int parseP2BFilterFile(QString filePath, libtorrent::ip_filter &filter);
|
int parseP2BFilterFile(QString filePath, libtorrent::ip_filter &filter);
|
||||||
void processFilterFile(QString _filePath);
|
void processFilterFile(QString filePath);
|
||||||
static void processFilterList(libtorrent::session *s, const QStringList &IPs);
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void IPFilterParsed(int ruleCount);
|
void IPFilterParsed(int ruleCount);
|
||||||
|
|
|
@ -27,17 +27,21 @@
|
||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <QList>
|
|
||||||
#include "speedmonitor.h"
|
#include "speedmonitor.h"
|
||||||
|
|
||||||
|
SpeedMonitor::SpeedMonitor()
|
||||||
|
: m_speedSamples(MAX_SAMPLES)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void SpeedMonitor::addSample(const SpeedSample &sample)
|
void SpeedMonitor::addSample(const SpeedSample &sample)
|
||||||
{
|
{
|
||||||
|
if (m_speedSamples.size() >= MAX_SAMPLES) {
|
||||||
|
m_sum -= m_speedSamples.front();
|
||||||
|
}
|
||||||
|
|
||||||
m_speedSamples.push_back(sample);
|
m_speedSamples.push_back(sample);
|
||||||
m_sum += sample;
|
m_sum += sample;
|
||||||
if (m_speedSamples.size() > MAX_SAMPLES) {
|
|
||||||
m_sum -= m_speedSamples.front();
|
|
||||||
m_speedSamples.pop_front();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SpeedSampleAvg SpeedMonitor::average() const
|
SpeedSampleAvg SpeedMonitor::average() const
|
||||||
|
|
|
@ -30,7 +30,11 @@
|
||||||
#ifndef SPEEDMONITOR_H
|
#ifndef SPEEDMONITOR_H
|
||||||
#define SPEEDMONITOR_H
|
#define SPEEDMONITOR_H
|
||||||
|
|
||||||
template<typename T> class QList;
|
#ifndef Q_MOC_RUN
|
||||||
|
#include <boost/circular_buffer.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <QtGlobal>
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct Sample
|
struct Sample
|
||||||
|
@ -71,13 +75,15 @@ typedef Sample<qreal> SpeedSampleAvg;
|
||||||
class SpeedMonitor
|
class SpeedMonitor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
SpeedMonitor();
|
||||||
|
|
||||||
void addSample(const SpeedSample &sample);
|
void addSample(const SpeedSample &sample);
|
||||||
SpeedSampleAvg average() const;
|
SpeedSampleAvg average() const;
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const int MAX_SAMPLES = 30;
|
static const int MAX_SAMPLES = 30;
|
||||||
QList<SpeedSample> m_speedSamples;
|
boost::circular_buffer<SpeedSample> m_speedSamples;
|
||||||
SpeedSample m_sum;
|
SpeedSample m_sum;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -30,17 +30,23 @@
|
||||||
#ifndef BITTORRENT_SESSION_H
|
#ifndef BITTORRENT_SESSION_H
|
||||||
#define BITTORRENT_SESSION_H
|
#define BITTORRENT_SESSION_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <libtorrent/version.hpp>
|
||||||
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include <QPointer>
|
#if LIBTORRENT_VERSION_NUM < 10100
|
||||||
#include <QVector>
|
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
#include <QWaitCondition>
|
#endif
|
||||||
#include <QNetworkConfigurationManager>
|
#include <QNetworkConfigurationManager>
|
||||||
|
#include <QPointer>
|
||||||
|
#include <QReadWriteLock>
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QVector>
|
||||||
|
#include <QWaitCondition>
|
||||||
|
|
||||||
#include <libtorrent/version.hpp>
|
#include "base/settingvalue.h"
|
||||||
|
|
||||||
#include "base/tristatebool.h"
|
#include "base/tristatebool.h"
|
||||||
#include "base/types.h"
|
#include "base/types.h"
|
||||||
#include "torrentinfo.h"
|
#include "torrentinfo.h"
|
||||||
|
@ -52,19 +58,12 @@ namespace libtorrent
|
||||||
class entry;
|
class entry;
|
||||||
struct add_torrent_params;
|
struct add_torrent_params;
|
||||||
struct pe_settings;
|
struct pe_settings;
|
||||||
struct session_settings;
|
|
||||||
struct session_status;
|
|
||||||
|
|
||||||
#if LIBTORRENT_VERSION_NUM < 10100
|
#if LIBTORRENT_VERSION_NUM < 10100
|
||||||
struct proxy_settings;
|
struct session_settings;
|
||||||
#else
|
#else
|
||||||
namespace aux
|
struct settings_pack;
|
||||||
{
|
|
||||||
struct proxy_settings;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef aux::proxy_settings proxy_settings;
|
|
||||||
#endif
|
#endif
|
||||||
|
struct session_status;
|
||||||
|
|
||||||
class alert;
|
class alert;
|
||||||
struct torrent_alert;
|
struct torrent_alert;
|
||||||
|
@ -111,7 +110,6 @@ class FilterParserThread;
|
||||||
class BandwidthScheduler;
|
class BandwidthScheduler;
|
||||||
class Statistics;
|
class Statistics;
|
||||||
class ResumeDataSavingManager;
|
class ResumeDataSavingManager;
|
||||||
class SettingsStorage;
|
|
||||||
|
|
||||||
enum MaxRatioAction
|
enum MaxRatioAction
|
||||||
{
|
{
|
||||||
|
@ -172,19 +170,13 @@ namespace BitTorrent
|
||||||
static void freeInstance();
|
static void freeInstance();
|
||||||
static Session *instance();
|
static Session *instance();
|
||||||
|
|
||||||
bool isDHTEnabled() const;
|
|
||||||
bool isLSDEnabled() const;
|
|
||||||
bool isPexEnabled() const;
|
|
||||||
bool isQueueingEnabled() const;
|
|
||||||
qreal globalMaxRatio() const;
|
|
||||||
bool isAppendExtensionEnabled() const;
|
|
||||||
|
|
||||||
QString defaultSavePath() const;
|
QString defaultSavePath() const;
|
||||||
void setDefaultSavePath(QString path);
|
void setDefaultSavePath(QString path);
|
||||||
QString tempPath() const;
|
QString tempPath() const;
|
||||||
void setTempPath(QString path);
|
void setTempPath(QString path);
|
||||||
bool isTempPathEnabled() const;
|
bool isTempPathEnabled() const;
|
||||||
void setTempPathEnabled(bool enabled);
|
void setTempPathEnabled(bool enabled);
|
||||||
|
QString torrentTempPath(const InfoHash &hash) const;
|
||||||
|
|
||||||
static bool isValidCategoryName(const QString &name);
|
static bool isValidCategoryName(const QString &name);
|
||||||
// returns category itself and all top level categories
|
// returns category itself and all top level categories
|
||||||
|
@ -198,28 +190,144 @@ namespace BitTorrent
|
||||||
bool isSubcategoriesEnabled() const;
|
bool isSubcategoriesEnabled() const;
|
||||||
void setSubcategoriesEnabled(bool value);
|
void setSubcategoriesEnabled(bool value);
|
||||||
|
|
||||||
// Advanced Saving Management subsystem (ASM)
|
// Torrent Management Mode subsystem (TMM)
|
||||||
//
|
//
|
||||||
// Each torrent can be either in Simple mode or in Advanced mode
|
// Each torrent can be either in Manual mode or in Automatic mode
|
||||||
// In Simple mode torrent has explicit save path
|
// In Manual Mode various torrent properties are set explicitly(eg save path)
|
||||||
// In Advanced Mode torrent has implicit save path (based on Default
|
// In Automatic Mode various torrent properties are set implicitly(eg save path)
|
||||||
// save path and Category save path)
|
// based on the associated category.
|
||||||
// In Advanced Mode torrent save path can be changed in following cases:
|
// In Automatic Mode torrent save path can be changed in following cases:
|
||||||
// 1. Default save path changed
|
// 1. Default save path changed
|
||||||
// 2. Torrent category save path changed
|
// 2. Torrent category save path changed
|
||||||
// 3. Torrent category changed
|
// 3. Torrent category changed
|
||||||
// (unless otherwise is specified)
|
// (unless otherwise is specified)
|
||||||
bool isASMDisabledByDefault() const;
|
bool isAutoTMMDisabledByDefault() const;
|
||||||
void setASMDisabledByDefault(bool value);
|
void setAutoTMMDisabledByDefault(bool value);
|
||||||
bool isDisableASMWhenCategoryChanged() const;
|
bool isDisableAutoTMMWhenCategoryChanged() const;
|
||||||
void setDisableASMWhenCategoryChanged(bool value);
|
void setDisableAutoTMMWhenCategoryChanged(bool value);
|
||||||
bool isDisableASMWhenDefaultSavePathChanged() const;
|
bool isDisableAutoTMMWhenDefaultSavePathChanged() const;
|
||||||
void setDisableASMWhenDefaultSavePathChanged(bool value);
|
void setDisableAutoTMMWhenDefaultSavePathChanged(bool value);
|
||||||
bool isDisableASMWhenCategorySavePathChanged() const;
|
bool isDisableAutoTMMWhenCategorySavePathChanged() const;
|
||||||
void setDisableASMWhenCategorySavePathChanged(bool value);
|
void setDisableAutoTMMWhenCategorySavePathChanged(bool value);
|
||||||
|
|
||||||
|
qreal globalMaxRatio() const;
|
||||||
|
void setGlobalMaxRatio(qreal ratio);
|
||||||
|
bool isDHTEnabled() const;
|
||||||
|
void setDHTEnabled(bool enabled);
|
||||||
|
bool isLSDEnabled() const;
|
||||||
|
void setLSDEnabled(bool enabled);
|
||||||
|
bool isPeXEnabled() const;
|
||||||
|
void setPeXEnabled(bool enabled);
|
||||||
|
bool isTrackerExchangeEnabled() const;
|
||||||
|
void setTrackerExchangeEnabled(bool enabled);
|
||||||
bool isAddTorrentPaused() const;
|
bool isAddTorrentPaused() const;
|
||||||
void setAddTorrentPaused(bool value);
|
void setAddTorrentPaused(bool value);
|
||||||
|
bool isTrackerEnabled() const;
|
||||||
|
void setTrackerEnabled(bool enabled);
|
||||||
|
bool isAppendExtensionEnabled() const;
|
||||||
|
void setAppendExtensionEnabled(bool enabled);
|
||||||
|
uint refreshInterval() const;
|
||||||
|
void setRefreshInterval(uint value);
|
||||||
|
bool isPreallocationEnabled() const;
|
||||||
|
void setPreallocationEnabled(bool enabled);
|
||||||
|
QString torrentExportDirectory() const;
|
||||||
|
void setTorrentExportDirectory(QString path);
|
||||||
|
QString finishedTorrentExportDirectory() const;
|
||||||
|
void setFinishedTorrentExportDirectory(QString path);
|
||||||
|
|
||||||
|
int globalDownloadSpeedLimit() const;
|
||||||
|
void setGlobalDownloadSpeedLimit(int limit);
|
||||||
|
int globalUploadSpeedLimit() const;
|
||||||
|
void setGlobalUploadSpeedLimit(int limit);
|
||||||
|
int altGlobalDownloadSpeedLimit() const;
|
||||||
|
void setAltGlobalDownloadSpeedLimit(int limit);
|
||||||
|
int altGlobalUploadSpeedLimit() const;
|
||||||
|
void setAltGlobalUploadSpeedLimit(int limit);
|
||||||
|
int downloadSpeedLimit() const;
|
||||||
|
void setDownloadSpeedLimit(int limit);
|
||||||
|
int uploadSpeedLimit() const;
|
||||||
|
void setUploadSpeedLimit(int limit);
|
||||||
|
bool isAltGlobalSpeedLimitEnabled() const;
|
||||||
|
void setAltGlobalSpeedLimitEnabled(bool enabled);
|
||||||
|
bool isBandwidthSchedulerEnabled() const;
|
||||||
|
void setBandwidthSchedulerEnabled(bool enabled);
|
||||||
|
|
||||||
|
uint saveResumeDataInterval() const;
|
||||||
|
void setSaveResumeDataInterval(uint value);
|
||||||
|
int port() const;
|
||||||
|
void setPort(int port);
|
||||||
|
bool useRandomPort() const;
|
||||||
|
void setUseRandomPort(bool value);
|
||||||
|
QString networkInterface() const;
|
||||||
|
void setNetworkInterface(const QString &interface);
|
||||||
|
QString networkInterfaceName() const;
|
||||||
|
void setNetworkInterfaceName(const QString &name);
|
||||||
|
QString networkInterfaceAddress() const;
|
||||||
|
void setNetworkInterfaceAddress(const QString &address);
|
||||||
|
bool isIPv6Enabled() const;
|
||||||
|
void setIPv6Enabled(bool enabled);
|
||||||
|
int encryption() const;
|
||||||
|
void setEncryption(int state);
|
||||||
|
bool isForceProxyEnabled() const;
|
||||||
|
void setForceProxyEnabled(bool enabled);
|
||||||
|
bool isProxyPeerConnectionsEnabled() const;
|
||||||
|
void setProxyPeerConnectionsEnabled(bool enabled);
|
||||||
|
bool isAddTrackersEnabled() const;
|
||||||
|
void setAddTrackersEnabled(bool enabled);
|
||||||
|
QString additionalTrackers() const;
|
||||||
|
void setAdditionalTrackers(const QString &trackers);
|
||||||
|
bool isIPFilteringEnabled() const;
|
||||||
|
void setIPFilteringEnabled(bool enabled);
|
||||||
|
QString IPFilterFile() const;
|
||||||
|
void setIPFilterFile(QString path);
|
||||||
|
bool announceToAllTrackers() const;
|
||||||
|
void setAnnounceToAllTrackers(bool val);
|
||||||
|
uint diskCacheSize() const;
|
||||||
|
void setDiskCacheSize(uint size);
|
||||||
|
uint diskCacheTTL() const;
|
||||||
|
void setDiskCacheTTL(uint ttl);
|
||||||
|
bool useOSCache() const;
|
||||||
|
void setUseOSCache(bool use);
|
||||||
|
bool isAnonymousModeEnabled() const;
|
||||||
|
void setAnonymousModeEnabled(bool enabled);
|
||||||
|
bool isQueueingSystemEnabled() const;
|
||||||
|
void setQueueingSystemEnabled(bool enabled);
|
||||||
|
bool ignoreSlowTorrentsForQueueing() const;
|
||||||
|
void setIgnoreSlowTorrentsForQueueing(bool ignore);
|
||||||
|
uint outgoingPortsMin() const;
|
||||||
|
void setOutgoingPortsMin(uint min);
|
||||||
|
uint outgoingPortsMax() const;
|
||||||
|
void setOutgoingPortsMax(uint max);
|
||||||
|
bool ignoreLimitsOnLAN() const;
|
||||||
|
void setIgnoreLimitsOnLAN(bool ignore);
|
||||||
|
bool includeOverheadInLimits() const;
|
||||||
|
void setIncludeOverheadInLimits(bool include);
|
||||||
|
QString announceIP() const;
|
||||||
|
void setAnnounceIP(const QString &ip);
|
||||||
|
bool isSuperSeedingEnabled() const;
|
||||||
|
void setSuperSeedingEnabled(bool enabled);
|
||||||
|
int maxConnections() const;
|
||||||
|
void setMaxConnections(int max);
|
||||||
|
int maxHalfOpenConnections() const;
|
||||||
|
void setMaxHalfOpenConnections(int max);
|
||||||
|
int maxConnectionsPerTorrent() const;
|
||||||
|
void setMaxConnectionsPerTorrent(int max);
|
||||||
|
int maxUploads() const;
|
||||||
|
void setMaxUploads(int max);
|
||||||
|
int maxUploadsPerTorrent() const;
|
||||||
|
void setMaxUploadsPerTorrent(int max);
|
||||||
|
int maxActiveDownloads() const;
|
||||||
|
void setMaxActiveDownloads(int max);
|
||||||
|
int maxActiveUploads() const;
|
||||||
|
void setMaxActiveUploads(int max);
|
||||||
|
int maxActiveTorrents() const;
|
||||||
|
void setMaxActiveTorrents(int max);
|
||||||
|
bool isUTPEnabled() const;
|
||||||
|
void setUTPEnabled(bool enabled);
|
||||||
|
bool isUTPRateLimited() const;
|
||||||
|
void setUTPRateLimited(bool limited);
|
||||||
|
bool isTrackerFilteringEnabled() const;
|
||||||
|
void setTrackerFilteringEnabled(bool enabled);
|
||||||
|
|
||||||
TorrentHandle *findTorrent(const InfoHash &hash) const;
|
TorrentHandle *findTorrent(const InfoHash &hash) const;
|
||||||
QHash<InfoHash, TorrentHandle *> torrents() const;
|
QHash<InfoHash, TorrentHandle *> torrents() const;
|
||||||
|
@ -230,19 +338,11 @@ namespace BitTorrent
|
||||||
CacheStatus cacheStatus() const;
|
CacheStatus cacheStatus() const;
|
||||||
quint64 getAlltimeDL() const;
|
quint64 getAlltimeDL() const;
|
||||||
quint64 getAlltimeUL() const;
|
quint64 getAlltimeUL() const;
|
||||||
int downloadRateLimit() const;
|
|
||||||
int uploadRateLimit() const;
|
|
||||||
bool isListening() const;
|
bool isListening() const;
|
||||||
|
|
||||||
MaxRatioAction maxRatioAction() const;
|
MaxRatioAction maxRatioAction() const;
|
||||||
void setMaxRatioAction(MaxRatioAction act);
|
void setMaxRatioAction(MaxRatioAction act);
|
||||||
|
|
||||||
void changeSpeedLimitMode(bool alternative);
|
|
||||||
void setDownloadRateLimit(int rate);
|
|
||||||
void setUploadRateLimit(int rate);
|
|
||||||
void setGlobalMaxRatio(qreal ratio);
|
|
||||||
void enableIPFilter(const QString &filterPath, bool force = false);
|
|
||||||
void disableIPFilter();
|
|
||||||
void banIP(const QString &ip);
|
void banIP(const QString &ip);
|
||||||
|
|
||||||
bool isKnownTorrent(const InfoHash &hash) const;
|
bool isKnownTorrent(const InfoHash &hash) const;
|
||||||
|
@ -284,6 +384,7 @@ namespace BitTorrent
|
||||||
void torrentsUpdated();
|
void torrentsUpdated();
|
||||||
void addTorrentFailed(const QString &error);
|
void addTorrentFailed(const QString &error);
|
||||||
void torrentAdded(BitTorrent::TorrentHandle *const torrent);
|
void torrentAdded(BitTorrent::TorrentHandle *const torrent);
|
||||||
|
void torrentNew(BitTorrent::TorrentHandle *const torrent);
|
||||||
void torrentAboutToBeRemoved(BitTorrent::TorrentHandle *const torrent);
|
void torrentAboutToBeRemoved(BitTorrent::TorrentHandle *const torrent);
|
||||||
void torrentPaused(BitTorrent::TorrentHandle *const torrent);
|
void torrentPaused(BitTorrent::TorrentHandle *const torrent);
|
||||||
void torrentResumed(BitTorrent::TorrentHandle *const torrent);
|
void torrentResumed(BitTorrent::TorrentHandle *const torrent);
|
||||||
|
@ -302,7 +403,7 @@ namespace BitTorrent
|
||||||
void trackerAuthenticationRequired(BitTorrent::TorrentHandle *const torrent);
|
void trackerAuthenticationRequired(BitTorrent::TorrentHandle *const torrent);
|
||||||
void recursiveTorrentDownloadPossible(BitTorrent::TorrentHandle *const torrent);
|
void recursiveTorrentDownloadPossible(BitTorrent::TorrentHandle *const torrent);
|
||||||
void speedLimitModeChanged(bool alternative);
|
void speedLimitModeChanged(bool alternative);
|
||||||
void ipFilterParsed(bool error, int ruleCount);
|
void IPFilterParsed(bool error, int ruleCount);
|
||||||
void trackersAdded(BitTorrent::TorrentHandle *const torrent, const QList<BitTorrent::TrackerEntry> &trackers);
|
void trackersAdded(BitTorrent::TorrentHandle *const torrent, const QList<BitTorrent::TrackerEntry> &trackers);
|
||||||
void trackersRemoved(BitTorrent::TorrentHandle *const torrent, const QList<BitTorrent::TrackerEntry> &trackers);
|
void trackersRemoved(BitTorrent::TorrentHandle *const torrent, const QList<BitTorrent::TrackerEntry> &trackers);
|
||||||
void trackersChanged(BitTorrent::TorrentHandle *const torrent);
|
void trackersChanged(BitTorrent::TorrentHandle *const torrent);
|
||||||
|
@ -314,7 +415,7 @@ namespace BitTorrent
|
||||||
void subcategoriesSupportChanged();
|
void subcategoriesSupportChanged();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void configure();
|
void configureDeferred();
|
||||||
void readAlerts();
|
void readAlerts();
|
||||||
void refresh();
|
void refresh();
|
||||||
void processBigRatios();
|
void processBigRatios();
|
||||||
|
@ -339,25 +440,30 @@ namespace BitTorrent
|
||||||
void initResumeFolder();
|
void initResumeFolder();
|
||||||
|
|
||||||
// Session configuration
|
// Session configuration
|
||||||
void setSessionSettings();
|
Q_INVOKABLE void configure();
|
||||||
void setProxySettings(libtorrent::proxy_settings proxySettings);
|
#if LIBTORRENT_VERSION_NUM < 10100
|
||||||
void adjustLimits();
|
void configure(libtorrent::session_settings &sessionSettings);
|
||||||
void adjustLimits(libtorrent::session_settings &sessionSettings);
|
void adjustLimits(libtorrent::session_settings &sessionSettings);
|
||||||
|
#else
|
||||||
|
void configure(libtorrent::settings_pack &settingsPack);
|
||||||
|
void adjustLimits(libtorrent::settings_pack &settingsPack);
|
||||||
|
#endif
|
||||||
|
void adjustLimits();
|
||||||
|
void processBannedIPs();
|
||||||
const QStringList getListeningIPs();
|
const QStringList getListeningIPs();
|
||||||
void setListeningPort();
|
void configureListeningInterface();
|
||||||
void preAllocateAllFiles(bool b);
|
|
||||||
void setMaxConnectionsPerTorrent(int max);
|
|
||||||
void setMaxUploadsPerTorrent(int max);
|
|
||||||
void enableLSD(bool enable);
|
|
||||||
void enableDHT(bool enable);
|
|
||||||
void changeSpeedLimitMode_impl(bool alternative);
|
void changeSpeedLimitMode_impl(bool alternative);
|
||||||
|
void enableTracker(bool enable);
|
||||||
void setAppendExtension(bool append);
|
void enableBandwidthScheduler();
|
||||||
|
void populateAdditionalTrackers();
|
||||||
|
void enableIPFilter();
|
||||||
|
void disableIPFilter();
|
||||||
|
|
||||||
void startUpTorrents();
|
void startUpTorrents();
|
||||||
bool addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri,
|
bool addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri,
|
||||||
const TorrentInfo &torrentInfo = TorrentInfo(),
|
TorrentInfo torrentInfo = TorrentInfo(),
|
||||||
const QByteArray &fastresumeData = QByteArray());
|
const QByteArray &fastresumeData = QByteArray());
|
||||||
|
bool findIncompleteFiles(TorrentInfo &torrentInfo, QString &savePath) const;
|
||||||
|
|
||||||
void updateRatioTimer();
|
void updateRatioTimer();
|
||||||
void exportTorrentFile(TorrentHandle *const torrent, TorrentExportFolder folder = TorrentExportFolder::Regular);
|
void exportTorrentFile(TorrentHandle *const torrent, TorrentExportFolder folder = TorrentExportFolder::Regular);
|
||||||
|
@ -385,34 +491,100 @@ namespace BitTorrent
|
||||||
|
|
||||||
void saveResumeData();
|
void saveResumeData();
|
||||||
|
|
||||||
void dispatchAlerts(std::auto_ptr<libtorrent::alert> alertPtr);
|
#if LIBTORRENT_VERSION_NUM < 10100
|
||||||
void getPendingAlerts(QVector<libtorrent::alert *> &out, ulong time = 0);
|
void dispatchAlerts(libtorrent::alert *alertPtr);
|
||||||
|
#endif
|
||||||
SettingsStorage *m_settings;
|
void getPendingAlerts(std::vector<libtorrent::alert *> &out, ulong time = 0);
|
||||||
|
|
||||||
// BitTorrent
|
// BitTorrent
|
||||||
libtorrent::session *m_nativeSession;
|
libtorrent::session *m_nativeSession;
|
||||||
|
|
||||||
bool m_LSDEnabled;
|
bool m_deferredConfigureScheduled;
|
||||||
bool m_DHTEnabled;
|
bool m_IPFilteringChanged;
|
||||||
bool m_PeXEnabled;
|
#if LIBTORRENT_VERSION_NUM >= 10100
|
||||||
bool m_queueingEnabled;
|
bool m_listenInterfaceChanged; // optimization
|
||||||
bool m_torrentExportEnabled;
|
#endif
|
||||||
bool m_finishedTorrentExportEnabled;
|
CachedSettingValue<bool> m_isDHTEnabled;
|
||||||
bool m_preAllocateAll;
|
CachedSettingValue<bool> m_isLSDEnabled;
|
||||||
qreal m_globalMaxRatio;
|
CachedSettingValue<bool> m_isPeXEnabled;
|
||||||
|
CachedSettingValue<bool> m_isTrackerExchangeEnabled;
|
||||||
|
CachedSettingValue<bool> m_isIPFilteringEnabled;
|
||||||
|
CachedSettingValue<bool> m_isTrackerFilteringEnabled;
|
||||||
|
CachedSettingValue<QString> m_IPFilterFile;
|
||||||
|
CachedSettingValue<bool> m_announceToAllTrackers;
|
||||||
|
CachedSettingValue<uint> m_diskCacheSize;
|
||||||
|
CachedSettingValue<uint> m_diskCacheTTL;
|
||||||
|
CachedSettingValue<bool> m_useOSCache;
|
||||||
|
CachedSettingValue<bool> m_isAnonymousModeEnabled;
|
||||||
|
CachedSettingValue<bool> m_isQueueingEnabled;
|
||||||
|
CachedSettingValue<int> m_maxActiveDownloads;
|
||||||
|
CachedSettingValue<int> m_maxActiveUploads;
|
||||||
|
CachedSettingValue<int> m_maxActiveTorrents;
|
||||||
|
CachedSettingValue<bool> m_ignoreSlowTorrentsForQueueing;
|
||||||
|
CachedSettingValue<uint> m_outgoingPortsMin;
|
||||||
|
CachedSettingValue<uint> m_outgoingPortsMax;
|
||||||
|
CachedSettingValue<bool> m_ignoreLimitsOnLAN;
|
||||||
|
CachedSettingValue<bool> m_includeOverheadInLimits;
|
||||||
|
CachedSettingValue<QString> m_announceIP;
|
||||||
|
CachedSettingValue<bool> m_isSuperSeedingEnabled;
|
||||||
|
CachedSettingValue<int> m_maxConnections;
|
||||||
|
CachedSettingValue<int> m_maxHalfOpenConnections;
|
||||||
|
CachedSettingValue<int> m_maxUploads;
|
||||||
|
CachedSettingValue<int> m_maxConnectionsPerTorrent;
|
||||||
|
CachedSettingValue<int> m_maxUploadsPerTorrent;
|
||||||
|
CachedSettingValue<bool> m_isUTPEnabled;
|
||||||
|
CachedSettingValue<bool> m_isUTPRateLimited;
|
||||||
|
CachedSettingValue<bool> m_isAddTrackersEnabled;
|
||||||
|
CachedSettingValue<QString> m_additionalTrackers;
|
||||||
|
CachedSettingValue<qreal> m_globalMaxRatio;
|
||||||
|
CachedSettingValue<bool> m_isAddTorrentPaused;
|
||||||
|
CachedSettingValue<bool> m_isAppendExtensionEnabled;
|
||||||
|
CachedSettingValue<uint> m_refreshInterval;
|
||||||
|
CachedSettingValue<bool> m_isPreallocationEnabled;
|
||||||
|
CachedSettingValue<QString> m_torrentExportDirectory;
|
||||||
|
CachedSettingValue<QString> m_finishedTorrentExportDirectory;
|
||||||
|
CachedSettingValue<int> m_globalDownloadSpeedLimit;
|
||||||
|
CachedSettingValue<int> m_globalUploadSpeedLimit;
|
||||||
|
CachedSettingValue<int> m_altGlobalDownloadSpeedLimit;
|
||||||
|
CachedSettingValue<int> m_altGlobalUploadSpeedLimit;
|
||||||
|
CachedSettingValue<bool> m_isAltGlobalSpeedLimitEnabled;
|
||||||
|
CachedSettingValue<bool> m_isBandwidthSchedulerEnabled;
|
||||||
|
CachedSettingValue<uint> m_saveResumeDataInterval;
|
||||||
|
CachedSettingValue<int> m_port;
|
||||||
|
CachedSettingValue<bool> m_useRandomPort;
|
||||||
|
CachedSettingValue<QString> m_networkInterface;
|
||||||
|
CachedSettingValue<QString> m_networkInterfaceName;
|
||||||
|
CachedSettingValue<QString> m_networkInterfaceAddress;
|
||||||
|
CachedSettingValue<bool> m_isIPv6Enabled;
|
||||||
|
CachedSettingValue<int> m_encryption;
|
||||||
|
CachedSettingValue<bool> m_isForceProxyEnabled;
|
||||||
|
CachedSettingValue<bool> m_isProxyPeerConnectionsEnabled;
|
||||||
|
CachedSettingValue<QVariantMap> m_storedCategories;
|
||||||
|
CachedSettingValue<int> m_maxRatioAction;
|
||||||
|
CachedSettingValue<QString> m_defaultSavePath;
|
||||||
|
CachedSettingValue<QString> m_tempPath;
|
||||||
|
CachedSettingValue<bool> m_isSubcategoriesEnabled;
|
||||||
|
CachedSettingValue<bool> m_isTempPathEnabled;
|
||||||
|
CachedSettingValue<bool> m_isAutoTMMDisabledByDefault;
|
||||||
|
CachedSettingValue<bool> m_isDisableAutoTMMWhenCategoryChanged;
|
||||||
|
CachedSettingValue<bool> m_isDisableAutoTMMWhenDefaultSavePathChanged;
|
||||||
|
CachedSettingValue<bool> m_isDisableAutoTMMWhenCategorySavePathChanged;
|
||||||
|
CachedSettingValue<bool> m_isTrackerEnabled;
|
||||||
|
CachedSettingValue<QStringList> m_bannedIPs;
|
||||||
|
|
||||||
|
// Order is important. These need to be declared after their CachedSettingsValue
|
||||||
|
// counterparts, because they use them for initialization in the constructor
|
||||||
|
// initialization list.
|
||||||
|
const bool m_wasPexEnabled;
|
||||||
|
const bool m_wasTrackerExchangeEnabled;
|
||||||
|
|
||||||
int m_numResumeData;
|
int m_numResumeData;
|
||||||
int m_extraLimit;
|
int m_extraLimit;
|
||||||
bool m_appendExtension;
|
QList<BitTorrent::TrackerEntry> m_additionalTrackerList;
|
||||||
uint m_refreshInterval;
|
|
||||||
MaxRatioAction m_maxRatioAction;
|
|
||||||
QList<BitTorrent::TrackerEntry> m_additionalTrackers;
|
|
||||||
QString m_defaultSavePath;
|
|
||||||
QString m_tempPath;
|
|
||||||
QString m_filterPath;
|
|
||||||
QString m_resumeFolderPath;
|
QString m_resumeFolderPath;
|
||||||
QFile m_resumeFolderLock;
|
QFile m_resumeFolderLock;
|
||||||
QHash<InfoHash, QString> m_savePathsToRemove;
|
QHash<InfoHash, QString> m_savePathsToRemove;
|
||||||
|
bool m_useProxy;
|
||||||
|
|
||||||
QTimer *m_refreshTimer;
|
QTimer *m_refreshTimer;
|
||||||
QTimer *m_bigRatioTimer;
|
QTimer *m_bigRatioTimer;
|
||||||
|
@ -434,12 +606,16 @@ namespace BitTorrent
|
||||||
TorrentStatusReport m_torrentStatusReport;
|
TorrentStatusReport m_torrentStatusReport;
|
||||||
QStringMap m_categories;
|
QStringMap m_categories;
|
||||||
|
|
||||||
|
#if LIBTORRENT_VERSION_NUM < 10100
|
||||||
QMutex m_alertsMutex;
|
QMutex m_alertsMutex;
|
||||||
QWaitCondition m_alertsWaitCondition;
|
QWaitCondition m_alertsWaitCondition;
|
||||||
QVector<libtorrent::alert *> m_alerts;
|
std::vector<libtorrent::alert *> m_alerts;
|
||||||
|
#endif
|
||||||
|
|
||||||
QNetworkConfigurationManager m_networkManager;
|
QNetworkConfigurationManager m_networkManager;
|
||||||
|
|
||||||
|
mutable QReadWriteLock m_lock;
|
||||||
|
|
||||||
static Session *m_instance;
|
static Session *m_instance;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@
|
||||||
#include "trackerentry.h"
|
#include "trackerentry.h"
|
||||||
#include "torrenthandle.h"
|
#include "torrenthandle.h"
|
||||||
|
|
||||||
static const char QB_EXT[] = ".!qB";
|
const QString QB_EXT {".!qB"};
|
||||||
|
|
||||||
namespace libt = libtorrent;
|
namespace libt = libtorrent;
|
||||||
using namespace BitTorrent;
|
using namespace BitTorrent;
|
||||||
|
@ -199,10 +199,10 @@ TorrentHandle::TorrentHandle(Session *session, const libtorrent::torrent_handle
|
||||||
, m_nativeHandle(nativeHandle)
|
, m_nativeHandle(nativeHandle)
|
||||||
, m_state(TorrentState::Unknown)
|
, m_state(TorrentState::Unknown)
|
||||||
, m_renameCount(0)
|
, m_renameCount(0)
|
||||||
|
, m_useAutoTMM(data.savePath.isEmpty())
|
||||||
, m_name(data.name)
|
, m_name(data.name)
|
||||||
, m_savePath(Utils::Fs::toNativePath(data.savePath))
|
, m_savePath(Utils::Fs::toNativePath(data.savePath))
|
||||||
, m_category(data.category)
|
, m_category(data.category)
|
||||||
, m_useASM(data.savePath.isEmpty())
|
|
||||||
, m_hasSeedStatus(data.hasSeedStatus)
|
, m_hasSeedStatus(data.hasSeedStatus)
|
||||||
, m_ratioLimit(data.ratioLimit)
|
, m_ratioLimit(data.ratioLimit)
|
||||||
, m_tempPathDisabled(data.disableTempPath)
|
, m_tempPathDisabled(data.disableTempPath)
|
||||||
|
@ -210,20 +210,14 @@ TorrentHandle::TorrentHandle(Session *session, const libtorrent::torrent_handle
|
||||||
, m_pauseAfterRecheck(false)
|
, m_pauseAfterRecheck(false)
|
||||||
, m_needSaveResumeData(false)
|
, m_needSaveResumeData(false)
|
||||||
{
|
{
|
||||||
if (m_useASM)
|
if (m_useAutoTMM)
|
||||||
m_savePath = Utils::Fs::toNativePath(m_session->categorySavePath(m_category));
|
m_savePath = Utils::Fs::toNativePath(m_session->categorySavePath(m_category));
|
||||||
|
|
||||||
updateStatus();
|
updateStatus();
|
||||||
m_hash = InfoHash(m_nativeStatus.info_hash);
|
m_hash = InfoHash(m_nativeStatus.info_hash);
|
||||||
adjustActualSavePath();
|
|
||||||
|
|
||||||
if (!data.resumed) {
|
if (!data.resumed)
|
||||||
setSequentialDownload(data.sequential);
|
setSequentialDownload(data.sequential);
|
||||||
if (hasMetadata()) {
|
|
||||||
if (m_session->isAppendExtensionEnabled())
|
|
||||||
appendExtensionsToIncompleteFiles();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TorrentHandle::~TorrentHandle() {}
|
TorrentHandle::~TorrentHandle() {}
|
||||||
|
@ -332,19 +326,19 @@ QString TorrentHandle::contentPath(bool actual) const
|
||||||
return rootPath(actual);
|
return rootPath(actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TorrentHandle::isASMEnabled() const
|
bool TorrentHandle::isAutoTMMEnabled() const
|
||||||
{
|
{
|
||||||
return m_useASM;
|
return m_useAutoTMM;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TorrentHandle::setASMEnabled(bool enabled)
|
void TorrentHandle::setAutoTMMEnabled(bool enabled)
|
||||||
{
|
{
|
||||||
if (m_useASM == enabled) return;
|
if (m_useAutoTMM == enabled) return;
|
||||||
|
|
||||||
m_useASM = enabled;
|
m_useAutoTMM = enabled;
|
||||||
m_session->handleTorrentSavingModeChanged(this);
|
m_session->handleTorrentSavingModeChanged(this);
|
||||||
|
|
||||||
if (m_useASM)
|
if (m_useAutoTMM)
|
||||||
move_impl(m_session->categorySavePath(m_category));
|
move_impl(m_session->categorySavePath(m_category));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -603,25 +597,6 @@ QStringList TorrentHandle::absoluteFilePathsUnwanted() const
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPair<int, int> TorrentHandle::fileExtremityPieces(int index) const
|
|
||||||
{
|
|
||||||
if (!hasMetadata()) return qMakePair(-1, -1);
|
|
||||||
|
|
||||||
const int numPieces = piecesCount();
|
|
||||||
const qlonglong pieceSize = pieceLength();
|
|
||||||
|
|
||||||
// Determine the first and last piece of the file
|
|
||||||
int firstPiece = floor((m_torrentInfo.fileOffset(index) + 1) / (float) pieceSize);
|
|
||||||
Q_ASSERT((firstPiece >= 0) && (firstPiece < numPieces));
|
|
||||||
|
|
||||||
int numPiecesInFile = ceil(fileSize(index) / (float) pieceSize);
|
|
||||||
int lastPiece = firstPiece + numPiecesInFile - 1;
|
|
||||||
Q_ASSERT((lastPiece >= 0) && (lastPiece < numPieces));
|
|
||||||
|
|
||||||
Q_UNUSED(numPieces)
|
|
||||||
return qMakePair(firstPiece, lastPiece);
|
|
||||||
}
|
|
||||||
|
|
||||||
QVector<int> TorrentHandle::filePriorities() const
|
QVector<int> TorrentHandle::filePriorities() const
|
||||||
{
|
{
|
||||||
std::vector<int> fp;
|
std::vector<int> fp;
|
||||||
|
@ -739,13 +714,13 @@ bool TorrentHandle::hasFirstLastPiecePriority() const
|
||||||
std::vector<int> fp;
|
std::vector<int> fp;
|
||||||
SAFE_GET(fp, file_priorities);
|
SAFE_GET(fp, file_priorities);
|
||||||
|
|
||||||
QPair<int, int> extremities;
|
TorrentInfo::PieceRange extremities;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
int count = static_cast<int>(fp.size());
|
int count = static_cast<int>(fp.size());
|
||||||
for (int i = 0; i < count; ++i) {
|
for (int i = 0; i < count; ++i) {
|
||||||
const QString ext = Utils::Fs::fileExtension(filePath(i));
|
const QString ext = Utils::Fs::fileExtension(filePath(i));
|
||||||
if (Utils::Misc::isPreviewable(ext) && (fp[i] > 0)) {
|
if (Utils::Misc::isPreviewable(ext) && (fp[i] > 0)) {
|
||||||
extremities = fileExtremityPieces(i);
|
extremities = info().filePieces(i);
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -755,8 +730,8 @@ bool TorrentHandle::hasFirstLastPiecePriority() const
|
||||||
|
|
||||||
int first = 0;
|
int first = 0;
|
||||||
int last = 0;
|
int last = 0;
|
||||||
SAFE_GET(first, piece_priority, extremities.first);
|
SAFE_GET(first, piece_priority, extremities.first());
|
||||||
SAFE_GET(last, piece_priority, extremities.second);
|
SAFE_GET(last, piece_priority, extremities.last());
|
||||||
|
|
||||||
return ((first == 7) && (last == 7));
|
return ((first == 7) && (last == 7));
|
||||||
}
|
}
|
||||||
|
@ -777,7 +752,7 @@ void TorrentHandle::updateState()
|
||||||
m_state = isSeed() ? TorrentState::PausedUploading : TorrentState::PausedDownloading;
|
m_state = isSeed() ? TorrentState::PausedUploading : TorrentState::PausedDownloading;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (m_session->isQueueingEnabled() && isQueued() && !isChecking()) {
|
if (m_session->isQueueingSystemEnabled() && isQueued() && !isChecking()) {
|
||||||
m_state = isSeed() ? TorrentState::QueuedUploading : TorrentState::QueuedDownloading;
|
m_state = isSeed() ? TorrentState::QueuedUploading : TorrentState::QueuedDownloading;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1156,11 +1131,11 @@ bool TorrentHandle::setCategory(const QString &category)
|
||||||
m_needSaveResumeData = true;
|
m_needSaveResumeData = true;
|
||||||
m_session->handleTorrentCategoryChanged(this, oldCategory);
|
m_session->handleTorrentCategoryChanged(this, oldCategory);
|
||||||
|
|
||||||
if (m_useASM) {
|
if (m_useAutoTMM) {
|
||||||
if (!m_session->isDisableASMWhenCategoryChanged())
|
if (!m_session->isDisableAutoTMMWhenCategoryChanged())
|
||||||
move_impl(m_session->categorySavePath(m_category));
|
move_impl(m_session->categorySavePath(m_category));
|
||||||
else
|
else
|
||||||
setASMEnabled(false);
|
setAutoTMMEnabled(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1169,7 +1144,7 @@ bool TorrentHandle::setCategory(const QString &category)
|
||||||
|
|
||||||
void TorrentHandle::move(QString path)
|
void TorrentHandle::move(QString path)
|
||||||
{
|
{
|
||||||
m_useASM = false;
|
m_useAutoTMM = false;
|
||||||
m_session->handleTorrentSavingModeChanged(this);
|
m_session->handleTorrentSavingModeChanged(this);
|
||||||
|
|
||||||
path = Utils::Fs::fromNativePath(path.trimmed());
|
path = Utils::Fs::fromNativePath(path.trimmed());
|
||||||
|
@ -1251,13 +1226,13 @@ void TorrentHandle::setFirstLastPiecePriority(bool b)
|
||||||
// Determine the priority to set
|
// Determine the priority to set
|
||||||
int prio = b ? 7 : fp[index];
|
int prio = b ? 7 : fp[index];
|
||||||
|
|
||||||
QPair<int, int> extremities = fileExtremityPieces(index);
|
TorrentInfo::PieceRange extremities = info().filePieces(index);
|
||||||
|
|
||||||
// worst case: AVI index = 1% of total file size (at the end of the file)
|
// worst case: AVI index = 1% of total file size (at the end of the file)
|
||||||
int nNumPieces = ceil(fileSize(index) * 0.01 / pieceLength());
|
int nNumPieces = ceil(fileSize(index) * 0.01 / pieceLength());
|
||||||
for (int i = 0; i < nNumPieces; ++i) {
|
for (int i = 0; i < nNumPieces; ++i) {
|
||||||
pp[extremities.first + i] = prio;
|
pp[extremities.first() + i] = prio;
|
||||||
pp[extremities.second - i] = prio;
|
pp[extremities.last() - i] = prio;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1309,10 +1284,6 @@ void TorrentHandle::moveStorage(const QString &newPath)
|
||||||
if (QDir(oldPath) == QDir(newPath)) return;
|
if (QDir(oldPath) == QDir(newPath)) return;
|
||||||
|
|
||||||
qDebug("move storage: %s to %s", qPrintable(oldPath), qPrintable(newPath));
|
qDebug("move storage: %s to %s", qPrintable(oldPath), qPrintable(newPath));
|
||||||
// Create destination directory if necessary
|
|
||||||
// or move_storage() will fail...
|
|
||||||
QDir().mkpath(newPath);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Actually move the storage
|
// Actually move the storage
|
||||||
m_nativeHandle.move_storage(newPath.toUtf8().constData());
|
m_nativeHandle.move_storage(newPath.toUtf8().constData());
|
||||||
|
@ -1398,7 +1369,7 @@ void TorrentHandle::handleStorageMovedAlert(libtorrent::storage_moved_alert *p)
|
||||||
|
|
||||||
// Attempt to remove old folder if empty
|
// Attempt to remove old folder if empty
|
||||||
QDir oldSaveDir(Utils::Fs::fromNativePath(m_oldPath));
|
QDir oldSaveDir(Utils::Fs::fromNativePath(m_oldPath));
|
||||||
if ((oldSaveDir != QDir(m_session->defaultSavePath())) && (oldSaveDir != QDir(m_session->tempPath()))) {
|
if (oldSaveDir != QDir(m_session->defaultSavePath())) {
|
||||||
qDebug("Attempting to remove %s", qPrintable(m_oldPath));
|
qDebug("Attempting to remove %s", qPrintable(m_oldPath));
|
||||||
QDir().rmpath(m_oldPath);
|
QDir().rmpath(m_oldPath);
|
||||||
}
|
}
|
||||||
|
@ -1475,6 +1446,7 @@ void TorrentHandle::handleTorrentCheckedAlert(libtorrent::torrent_checked_alert
|
||||||
m_hasSeedStatus = true;
|
m_hasSeedStatus = true;
|
||||||
|
|
||||||
adjustActualSavePath();
|
adjustActualSavePath();
|
||||||
|
manageIncompleteFiles();
|
||||||
|
|
||||||
if (m_pauseAfterRecheck) {
|
if (m_pauseAfterRecheck) {
|
||||||
m_pauseAfterRecheck = false;
|
m_pauseAfterRecheck = false;
|
||||||
|
@ -1496,13 +1468,19 @@ void TorrentHandle::handleTorrentFinishedAlert(libtorrent::torrent_finished_aler
|
||||||
m_hasSeedStatus = true;
|
m_hasSeedStatus = true;
|
||||||
|
|
||||||
adjustActualSavePath();
|
adjustActualSavePath();
|
||||||
if (Preferences::instance()->recheckTorrentsOnCompletion())
|
manageIncompleteFiles();
|
||||||
forceRecheck();
|
|
||||||
|
|
||||||
if (isMoveInProgress() || m_renameCount > 0)
|
const bool recheckTorrentsOnCompletion = Preferences::instance()->recheckTorrentsOnCompletion();
|
||||||
|
if (isMoveInProgress() || m_renameCount > 0) {
|
||||||
|
if (recheckTorrentsOnCompletion)
|
||||||
|
m_moveFinishedTriggers.append(boost::bind(&TorrentHandle::forceRecheck, this));
|
||||||
m_moveFinishedTriggers.append(boost::bind(&Session::handleTorrentFinished, m_session, this));
|
m_moveFinishedTriggers.append(boost::bind(&Session::handleTorrentFinished, m_session, this));
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
|
if (recheckTorrentsOnCompletion)
|
||||||
|
forceRecheck();
|
||||||
m_session->handleTorrentFinished(this);
|
m_session->handleTorrentFinished(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TorrentHandle::handleTorrentPausedAlert(libtorrent::torrent_paused_alert *p)
|
void TorrentHandle::handleTorrentPausedAlert(libtorrent::torrent_paused_alert *p)
|
||||||
|
@ -1530,7 +1508,7 @@ void TorrentHandle::handleSaveResumeDataAlert(libtorrent::save_resume_data_alert
|
||||||
resumeData["qBt-paused"] = isPaused();
|
resumeData["qBt-paused"] = isPaused();
|
||||||
resumeData["qBt-forced"] = isForced();
|
resumeData["qBt-forced"] = isForced();
|
||||||
}
|
}
|
||||||
resumeData["qBt-savePath"] = m_useASM ? "" : Utils::String::toStdString(m_savePath);
|
resumeData["qBt-savePath"] = m_useAutoTMM ? "" : Utils::String::toStdString(m_savePath);
|
||||||
resumeData["qBt-ratioLimit"] = Utils::String::toStdString(QString::number(m_ratioLimit));
|
resumeData["qBt-ratioLimit"] = Utils::String::toStdString(QString::number(m_ratioLimit));
|
||||||
resumeData["qBt-category"] = Utils::String::toStdString(m_category);
|
resumeData["qBt-category"] = Utils::String::toStdString(m_category);
|
||||||
resumeData["qBt-name"] = Utils::String::toStdString(m_name);
|
resumeData["qBt-name"] = Utils::String::toStdString(m_name);
|
||||||
|
@ -1616,7 +1594,7 @@ void TorrentHandle::handleFileCompletedAlert(libtorrent::file_completed_alert *p
|
||||||
QString name = filePath(p->index);
|
QString name = filePath(p->index);
|
||||||
if (name.endsWith(QB_EXT)) {
|
if (name.endsWith(QB_EXT)) {
|
||||||
const QString oldName = name;
|
const QString oldName = name;
|
||||||
name.chop(QString(QB_EXT).size());
|
name.chop(QB_EXT.size());
|
||||||
qDebug("Renaming %s to %s", qPrintable(oldName), qPrintable(name));
|
qDebug("Renaming %s to %s", qPrintable(oldName), qPrintable(name));
|
||||||
renameFile(p->index, name);
|
renameFile(p->index, name);
|
||||||
}
|
}
|
||||||
|
@ -1637,7 +1615,7 @@ void TorrentHandle::handleMetadataReceivedAlert(libt::metadata_received_alert *p
|
||||||
qDebug("Metadata received for torrent %s.", qPrintable(name()));
|
qDebug("Metadata received for torrent %s.", qPrintable(name()));
|
||||||
updateStatus();
|
updateStatus();
|
||||||
if (m_session->isAppendExtensionEnabled())
|
if (m_session->isAppendExtensionEnabled())
|
||||||
appendExtensionsToIncompleteFiles();
|
manageIncompleteFiles();
|
||||||
m_session->handleTorrentMetadataReceived(this);
|
m_session->handleTorrentMetadataReceived(this);
|
||||||
|
|
||||||
if (isPaused()) {
|
if (isPaused()) {
|
||||||
|
@ -1655,7 +1633,7 @@ void TorrentHandle::handleTempPathChanged()
|
||||||
|
|
||||||
void TorrentHandle::handleCategorySavePathChanged()
|
void TorrentHandle::handleCategorySavePathChanged()
|
||||||
{
|
{
|
||||||
if (m_useASM)
|
if (m_useAutoTMM)
|
||||||
move_impl(m_session->categorySavePath(m_category));
|
move_impl(m_session->categorySavePath(m_category));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1663,10 +1641,7 @@ void TorrentHandle::handleAppendExtensionToggled()
|
||||||
{
|
{
|
||||||
if (!hasMetadata()) return;
|
if (!hasMetadata()) return;
|
||||||
|
|
||||||
if (m_session->isAppendExtensionEnabled())
|
manageIncompleteFiles();
|
||||||
appendExtensionsToIncompleteFiles();
|
|
||||||
else
|
|
||||||
removeExtensionsFromIncompleteFiles();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TorrentHandle::handleAlert(libtorrent::alert *a)
|
void TorrentHandle::handleAlert(libtorrent::alert *a)
|
||||||
|
@ -1723,30 +1698,26 @@ void TorrentHandle::handleAlert(libtorrent::alert *a)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TorrentHandle::appendExtensionsToIncompleteFiles()
|
void TorrentHandle::manageIncompleteFiles()
|
||||||
{
|
{
|
||||||
|
const bool isAppendExtensionEnabled = m_session->isAppendExtensionEnabled();
|
||||||
QVector<qreal> fp = filesProgress();
|
QVector<qreal> fp = filesProgress();
|
||||||
for (int i = 0; i < filesCount(); ++i) {
|
for (int i = 0; i < filesCount(); ++i) {
|
||||||
if ((fileSize(i) > 0) && (fp[i] < 1)) {
|
QString name = filePath(i);
|
||||||
const QString name = filePath(i);
|
if (isAppendExtensionEnabled && (fileSize(i) > 0) && (fp[i] < 1)) {
|
||||||
if (!name.endsWith(QB_EXT)) {
|
if (!name.endsWith(QB_EXT)) {
|
||||||
const QString newName = name + QB_EXT;
|
const QString newName = name + QB_EXT;
|
||||||
qDebug("Renaming %s to %s", qPrintable(name), qPrintable(newName));
|
qDebug() << "Renaming" << name << "to" << newName;
|
||||||
renameFile(i, newName);
|
renameFile(i, newName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
}
|
if (name.endsWith(QB_EXT)) {
|
||||||
|
const QString oldName = name;
|
||||||
void TorrentHandle::removeExtensionsFromIncompleteFiles()
|
name.chop(QB_EXT.size());
|
||||||
{
|
qDebug() << "Renaming" << oldName << "to" << name;
|
||||||
for (int i = 0; i < filesCount(); ++i) {
|
renameFile(i, name);
|
||||||
QString name = filePath(i);
|
}
|
||||||
if (name.endsWith(QB_EXT)) {
|
|
||||||
const QString oldName = name;
|
|
||||||
name.chop(QString(QB_EXT).size());
|
|
||||||
qDebug("Renaming %s to %s", qPrintable(oldName), qPrintable(name));
|
|
||||||
renameFile(i, name);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1769,8 +1740,8 @@ void TorrentHandle::adjustActualSavePath_impl()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Moving all downloading torrents to temporary save path
|
// Moving all downloading torrents to temporary save path
|
||||||
path = m_session->tempPath();
|
path = m_session->torrentTempPath(hash());
|
||||||
qDebug("Moving torrent to its temp save path: %s", qPrintable(path));
|
qDebug() << "Moving torrent to its temp save path:" << path;
|
||||||
}
|
}
|
||||||
|
|
||||||
moveStorage(Utils::Fs::toNativePath(path));
|
moveStorage(Utils::Fs::toNativePath(path));
|
||||||
|
|
|
@ -54,6 +54,8 @@ class QBitArray;
|
||||||
class QStringList;
|
class QStringList;
|
||||||
template<typename T, typename U> struct QPair;
|
template<typename T, typename U> struct QPair;
|
||||||
|
|
||||||
|
extern const QString QB_EXT;
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
class alert;
|
class alert;
|
||||||
|
@ -227,8 +229,8 @@ namespace BitTorrent
|
||||||
QString rootPath(bool actual = false) const;
|
QString rootPath(bool actual = false) const;
|
||||||
QString contentPath(bool actual = false) const;
|
QString contentPath(bool actual = false) const;
|
||||||
|
|
||||||
bool isASMEnabled() const;
|
bool isAutoTMMEnabled() const;
|
||||||
void setASMEnabled(bool enabled);
|
void setAutoTMMEnabled(bool enabled);
|
||||||
QString category() const;
|
QString category() const;
|
||||||
bool belongsToCategory(const QString &category) const;
|
bool belongsToCategory(const QString &category) const;
|
||||||
bool setCategory(const QString &category);
|
bool setCategory(const QString &category);
|
||||||
|
@ -245,7 +247,6 @@ namespace BitTorrent
|
||||||
qlonglong fileSize(int index) const;
|
qlonglong fileSize(int index) const;
|
||||||
QStringList absoluteFilePaths() const;
|
QStringList absoluteFilePaths() const;
|
||||||
QStringList absoluteFilePathsUnwanted() const;
|
QStringList absoluteFilePathsUnwanted() const;
|
||||||
QPair<int, int> fileExtremityPieces(int index) const;
|
|
||||||
QVector<int> filePriorities() const;
|
QVector<int> filePriorities() const;
|
||||||
|
|
||||||
TorrentInfo info() const;
|
TorrentInfo info() const;
|
||||||
|
@ -386,8 +387,7 @@ namespace BitTorrent
|
||||||
void adjustActualSavePath_impl();
|
void adjustActualSavePath_impl();
|
||||||
void move_impl(QString path);
|
void move_impl(QString path);
|
||||||
void moveStorage(const QString &newPath);
|
void moveStorage(const QString &newPath);
|
||||||
void appendExtensionsToIncompleteFiles();
|
void manageIncompleteFiles();
|
||||||
void removeExtensionsFromIncompleteFiles();
|
|
||||||
bool addTracker(const TrackerEntry &tracker);
|
bool addTracker(const TrackerEntry &tracker);
|
||||||
bool addUrlSeed(const QUrl &urlSeed);
|
bool addUrlSeed(const QUrl &urlSeed);
|
||||||
bool removeUrlSeed(const QUrl &urlSeed);
|
bool removeUrlSeed(const QUrl &urlSeed);
|
||||||
|
@ -411,7 +411,7 @@ namespace BitTorrent
|
||||||
QQueue<EventTrigger> m_moveFinishedTriggers;
|
QQueue<EventTrigger> m_moveFinishedTriggers;
|
||||||
int m_renameCount;
|
int m_renameCount;
|
||||||
|
|
||||||
bool m_useASM;
|
bool m_useAutoTMM;
|
||||||
|
|
||||||
// Persistent data
|
// Persistent data
|
||||||
QString m_name;
|
QString m_name;
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
@ -138,6 +139,12 @@ int TorrentInfo::pieceLength() const
|
||||||
return m_nativeInfo->piece_length();
|
return m_nativeInfo->piece_length();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int TorrentInfo::pieceLength(int index) const
|
||||||
|
{
|
||||||
|
if (!isValid()) return -1;
|
||||||
|
return m_nativeInfo->piece_size(index);
|
||||||
|
}
|
||||||
|
|
||||||
int TorrentInfo::piecesCount() const
|
int TorrentInfo::piecesCount() const
|
||||||
{
|
{
|
||||||
if (!isValid()) return -1;
|
if (!isValid()) return -1;
|
||||||
|
@ -178,7 +185,7 @@ qlonglong TorrentInfo::fileSize(int index) const
|
||||||
|
|
||||||
qlonglong TorrentInfo::fileOffset(int index) const
|
qlonglong TorrentInfo::fileOffset(int index) const
|
||||||
{
|
{
|
||||||
if (!isValid()) return -1;
|
if (!isValid()) return -1;
|
||||||
return m_nativeInfo->file_at(index).offset;
|
return m_nativeInfo->file_at(index).offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,24 +220,79 @@ QByteArray TorrentInfo::metadata() const
|
||||||
|
|
||||||
QStringList TorrentInfo::filesForPiece(int pieceIndex) const
|
QStringList TorrentInfo::filesForPiece(int pieceIndex) const
|
||||||
{
|
{
|
||||||
if (pieceIndex < 0)
|
// no checks here because fileIndicesForPiece() will return an empty list
|
||||||
return QStringList();
|
QVector<int> fileIndices = fileIndicesForPiece(pieceIndex);
|
||||||
|
|
||||||
std::vector<libtorrent::file_slice> files(
|
|
||||||
nativeInfo()->map_block(pieceIndex, 0, nativeInfo()->piece_size(pieceIndex)));
|
|
||||||
QStringList res;
|
QStringList res;
|
||||||
for (const libtorrent::file_slice& s: files) {
|
res.reserve(fileIndices.size());
|
||||||
res.append(filePath(s.file_index));
|
std::transform(fileIndices.begin(), fileIndices.end(), std::back_inserter(res),
|
||||||
}
|
[this](int i) { return filePath(i); });
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVector<int> TorrentInfo::fileIndicesForPiece(int pieceIndex) const
|
||||||
|
{
|
||||||
|
if (!isValid() || (pieceIndex < 0) || (pieceIndex >= piecesCount()))
|
||||||
|
return QVector<int>();
|
||||||
|
|
||||||
|
std::vector<libt::file_slice> files(
|
||||||
|
nativeInfo()->map_block(pieceIndex, 0, nativeInfo()->piece_size(pieceIndex)));
|
||||||
|
QVector<int> res;
|
||||||
|
res.reserve(int(files.size()));
|
||||||
|
std::transform(files.begin(), files.end(), std::back_inserter(res),
|
||||||
|
[](const libt::file_slice &s) { return s.file_index; });
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
TorrentInfo::PieceRange TorrentInfo::filePieces(const QString& file) const
|
||||||
|
{
|
||||||
|
if (!isValid()) // if we do not check here the debug message will be printed, which would be not correct
|
||||||
|
return {};
|
||||||
|
|
||||||
|
int index = fileIndex(file);
|
||||||
|
if (index == -1) {
|
||||||
|
qDebug() << "Filename" << file << "was not found in torrent" << name();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return filePieces(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
TorrentInfo::PieceRange TorrentInfo::filePieces(int fileIndex) const
|
||||||
|
{
|
||||||
|
if (!isValid())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
if ((fileIndex < 0) || (fileIndex >= filesCount())) {
|
||||||
|
qDebug() << "File index (" << fileIndex << ") is out of range for torrent" << name();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const libt::file_storage &files = nativeInfo()->files();
|
||||||
|
const auto fileSize = files.file_size(fileIndex);
|
||||||
|
const auto firstOffset = files.file_offset(fileIndex);
|
||||||
|
return makeInterval(static_cast<int>(firstOffset / pieceLength()),
|
||||||
|
static_cast<int>((firstOffset + fileSize - 1) / pieceLength()));
|
||||||
|
}
|
||||||
|
|
||||||
void TorrentInfo::renameFile(uint index, const QString &newPath)
|
void TorrentInfo::renameFile(uint index, const QString &newPath)
|
||||||
{
|
{
|
||||||
if (!isValid()) return;
|
if (!isValid()) return;
|
||||||
nativeInfo()->rename_file(index, Utils::String::toStdString(newPath));
|
nativeInfo()->rename_file(index, Utils::String::toStdString(newPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int BitTorrent::TorrentInfo::fileIndex(const QString& fileName) const
|
||||||
|
{
|
||||||
|
// the check whether the object valid is not needed here
|
||||||
|
// because filesCount() returns -1 in that case and the loop exits immediately
|
||||||
|
for (int i = 0; i < filesCount(); ++i)
|
||||||
|
if (fileName == filePath(i))
|
||||||
|
return i;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
TorrentInfo::NativePtr TorrentInfo::nativeInfo() const
|
TorrentInfo::NativePtr TorrentInfo::nativeInfo() const
|
||||||
{
|
{
|
||||||
return m_nativeInfo;
|
return m_nativeInfo;
|
||||||
|
|
|
@ -34,12 +34,15 @@
|
||||||
#include <libtorrent/torrent_info.hpp>
|
#include <libtorrent/torrent_info.hpp>
|
||||||
#include <libtorrent/version.hpp>
|
#include <libtorrent/version.hpp>
|
||||||
|
|
||||||
|
#include "base/indexrange.h"
|
||||||
|
|
||||||
class QString;
|
class QString;
|
||||||
class QUrl;
|
class QUrl;
|
||||||
class QDateTime;
|
class QDateTime;
|
||||||
class QStringList;
|
class QStringList;
|
||||||
class QByteArray;
|
class QByteArray;
|
||||||
template<typename T> class QList;
|
template<typename T> class QList;
|
||||||
|
template<typename T> class QVector;
|
||||||
|
|
||||||
namespace BitTorrent
|
namespace BitTorrent
|
||||||
{
|
{
|
||||||
|
@ -75,6 +78,7 @@ namespace BitTorrent
|
||||||
qlonglong totalSize() const;
|
qlonglong totalSize() const;
|
||||||
int filesCount() const;
|
int filesCount() const;
|
||||||
int pieceLength() const;
|
int pieceLength() const;
|
||||||
|
int pieceLength(int index) const;
|
||||||
int piecesCount() const;
|
int piecesCount() const;
|
||||||
QString filePath(int index) const;
|
QString filePath(int index) const;
|
||||||
QStringList filePaths() const;
|
QStringList filePaths() const;
|
||||||
|
@ -86,12 +90,21 @@ namespace BitTorrent
|
||||||
QList<QUrl> urlSeeds() const;
|
QList<QUrl> urlSeeds() const;
|
||||||
QByteArray metadata() const;
|
QByteArray metadata() const;
|
||||||
QStringList filesForPiece(int pieceIndex) const;
|
QStringList filesForPiece(int pieceIndex) const;
|
||||||
|
QVector<int> fileIndicesForPiece(int pieceIndex) const;
|
||||||
|
|
||||||
|
using PieceRange = IndexRange<int>;
|
||||||
|
// returns pair of the first and the last pieces into which
|
||||||
|
// the given file extends (maybe partially).
|
||||||
|
PieceRange filePieces(const QString &file) const;
|
||||||
|
PieceRange filePieces(int fileIndex) const;
|
||||||
|
|
||||||
void renameFile(uint index, const QString &newPath);
|
void renameFile(uint index, const QString &newPath);
|
||||||
|
|
||||||
NativePtr nativeInfo() const;
|
NativePtr nativeInfo() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// returns file index or -1 if fileName is not found
|
||||||
|
int fileIndex(const QString &fileName) const;
|
||||||
NativePtr m_nativeInfo;
|
NativePtr m_nativeInfo;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,6 +91,7 @@ void Server::incomingConnection(int socketDescriptor)
|
||||||
#else
|
#else
|
||||||
static_cast<QSslSocket*>(serverSocket)->setLocalCertificate(m_certificates.first());
|
static_cast<QSslSocket*>(serverSocket)->setLocalCertificate(m_certificates.first());
|
||||||
#endif
|
#endif
|
||||||
|
static_cast<QSslSocket*>(serverSocket)->setPeerVerifyMode(QSslSocket::VerifyNone);
|
||||||
static_cast<QSslSocket*>(serverSocket)->startServerEncryption();
|
static_cast<QSslSocket*>(serverSocket)->startServerEncryption();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
130
src/base/indexrange.h
Normal file
130
src/base/indexrange.h
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
/*
|
||||||
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
|
* Copyright (C) 2016 Eugene Shalygin
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the copyright holders give permission to
|
||||||
|
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
||||||
|
* modified versions of it that use the same license as the "OpenSSL" library),
|
||||||
|
* and distribute the linked executables. You must obey the GNU General Public
|
||||||
|
* License in all respects for all of the code used other than "OpenSSL". If you
|
||||||
|
* modify file(s), you may extend this exception to your version of the file(s),
|
||||||
|
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||||
|
* exception statement from your version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef QBT_INDEXRANGE_H
|
||||||
|
#define QBT_INDEXRANGE_H
|
||||||
|
|
||||||
|
#include <QtGlobal>
|
||||||
|
|
||||||
|
// Interval is defined via [first;last]
|
||||||
|
template <typename Index>
|
||||||
|
class IndexInterval
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using IndexType = Index;
|
||||||
|
|
||||||
|
IndexInterval(IndexType first, IndexType last)
|
||||||
|
: m_first {first}
|
||||||
|
, m_last {last}
|
||||||
|
{
|
||||||
|
Q_ASSERT(first <= last);
|
||||||
|
}
|
||||||
|
|
||||||
|
IndexType first() const
|
||||||
|
{
|
||||||
|
return m_first;
|
||||||
|
}
|
||||||
|
|
||||||
|
IndexType last() const
|
||||||
|
{
|
||||||
|
return m_last;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
IndexType m_first;
|
||||||
|
IndexType m_last;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline IndexInterval<T> makeInterval(T first, T last)
|
||||||
|
{
|
||||||
|
return {first, last};
|
||||||
|
}
|
||||||
|
|
||||||
|
// range is defined via first index and size
|
||||||
|
template <typename Index, typename IndexDiff = Index>
|
||||||
|
class IndexRange
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using IndexType = Index;
|
||||||
|
using IndexDiffType = IndexDiff;
|
||||||
|
|
||||||
|
constexpr IndexRange()
|
||||||
|
: m_first {0}
|
||||||
|
, m_size {0}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr IndexRange(IndexType first, IndexDiffType size)
|
||||||
|
: m_first {first}
|
||||||
|
, m_size {size}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr IndexRange(const IndexInterval<IndexType> &interval)
|
||||||
|
: m_first {interval.first()}
|
||||||
|
, m_size {interval.last() - interval.first() + 1}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr IndexType begin() const
|
||||||
|
{
|
||||||
|
return m_first;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr IndexType end() const
|
||||||
|
{
|
||||||
|
return m_first + m_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr IndexDiffType size() const
|
||||||
|
{
|
||||||
|
return m_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr IndexType first() const
|
||||||
|
{
|
||||||
|
return m_first;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr IndexType last() const
|
||||||
|
{
|
||||||
|
return m_first + m_size - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool isEmpty() const
|
||||||
|
{
|
||||||
|
return m_size == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
IndexType m_first;
|
||||||
|
IndexDiffType m_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QBT_INDEXRANGE_H
|
|
@ -27,20 +27,21 @@
|
||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "downloadmanager.h"
|
||||||
|
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QNetworkRequest>
|
#include <QDebug>
|
||||||
#include <QNetworkProxy>
|
|
||||||
#include <QNetworkCookieJar>
|
|
||||||
#include <QNetworkReply>
|
|
||||||
#include <QNetworkCookie>
|
#include <QNetworkCookie>
|
||||||
#include <QNetworkCookieJar>
|
#include <QNetworkCookieJar>
|
||||||
|
#include <QNetworkProxy>
|
||||||
|
#include <QNetworkReply>
|
||||||
|
#include <QNetworkRequest>
|
||||||
#include <QSslError>
|
#include <QSslError>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
#include "base/preferences.h"
|
#include "base/preferences.h"
|
||||||
#include "downloadhandler.h"
|
#include "downloadhandler.h"
|
||||||
#include "downloadmanager.h"
|
#include "proxyconfigurationmanager.h"
|
||||||
|
|
||||||
// Spoof Firefox 38 user agent to avoid web server banning
|
// Spoof Firefox 38 user agent to avoid web server banning
|
||||||
const char DEFAULT_USER_AGENT[] = "Mozilla/5.0 (X11; Linux i686; rv:38.0) Gecko/20100101 Firefox/38.0";
|
const char DEFAULT_USER_AGENT[] = "Mozilla/5.0 (X11; Linux i686; rv:38.0) Gecko/20100101 Firefox/38.0";
|
||||||
|
@ -75,6 +76,9 @@ namespace
|
||||||
Preferences::instance()->setNetworkCookies(cookies);
|
Preferences::instance()->setNetworkCookies(cookies);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using QNetworkCookieJar::allCookies;
|
||||||
|
using QNetworkCookieJar::setAllCookies;
|
||||||
|
|
||||||
#ifndef QBT_USES_QT5
|
#ifndef QBT_USES_QT5
|
||||||
virtual bool deleteCookie(const QNetworkCookie &cookie)
|
virtual bool deleteCookie(const QNetworkCookie &cookie)
|
||||||
{
|
{
|
||||||
|
@ -188,6 +192,16 @@ bool DownloadManager::setCookiesFromUrl(const QList<QNetworkCookie> &cookieList,
|
||||||
return m_networkManager.cookieJar()->setCookiesFromUrl(cookieList, url);
|
return m_networkManager.cookieJar()->setCookiesFromUrl(cookieList, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<QNetworkCookie> DownloadManager::allCookies() const
|
||||||
|
{
|
||||||
|
return static_cast<NetworkCookieJar *>(m_networkManager.cookieJar())->allCookies();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DownloadManager::setAllCookies(const QList<QNetworkCookie> &cookieList)
|
||||||
|
{
|
||||||
|
static_cast<NetworkCookieJar *>(m_networkManager.cookieJar())->setAllCookies(cookieList);
|
||||||
|
}
|
||||||
|
|
||||||
bool DownloadManager::deleteCookie(const QNetworkCookie &cookie)
|
bool DownloadManager::deleteCookie(const QNetworkCookie &cookie)
|
||||||
{
|
{
|
||||||
return static_cast<NetworkCookieJar *>(m_networkManager.cookieJar())->deleteCookie(cookie);
|
return static_cast<NetworkCookieJar *>(m_networkManager.cookieJar())->deleteCookie(cookie);
|
||||||
|
@ -195,16 +209,16 @@ bool DownloadManager::deleteCookie(const QNetworkCookie &cookie)
|
||||||
|
|
||||||
void DownloadManager::applyProxySettings()
|
void DownloadManager::applyProxySettings()
|
||||||
{
|
{
|
||||||
|
auto proxyManager = ProxyConfigurationManager::instance();
|
||||||
|
ProxyConfiguration proxyConfig = proxyManager->proxyConfiguration();
|
||||||
QNetworkProxy proxy;
|
QNetworkProxy proxy;
|
||||||
const Preferences* const pref = Preferences::instance();
|
|
||||||
|
|
||||||
if (pref->isProxyEnabled() && !pref->isProxyOnlyForTorrents()) {
|
if (!proxyManager->isProxyOnlyForTorrents() && (proxyConfig.type != ProxyType::None)) {
|
||||||
// Proxy enabled
|
// Proxy enabled
|
||||||
proxy.setHostName(pref->getProxyIp());
|
proxy.setHostName(proxyConfig.ip);
|
||||||
proxy.setPort(pref->getProxyPort());
|
proxy.setPort(proxyConfig.port);
|
||||||
// Default proxy type is HTTP, we must change if it is SOCKS5
|
// Default proxy type is HTTP, we must change if it is SOCKS5
|
||||||
const int proxyType = pref->getProxyType();
|
if ((proxyConfig.type == ProxyType::SOCKS5) || (proxyConfig.type == ProxyType::SOCKS5_PW)) {
|
||||||
if ((proxyType == Proxy::SOCKS5) || (proxyType == Proxy::SOCKS5_PW)) {
|
|
||||||
qDebug() << Q_FUNC_INFO << "using SOCKS proxy";
|
qDebug() << Q_FUNC_INFO << "using SOCKS proxy";
|
||||||
proxy.setType(QNetworkProxy::Socks5Proxy);
|
proxy.setType(QNetworkProxy::Socks5Proxy);
|
||||||
}
|
}
|
||||||
|
@ -213,10 +227,10 @@ void DownloadManager::applyProxySettings()
|
||||||
proxy.setType(QNetworkProxy::HttpProxy);
|
proxy.setType(QNetworkProxy::HttpProxy);
|
||||||
}
|
}
|
||||||
// Authentication?
|
// Authentication?
|
||||||
if (pref->isProxyAuthEnabled()) {
|
if (proxyManager->isAuthenticationRequired()) {
|
||||||
qDebug("Proxy requires authentication, authenticating");
|
qDebug("Proxy requires authentication, authenticating");
|
||||||
proxy.setUser(pref->getProxyUsername());
|
proxy.setUser(proxyConfig.username);
|
||||||
proxy.setPassword(pref->getProxyPassword());
|
proxy.setPassword(proxyConfig.password);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -54,6 +54,8 @@ namespace Net
|
||||||
DownloadHandler *downloadUrl(const QString &url, bool saveToFile = false, qint64 limit = 0, bool handleRedirectToMagnet = false, const QString &userAgent = "");
|
DownloadHandler *downloadUrl(const QString &url, bool saveToFile = false, qint64 limit = 0, bool handleRedirectToMagnet = false, const QString &userAgent = "");
|
||||||
QList<QNetworkCookie> cookiesForUrl(const QUrl &url) const;
|
QList<QNetworkCookie> cookiesForUrl(const QUrl &url) const;
|
||||||
bool setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url);
|
bool setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url);
|
||||||
|
QList<QNetworkCookie> allCookies() const;
|
||||||
|
void setAllCookies(const QList<QNetworkCookie> &cookieList);
|
||||||
bool deleteCookie(const QNetworkCookie &cookie);
|
bool deleteCookie(const QNetworkCookie &cookie);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
|
@ -45,7 +45,6 @@
|
||||||
static const char DATABASE_URL[] = "https://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz";
|
static const char DATABASE_URL[] = "https://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz";
|
||||||
static const char GEOIP_FOLDER[] = "GeoIP";
|
static const char GEOIP_FOLDER[] = "GeoIP";
|
||||||
static const char GEOIP_FILENAME[] = "GeoLite2-Country.mmdb";
|
static const char GEOIP_FILENAME[] = "GeoLite2-Country.mmdb";
|
||||||
static const int CACHE_SIZE = 1000;
|
|
||||||
static const int UPDATE_INTERVAL = 30; // Days between database updates
|
static const int UPDATE_INTERVAL = 30; // Days between database updates
|
||||||
|
|
||||||
using namespace Net;
|
using namespace Net;
|
||||||
|
|
|
@ -26,13 +26,17 @@
|
||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "portforwarder.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
#include <libtorrent/session.hpp>
|
#include <libtorrent/session.hpp>
|
||||||
|
#include <libtorrent/version.hpp>
|
||||||
|
|
||||||
#include "base/logger.h"
|
#include "base/logger.h"
|
||||||
#include "base/preferences.h"
|
#include "base/settingsstorage.h"
|
||||||
#include "portforwarder.h"
|
|
||||||
|
static const QString KEY_ENABLED = QLatin1String("Network/PortForwardingEnabled");
|
||||||
|
|
||||||
namespace libt = libtorrent;
|
namespace libt = libtorrent;
|
||||||
using namespace Net;
|
using namespace Net;
|
||||||
|
@ -42,8 +46,8 @@ PortForwarder::PortForwarder(libtorrent::session *provider, QObject *parent)
|
||||||
, m_active(false)
|
, m_active(false)
|
||||||
, m_provider(provider)
|
, m_provider(provider)
|
||||||
{
|
{
|
||||||
configure();
|
if (SettingsStorage::instance()->loadValue(KEY_ENABLED, true).toBool())
|
||||||
connect(Preferences::instance(), SIGNAL(changed()), SLOT(configure()));
|
start();
|
||||||
}
|
}
|
||||||
|
|
||||||
PortForwarder::~PortForwarder()
|
PortForwarder::~PortForwarder()
|
||||||
|
@ -70,7 +74,24 @@ PortForwarder *PortForwarder::instance()
|
||||||
return m_instance;
|
return m_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PortForwarder::addPort(qint16 port)
|
bool PortForwarder::isEnabled() const
|
||||||
|
{
|
||||||
|
return m_active;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PortForwarder::setEnabled(bool enabled)
|
||||||
|
{
|
||||||
|
if (m_active != enabled) {
|
||||||
|
if (enabled)
|
||||||
|
start();
|
||||||
|
else
|
||||||
|
stop();
|
||||||
|
|
||||||
|
SettingsStorage::instance()->storeValue(KEY_ENABLED, enabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PortForwarder::addPort(quint16 port)
|
||||||
{
|
{
|
||||||
if (!m_mappedPorts.contains(port)) {
|
if (!m_mappedPorts.contains(port)) {
|
||||||
m_mappedPorts.insert(port, 0);
|
m_mappedPorts.insert(port, 0);
|
||||||
|
@ -79,7 +100,7 @@ void PortForwarder::addPort(qint16 port)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PortForwarder::deletePort(qint16 port)
|
void PortForwarder::deletePort(quint16 port)
|
||||||
{
|
{
|
||||||
if (m_mappedPorts.contains(port)) {
|
if (m_mappedPorts.contains(port)) {
|
||||||
if (m_active)
|
if (m_active)
|
||||||
|
@ -88,23 +109,19 @@ void PortForwarder::deletePort(qint16 port)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PortForwarder::configure()
|
|
||||||
{
|
|
||||||
bool enable = Preferences::instance()->isUPnPEnabled();
|
|
||||||
if (m_active != enable) {
|
|
||||||
if (enable)
|
|
||||||
start();
|
|
||||||
else
|
|
||||||
stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PortForwarder::start()
|
void PortForwarder::start()
|
||||||
{
|
{
|
||||||
qDebug("Enabling UPnP / NAT-PMP");
|
qDebug("Enabling UPnP / NAT-PMP");
|
||||||
|
#if LIBTORRENT_VERSION_NUM < 10100
|
||||||
m_provider->start_upnp();
|
m_provider->start_upnp();
|
||||||
m_provider->start_natpmp();
|
m_provider->start_natpmp();
|
||||||
foreach (qint16 port, m_mappedPorts.keys())
|
#else
|
||||||
|
libt::settings_pack settingsPack = m_provider->get_settings();
|
||||||
|
settingsPack.set_bool(libt::settings_pack::enable_upnp, true);
|
||||||
|
settingsPack.set_bool(libt::settings_pack::enable_natpmp, true);
|
||||||
|
m_provider->apply_settings(settingsPack);
|
||||||
|
#endif
|
||||||
|
foreach (quint16 port, m_mappedPorts.keys())
|
||||||
m_mappedPorts[port] = m_provider->add_port_mapping(libt::session::tcp, port, port);
|
m_mappedPorts[port] = m_provider->add_port_mapping(libt::session::tcp, port, port);
|
||||||
m_active = true;
|
m_active = true;
|
||||||
Logger::instance()->addMessage(tr("UPnP / NAT-PMP support [ON]"), Log::INFO);
|
Logger::instance()->addMessage(tr("UPnP / NAT-PMP support [ON]"), Log::INFO);
|
||||||
|
@ -113,8 +130,15 @@ void PortForwarder::start()
|
||||||
void PortForwarder::stop()
|
void PortForwarder::stop()
|
||||||
{
|
{
|
||||||
qDebug("Disabling UPnP / NAT-PMP");
|
qDebug("Disabling UPnP / NAT-PMP");
|
||||||
|
#if LIBTORRENT_VERSION_NUM < 10100
|
||||||
m_provider->stop_upnp();
|
m_provider->stop_upnp();
|
||||||
m_provider->stop_natpmp();
|
m_provider->stop_natpmp();
|
||||||
|
#else
|
||||||
|
libt::settings_pack settingsPack = m_provider->get_settings();
|
||||||
|
settingsPack.set_bool(libt::settings_pack::enable_upnp, false);
|
||||||
|
settingsPack.set_bool(libt::settings_pack::enable_natpmp, false);
|
||||||
|
m_provider->apply_settings(settingsPack);
|
||||||
|
#endif
|
||||||
m_active = false;
|
m_active = false;
|
||||||
Logger::instance()->addMessage(tr("UPnP / NAT-PMP support [OFF]"), Log::INFO);
|
Logger::instance()->addMessage(tr("UPnP / NAT-PMP support [OFF]"), Log::INFO);
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,11 +49,11 @@ namespace Net
|
||||||
static void freeInstance();
|
static void freeInstance();
|
||||||
static PortForwarder *instance();
|
static PortForwarder *instance();
|
||||||
|
|
||||||
void addPort(qint16 port);
|
bool isEnabled() const;
|
||||||
void deletePort(qint16 port);
|
void setEnabled(bool enabled);
|
||||||
|
|
||||||
private slots:
|
void addPort(quint16 port);
|
||||||
void configure();
|
void deletePort(quint16 port);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit PortForwarder(libtorrent::session *const provider, QObject *parent = 0);
|
explicit PortForwarder(libtorrent::session *const provider, QObject *parent = 0);
|
||||||
|
@ -64,7 +64,7 @@ namespace Net
|
||||||
|
|
||||||
bool m_active;
|
bool m_active;
|
||||||
libtorrent::session *m_provider;
|
libtorrent::session *m_provider;
|
||||||
QHash<qint16, int> m_mappedPorts;
|
QHash<quint16, int> m_mappedPorts;
|
||||||
|
|
||||||
static PortForwarder *m_instance;
|
static PortForwarder *m_instance;
|
||||||
};
|
};
|
||||||
|
|
|
@ -40,7 +40,7 @@ namespace
|
||||||
{
|
{
|
||||||
const quint32 __ENDIAN_TEST__ = 0x00000001;
|
const quint32 __ENDIAN_TEST__ = 0x00000001;
|
||||||
const bool __IS_LITTLE_ENDIAN__ = (reinterpret_cast<const uchar *>(&__ENDIAN_TEST__)[0] == 0x01);
|
const bool __IS_LITTLE_ENDIAN__ = (reinterpret_cast<const uchar *>(&__ENDIAN_TEST__)[0] == 0x01);
|
||||||
const int MAX_FILE_SIZE = 10485760; // 10MB
|
const qint32 MAX_FILE_SIZE = 67108864; // 64MB
|
||||||
const char DB_TYPE[] = "GeoLite2-Country";
|
const char DB_TYPE[] = "GeoLite2-Country";
|
||||||
const quint32 MAX_METADATA_SIZE = 131072; // 128KB
|
const quint32 MAX_METADATA_SIZE = 131072; // 128KB
|
||||||
const char METADATA_BEGIN_MARK[] = "\xab\xcd\xefMaxMind.com";
|
const char METADATA_BEGIN_MARK[] = "\xab\xcd\xefMaxMind.com";
|
||||||
|
|
163
src/base/net/proxyconfigurationmanager.cpp
Normal file
163
src/base/net/proxyconfigurationmanager.cpp
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
/*
|
||||||
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
|
* Copyright (C) 2016 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the copyright holders give permission to
|
||||||
|
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
||||||
|
* modified versions of it that use the same license as the "OpenSSL" library),
|
||||||
|
* and distribute the linked executables. You must obey the GNU General Public
|
||||||
|
* License in all respects for all of the code used other than "OpenSSL". If you
|
||||||
|
* modify file(s), you may extend this exception to your version of the file(s),
|
||||||
|
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||||
|
* exception statement from your version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "proxyconfigurationmanager.h"
|
||||||
|
#include "base/settingsstorage.h"
|
||||||
|
|
||||||
|
#define SETTINGS_KEY(name) "Network/Proxy/" name
|
||||||
|
const QString KEY_ONLY_FOR_TORRENTS = SETTINGS_KEY("OnlyForTorrents");
|
||||||
|
const QString KEY_TYPE = SETTINGS_KEY("Type");
|
||||||
|
const QString KEY_IP = SETTINGS_KEY("IP");
|
||||||
|
const QString KEY_PORT = SETTINGS_KEY("Port");
|
||||||
|
const QString KEY_USERNAME = SETTINGS_KEY("Username");
|
||||||
|
const QString KEY_PASSWORD = SETTINGS_KEY("Password");
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
inline SettingsStorage *settings() { return SettingsStorage::instance(); }
|
||||||
|
|
||||||
|
inline bool isSameConfig(const Net::ProxyConfiguration &conf1, const Net::ProxyConfiguration &conf2)
|
||||||
|
{
|
||||||
|
return conf1.type == conf2.type
|
||||||
|
&& conf1.ip == conf2.ip
|
||||||
|
&& conf1.port == conf2.port
|
||||||
|
&& conf1.username == conf2.username
|
||||||
|
&& conf1.password == conf2.password;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace Net;
|
||||||
|
|
||||||
|
ProxyConfigurationManager *ProxyConfigurationManager::m_instance = nullptr;
|
||||||
|
|
||||||
|
ProxyConfigurationManager::ProxyConfigurationManager(QObject *parent)
|
||||||
|
: QObject(parent)
|
||||||
|
{
|
||||||
|
m_isProxyOnlyForTorrents = settings()->loadValue(KEY_ONLY_FOR_TORRENTS, false).toBool();
|
||||||
|
m_config.type = static_cast<ProxyType>(
|
||||||
|
settings()->loadValue(KEY_TYPE, static_cast<int>(ProxyType::None)).toInt());
|
||||||
|
if ((m_config.type < ProxyType::None) || (m_config.type > ProxyType::SOCKS4))
|
||||||
|
m_config.type = ProxyType::None;
|
||||||
|
m_config.ip = settings()->loadValue(KEY_IP, "0.0.0.0").toString();
|
||||||
|
m_config.port = static_cast<ushort>(settings()->loadValue(KEY_PORT, 8080).toUInt());
|
||||||
|
m_config.username = settings()->loadValue(KEY_USERNAME).toString();
|
||||||
|
m_config.password = settings()->loadValue(KEY_PASSWORD).toString();
|
||||||
|
configureProxy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProxyConfigurationManager::initInstance()
|
||||||
|
{
|
||||||
|
if (!m_instance)
|
||||||
|
m_instance = new ProxyConfigurationManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProxyConfigurationManager::freeInstance()
|
||||||
|
{
|
||||||
|
if (m_instance) {
|
||||||
|
delete m_instance;
|
||||||
|
m_instance = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ProxyConfigurationManager *ProxyConfigurationManager::instance()
|
||||||
|
{
|
||||||
|
return m_instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProxyConfiguration ProxyConfigurationManager::proxyConfiguration() const
|
||||||
|
{
|
||||||
|
return m_config;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProxyConfigurationManager::setProxyConfiguration(const ProxyConfiguration &config)
|
||||||
|
{
|
||||||
|
if (!isSameConfig(config, m_config)) {
|
||||||
|
m_config = config;
|
||||||
|
settings()->storeValue(KEY_TYPE, static_cast<int>(config.type));
|
||||||
|
settings()->storeValue(KEY_IP, config.ip);
|
||||||
|
settings()->storeValue(KEY_PORT, config.port);
|
||||||
|
settings()->storeValue(KEY_USERNAME, config.username);
|
||||||
|
settings()->storeValue(KEY_PASSWORD, config.password);
|
||||||
|
configureProxy();
|
||||||
|
|
||||||
|
emit proxyConfigurationChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ProxyConfigurationManager::isProxyOnlyForTorrents() const
|
||||||
|
{
|
||||||
|
return m_isProxyOnlyForTorrents || (m_config.type == ProxyType::SOCKS4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProxyConfigurationManager::setProxyOnlyForTorrents(bool onlyForTorrents)
|
||||||
|
{
|
||||||
|
if (m_isProxyOnlyForTorrents != onlyForTorrents) {
|
||||||
|
settings()->storeValue(KEY_ONLY_FOR_TORRENTS, onlyForTorrents);
|
||||||
|
m_isProxyOnlyForTorrents = onlyForTorrents;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ProxyConfigurationManager::isAuthenticationRequired() const
|
||||||
|
{
|
||||||
|
return m_config.type == ProxyType::SOCKS5_PW
|
||||||
|
|| m_config.type == ProxyType::HTTP_PW;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProxyConfigurationManager::configureProxy()
|
||||||
|
{
|
||||||
|
// Define environment variables for urllib in search engine plugins
|
||||||
|
QString proxyStrHTTP, proxyStrSOCK;
|
||||||
|
if (!m_isProxyOnlyForTorrents) {
|
||||||
|
switch (m_config.type) {
|
||||||
|
case ProxyType::HTTP_PW:
|
||||||
|
proxyStrHTTP = QString("http://%1:%2@%3:%4").arg(m_config.username)
|
||||||
|
.arg(m_config.password).arg(m_config.ip).arg(m_config.port);
|
||||||
|
break;
|
||||||
|
case ProxyType::HTTP:
|
||||||
|
proxyStrHTTP = QString("http://%1:%2").arg(m_config.ip).arg(m_config.port);
|
||||||
|
break;
|
||||||
|
case ProxyType::SOCKS5:
|
||||||
|
proxyStrSOCK = QString("%1:%2").arg(m_config.ip).arg(m_config.port);
|
||||||
|
break;
|
||||||
|
case ProxyType::SOCKS5_PW:
|
||||||
|
proxyStrSOCK = QString("%1:%2@%3:%4").arg(m_config.username)
|
||||||
|
.arg(m_config.password).arg(m_config.ip).arg(m_config.port);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
qDebug("Disabling HTTP communications proxy");
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug("HTTP communications proxy string: %s"
|
||||||
|
, qPrintable((m_config.type == ProxyType::SOCKS5) || (m_config.type == ProxyType::SOCKS5_PW)
|
||||||
|
? proxyStrSOCK : proxyStrHTTP));
|
||||||
|
}
|
||||||
|
|
||||||
|
qputenv("http_proxy", proxyStrHTTP.toLocal8Bit());
|
||||||
|
qputenv("https_proxy", proxyStrHTTP.toLocal8Bit());
|
||||||
|
qputenv("sock_proxy", proxyStrSOCK.toLocal8Bit());
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue