Magnets with trackers specified with tr.x param were not being unquoted
so unusable raw tracker string was being set.
Fixed by unquoting tracker and adding test
See-also: https://dev.deluge-torrent.org/ticket/2716
The changes to remove deprecated lt methods didn't account for magnet
trackers so magnets are missing trackers when added.
Previously the addition of trackers was handled by libtorrent when a url
was passed in add_torrent_params. The url parameter is deprecated so
instead we need to add both the info_hash and trackers.
Trac: https://dev.deluge-torrent.org/ticket/3530
A recent dependency change caused the tests running on GitHub Actions
under Python 3.10.5 on Windows to fail when starting pytest run:
...
INTERNALERROR> File "<frozen importlib._bootstrap>", line 123, in acquire
INTERNALERROR> KeyError: xxxx
The cause seems to have been a newer version of chardet package released
recently.
* Fixed by pinning chardet to v4
* Also pin Windows version to 2019 to match packaging workflow
See-also: https://github.com/deluge-torrent/deluge/actions/runs/2578427588
Issue: https://github.com/chardet/chardet/issues/265
Fix rendering issues in ReadTheDocs by specifying latest version of
sphinx-rtd-theme. Normally not an issue to install this latest
dependency from doc/requirement.txt but RTD installs in the env an older
version (<0.5) before running requirements file install
thus sphinx-rtd-theme is not upgraded unless a version is specified.
See-also: https://github.com/readthedocs/sphinx_rtd_theme/issues/1115
Pin Pyinstaller to latest v4.x until issue of aborting upon missing typelibs for various unbuilt gst-modules can be properly investigated and resolved. Specific error for one of the modules being:
`36738 INFO: Loading module hook 'hook-gi.repository.Gst.py' from 'C:\\hostedtoolcache\\windows\\Python\\3.9.13\\x64\\lib\\site-packages\\PyInstaller\\hooks'...
Traceback (most recent call last):
File "<string>", line 7, in <module>
gi.repository.GLib.GError: g-irepository-error-quark: Typelib file for namespace 'Gst', version '1.0' not found (0)
36870 ERROR: gi repository 'GIRepository 2.0' not found. Please make sure corresponding package is installed.
Traceback (most recent call last):
File "<string>", line 4, in <module>
File "C:\hostedtoolcache\windows\Python\3.9.13\x64\lib\site-packages\gi\__init__.py", line 139, in require_version
raise ValueError('Namespace %s not available' % namespace)
ValueError: Namespace Gst not available`
Added `--no-index` to ensure pip doesn't install from Pypi
Closes: https://github.com/deluge-torrent/deluge/pull/386
smtplib.SMTP.sendmail expects 'msg' in string of ascii chars or bytes,
where the former gets encoded to bytes through ascii codec, hence
raising said error, but now fixed by encoding to bytes ourself through
utf-8
Closes: https://github.com/deluge-torrent/deluge/pull/383
Just trying to clean up some of the more complicated callback logic.
Notable changes:
* The test was awaiting a DeferredList. By default that will eat
exceptions and just add them to the result list (including test
assertion exceptions.) Added fireOnOneErrback=True to make sure that
wasn't happening. * Moved the logic for multiple calls to await the
same response into torrentmanager from core, so no matter where the
prefetch is called from it will wait for the original call.
* Implemented the multiple calls with an explicit queue of waiting
callbacks, rather than a callback callback chain. * Moved to one inline
async function rather than split into a main and callback after alert
function.
* Added some more type hints to the stuff I changed.
Adjusted test since we are using prefetch as an async function now
we have to schedule the alert to come after we start awaiting the
prefetch call.
Closes: https://github.com/deluge-torrent/deluge/pull/368
Temporary torrent files are not deleted by add_torrent_url. Not as big a
problem as with tracker icons pages but should be removed after use.
Fixed by updating the method to use async and a try..finally cleanup
block.
Perhaps could be refactored to not require temporary files and instead
store the downloaded torrent as object for passing to add_torrent_file.
Trac: https://dev.deluge-torrent.org/ticket/3167
Temporary files created while download host html page are no cleaned up
if the download fails.
Fixed by adding a 'finally' step in the callback chain to delete any
created temporary files.
Added tests to ensure the temporary files are deleted, using a fixture
that creates a known filename for the test.
Trac: https://dev.deluge-torrent.org/ticket/3167
GitHub CI tests on Windows failing for get_windows_interface_name so
remove the fragile tests since not a requirement to be this specific
with testing whether name exists for these methods relying on standard
lib or 3rd-party libs.
When several torrents are being removed from session, an exception was
being raised in a callback function `on_status` with the `torrent_id` of
one (or more) of the removed torrents.
Now we will catch when the torrent does not exist anymore and print a
debug log about it.
Closes: https://dev.deluge-torrent.org/ticket/3498
Closes: https://github.com/deluge-torrent/deluge/pull/341
Up until now, the linux installation source of libtorrent was launchpad,
because there was no other source, and we wanted a debug version of lt.
With pypi wheel versions now available use lt in the requirements.txt
file.
Closes: https://github.com/deluge-torrent/deluge/pull/364
We cannot add python 3.6 because there is no precompiled version of it to used.
Therefor, will be using 3.7 as the minimum version in CI.
In addition, dropped version limits from pytest.
The SNI icon test is failing due to seo.com removing their favicon.
A new test to replace it would be needed to check SNI support. Ideally
new tests would not rely on external sites.
This propery cause issue with added extra space in the entries, likely a
minor GTK bug and property being leftover from GTK2 migration. The
default is True and should have no effect since no icon is shown.
A visual problem with the port spin button meant that the port number
was not fully visible in the entry field.
The problem is related to icon activatable property value set to False
when default is True. Although no icon is used is creates a left-hand
5px space in the entry which narrows the available text space and the
entry does not expand to account for this.
Fixed by removing primary_icon_activatable and
secondary_icon_activatable properies so that default values of True is
used.
Files should be installed into /usr/lib/systemd/user/
Unlike the existing service file, this one configures deluge to run as a
desktop session user. The difference between the services files is the
use of multi-user.target in system service which does not exist for user
services so requires default.target.
Including the Slice indicates to the service manager that this is a
background service. This can be used to handle OOM situations, or
prioritising foreground processes. There's no equivalent for system
services.
Refs: https://dev.deluge-torrent.org/ticket/2034
Closes: https://github.com/deluge-torrent/deluge/pull/380
The torrent status num_peers and num_seeds was replaced for session
status keys by accident as part of replacing deprecated session keys
so revert those changes
Ref: 2bd095e5bf
Users with older versions of Twisted <= 21.2 were encoutering the
following error:
File "/home/calum/projects/deluge/deluge/decorators.py", line 191, in activate
d = defer.Deferred.fromCoroutine(self.coro)
builtins.AttributeError: type object 'Deferred' has no attribute 'fromCoroutine'
Fixed by falling back to ensureDeferred since fromCoroutine was
introduced in Twisted 21.2 as a saner name for handling of coroutines.
Ref: https://twistedmatrix.com/trac/ticket/9825
If a libtorrent return type was specified e.g.
def get_lt_status(self) -> 'lt.torrent_status'
Even as a string autodoc_typehints module would raise and error:
Handler <function process_docstring at 0x7f6c16c8ec10> for event 'autodoc-process-docstring' threw an exception (exception: getattr(): attribute name must be string)
This was a result of using a custom mock in Sphinx autodoc config and
this Mock object name or qualname returns an object instead of str.
Testing with putting modules in autodoc_mock_imports again showed no
issues so removing custom mock
Ref: https://github.com/tox-dev/sphinx-autodoc-typehints/issues/220
We should not be mangling the torrent data in the JSON API since this
can have unintended consquences with names and filepaths that can be
edited. If we escape those symbols in the JSON API then the data no
longer matches that stored by core. Therefore shift the encoding to the
client and consider dealing separetely with these entities when the user
first adds a torrent.
* Created a modified htmlEncode in Deluge Formatter based on extjs
method that also encodes single quotes.
* Removed renderers in ListViews since only templates specified via tpl
are used and any render attribute specified was a no-op.
* Removed old buggy escapeHtml
Resolves: https://dev.deluge-torrent.org/ticket/3459
Ref: https://docs.sencha.com/extjs/6.5.3/modern/src/String.js.html#Ext.String-method-htmlEncode
Ref: https://docs.sencha.com/extjs/3.4.0/source/Format.html#Ext-util-Format-method-htmlEncode
Ensure all torrent attributes that might contain malicious HTML entities
are encoded.
By allowing HTML entities to be rendered it enable malicious torrent
files to perform XSS attacks.
Resolves: https://dev.deluge-torrent.org/ticket/3459
Could not see more than one host when connection manager opens so need to
scroll or resize window
Increased default height to now show three hosts when first opens
Closes: https://dev.deluge-torrent.org/ticket/3431
if move_completed is checked/True, options should be updated, not the
other way round
The path was updated the first time the move_completed option is selected
and then ignored on further updated to the path.
Fixed by checking instead if the path has changed.
Closes: https://github.com/deluge-torrent/deluge/pull/374
Notable changes:
* Prettier >=2.3 with more consistent js assignments
* Black now formats docstrings
* Added isort to list of autoformaters
* Update flake8 config for v4
Ref: https://prettier.io/blog/2021/05/09/2.3.0.html
As part of the process of adding support to LT 2.0, we should stop using
all deprecated function, as some (if not all) were removed.
For this process, we should use the LT 1.2 upgrade (guide)[1].
The change includes:
* stop using file entries directly
* start using the torrent handle's set/unset flags
* stop using url key in add_torrent_params (for magnet)
* stop accessing resume_data from save_resume_data_alert
* stop using deprecated session status keys in UI
[1] https://libtorrent.org/upgrade_to_1.2-ref.html
Closes: https://dev.deluge-torrent.org/ticket/3499
Closes: https://github.com/deluge-torrent/deluge/pull/342
Errors were raised when trying to add a new daemon account due to dialog
being destroyed before looking up widget values.
Fixed by saving widget values before destroying.
Refactored code to be simplified with a named tuple for the account
details instead of separate attributes and modernized the preferences
dialog creation and account saving by replacing callback functions.
The tests in connectionmanager for when a host is online are broken
and always considers a host as online.
When an error occurs in e.g. in _on_connect_fail, report_message()
in PopupsHandler expects the message to be string, not a Twisted Failure.
Fix by checking if message is string and log a warning before converting
to string.
Closes: https://github.com/deluge-torrent/deluge/pull/277
Currently, when creating a new plugin, a script for creating
the dev links was created for *NIX systems only.
Now, it will detect the system type and create the correct
script:
Windows: create_dev_links.bat
*NIX: create_dev_links.sh
Closes: https://github.com/deluge-torrent/deluge/pull/257
In a6840296, a refactor to the `config` class was introduced.
The change included an internal wrapper for `reactor.callLater`, for lazy
import, but didn't wrap it correctly and therefor, no args/kwargs were
passed to the wrapped method.
Furthermore, the exception was silently ignored.
This caused changes to be ignored and not applied, including
`preferencesmanager._on_config_value_change` callback.
Closes: https://github.com/deluge-torrent/deluge/pull/372
Our file priority test was using time.sleep to wait until libtorrent
had processed the command. This was sometimes not long enough and the
test would fail. On libtorrent 2.0.3+ there is an alert when the
process has finished, switch to waiting for that in this test to make
the test more consistent. On older libtorrent, make the delay a bit
longer, to try to make the test more consistent there as well.
Closes: https://github.com/deluge-torrent/deluge/pull/373
Standardize docstrings in core.py to google standard.
Remove type hints in docstrings in favor of the ones in method signatures.
Use function signature type hints in autodoc generated docs.
Change Deferred type hints to strings.
Older versions of twisted (<21.7) don't
support generic Deferred type hinting,
this prevents crashes on those versions.
Closes: https://github.com/deluge-torrent/deluge/pull/359
Not all dependencies were installed due to adding a comment in the
middle of the pip install command
Also need to specify Twisted extras to match requirement.txt
A problem with GdkPixbuf loaders on Windows causes a hard crash when
attempting to load ico or gif tracker icons.
Added a workaround by skipping these icon types until a more permanent
solution is found.
Ref: https://dev.deluge-torrent.org/ticket/3501
Fixed a mistake settings entry points in setup.py. Replaced with simpler
logic since gui_scripts only affect Windows.
Fixed entry point changes affecting pyinstaller build
Corrected deluge-web.exe to have no console instead of
deluge-web-debug.exe
Make logging functions synchronous.
They were not calling any async functions, and wrapping them in
maybe_coroutine caused reactor to be imported before gtkui could
install the gtk reactor.
Closes: https://github.com/deluge-torrent/deluge/pull/353
- Clean up callback hell by making more code inline
- Use async/await syntax as it has more modern niceties than inlineCallbacks
- Also gets us closer if we want to transition to asyncio in the future
- `await` is usable in places that `yield` is not. e.g. `return await thething` `func(await thething, 'otherparam')`
- IDEs know async semantics of async/await syntax to help more than with `inlineCallbacks`
- `maybe_coroutine` decorator has nice property (over `ensureDeferred`) that when used in a chain of other coroutines, they won't be wrapped in deferreds on each level, and so traceback will show each `await` call leading to the error.
- All async functions wrapped in `maybe_coroutine` are 100% backwards compatible with a regular Deferred returning function. Whether called from a coroutine or not.
- Use Deferred type hints as strings since older versions of twisted
(<21.7) don't support generic Deferred type hinting.
Added a new Config class parameter `log_mask_funcs` to enable config
instances hide sensitive information that would normally appear in
config debug logs.
Added mask password function to hostlist to replace passwords with '*'s
in logs.
Closes: https://github.com/deluge-torrent/deluge/pull/363
Typing is broken with older versions of Twisted e.g. with v21.2
deluge/deluge/core/core.py", line 404, in Core
) -> defer.Deferred[str]:
TypeError: 'type' object is not subscriptable
Also it might not be compatible with Python 3.6 or 3.7 with use of
certain types such as dict rather than Dict
This reverts commit 4096cdfdfe4fc7e42746cedd868bd7d8fea99f23.
Ref: https://twistedmatrix.com/trac/ticket/9816
Standardize docstrings in core.py to google standard.
Remove type hints in docstrings in favor of the ones in method signatures.
Use function signature type hints in autodoc generated docs.
Closes: https://github.com/deluge-torrent/deluge/pull/359
* Refactored duplication with setting config key and logging
* Simplified lazy importing reactor for callLater. This lazy importing
is required for testing and also prevents Gtk UI lockup if reactor
imported in Config.
* Fixed saving config to file when setting a key that doesn't exist yet.
This was due to returning early in the set_item method.
* Added a `default` arg to set_item to prevent saving to file when only
setting a default value for a key in init.
* Moved casting value to existing key type from set_item to dedicated
function.
Have the log dir be a protected windows folder and Deluge crashes.
Windows blocks access to the dir and so it fails. It will fail trying to write
to any protected folder. Should probably just pass on the error maybe
and maybe log to stdout and log a message saying access was blocked or
something.
.\deluge-debug -L debug -l E:\Documents\deluge.log
...
Failed to execute script 'deluge-debug-script' due to unhandled exception!
Closes: https://dev.deluge-torrent.org/ticket/3502
Closes: https://github.com/deluge-torrent/deluge/pull/358
Fixed crash when sys.stdout was None
When using pythonw on windows, sys.stdout and stdin are None. We had a
legacy unicode_argv handler that was crashing in this instance. Just
removed that, since sys.argv is always unicode on python 3 to fix the
crash.
Closes: https://github.com/deluge-torrent/deluge/pull/361
Convert all the twisted.trial tests to pytest_twisted. Also move off of unittest.TestCase as well. Seems there were several tests which weren't actually testing what they should, and also some code that wasn't doing what the broken test said it should.
Goals:
Remove twisted.trial tests
Move to pytest fixtures, rather than many classess and subclasses with setup and teardown functions
Move away from self.assertX to assert style tests
FIx broken tests
Going forward I think these should be the goals when adding/modifying tests:
* Don't use BaseTest or set_up tear_down methods any more. Fixtures should be used either in the test module/class, or make/improve the ones available in conftest.py
* For sure don't use unittest or twisted.trial, they mess up the pytest stuff.
* Prefer pytest_twisted.ensureDeferred with an async function over inlineCallbacks.
- I think the async function syntax is nicer, and it helps catch silly mistakes, e.g. await None is invalid, but yield None isn't, so if some function returns an unexpected thing we try to await on, it will be caught earlier. (I struggled debugging a test for quite a while, then caught it immediately when switching to the new syntax)
- Once the maybe_coroutine PR goes in, using the async syntax can also improve tracebacks when debugging tests.
Things that should probably be cleaned up going forward:
* Remove BaseTestCase
* Remove the subclasses like DaemonBase in favor of new fixtures.
* I think there are some other utility subclasses that could be removed too
* Perhaps use parameterization in the ui_entry tests, rather that the weird combination of subclasses and the set_var fixture I mixed in.
* Convert some of the callback stuff to pytest_twisted.ensureDeferred tests, just for nicer readability
Details relating to pytest fixtures conftest.py in root dir:
* https://github.com/pytest-dev/pytest/issues/5822#issuecomment-697331920
* https://docs.pytest.org/en/latest/deprecations.html#pytest-plugins-in-non-top-level-conftest-files
Closes: https://github.com/deluge-torrent/deluge/pull/354
Up until now, when closing the Add or Edit dialogs, of the `Edit Torrents`, using the top-right X
button or using the Escape key, they were being destroyed without any way to reopening them, and
it was breaking the `Edit Torrents` window itself.
Now both dialogs have the right handlers for handing the closing process without breaking anything.
Closes: deluge-torrent/deluge#324
Closes: https://dev.deluge-torrent.org/ticket/2434
Libtorrent now supports interface names instead of just IP address so
add new common functions to validate user input.
* Added is_interface that will verify if a libtorrent interface of name
or IP address.
* Added is_interface_name to verify that the name supplied is a valid
network interface name in the operating system.
On Windows sock.if_nameindex() is only supported on 3.8+ and does not
return a uuid (required by libtorrent) so use ifaddr package. Using git
commit version for ifaddr due to adapter name decode bug in v0.1.7.
On other OSes attempt to use stdlib and fallback to ifaddr if installed
otherwiser return True.
* Added tests for is_interface & is_interface_name
* Updated UIs with change from address to interface
* Updated is_ipv6 and is_ipv4 to used inet_pton; now supported on
Windows.
Ref: https://github.com/pydron/ifaddr/pull/32
Closes: https://github.com/deluge-torrent/deluge/pull/338
We should not let anyone know the account's password length,
as it can help to crack it.
Instead, we will print a constant amount (10) of asterisks.
Closes: https://github.com/deluge-torrent/deluge/pull/346
This makes the process of editing the file much more pleasant and
removes duplicate code.
Fixed collecting twisted package which brings both build speed
improvements but also decreases package size, as it stops PyInstaller
from bundling tests (actually, some tests might even execute during
import and break build if they're designed to throw!) used by
PyInstaller
Closes: https://github.com/deluge-torrent/deluge/pull/342
CirnoT reported how they felt that GTK3 is not reliable on Windows.
Seeing some weird issues where clicking Deluge icon on taskbar does
bring window to front but doing so again does not minimize it as one
would expect. By using GTK_CSD=0 this would reduce these problems.
> If changed to 0, this disables the default use of client-side
decorations on GTK windows, thus making the window manager responsible
for drawing the decorations of windows that do not have a custom
titlebar widget.
This can be overridden by a global env var.
Ref: https://github.com/deluge-torrent/deluge/pull/331#issuecomment-1012311605
Ref: https://docs.gtk.org/gtk3/running.html
this will lined-up with the WebUI, which already have this option.
in addition, it will not open the Add Torrent URL dialog after copied,
which happens automatically when there is torrent/magnet URIs in the clipboard.
Closes: deluge-torrent/deluge#328
Closes: https://dev.deluge-torrent.org/ticket/3489
Include arch in artifacts so they can be downloaded separately
Added libtorrent 2.0 to matrix since users often request latest
libtorrent.
Renamed workflow to make it's purpose clearer
libtorrent + pyinstaller requires a lib(ssl/crypto)-1_1.dll and
lib(ssl/crypto)-1_1-x64.dll odd quirk but solveable by just having
two copies. Maybe later compiling our own libtorrent.
* Rename instances of win32 to generic win or the appropriate bit where applicable
* Remove files used in GTK2
* Add spec file for use with PyInstaller
* Remove Python bbfreeze Script
* Add Github Action To Build Releases
* Add Modified script to make files used by NSIS
* Update Readme
Closes: https://github.com/deluge-torrent/deluge/pull/331
A new metadata version 2.1 has optional Description that is causing an
TypeError when looking up the key in plugin_info since clients are
assuming values are always strings but the default is None.
Fixed TypeError by ensuring that the info dict has a default empty
string set for all keys.
Separated the parsing of the pkg_info into static method to make it
easier to test.
Changed the missing plugin info to only set the Name and Version as
'not available' since all other fields are optional.
Ref: https://dev.deluge-torrent.org/ticket/3476
Ref: https://packaging.python.org/en/latest/specifications/core-metadata/#description
A UnicodeDecodeError is raised in transfer module when attempting to
prefetch a magnet.
This is result of passing a Python dict containing text bytes and raw
bytes that cannot be decoded as utf-8 in rencode when recieving the
message. This could be handled in rencode by returning raw bytes if
decoding fails (perhaps with a strict mode?) however better to follow
convention of encoding raw bytes in base64 in API calls.
Fixed by retaining bencoding and encoding with base64 when sending
result.
Resolves: https://github.com/deluge-torrent/deluge/pull/334
This happened due to the removal of `exception_msg` attribute, which was
removed with the changes to `RPC` protocol in commit 9b812a4.
Now we access the message using the `message` attribute.
Closes: deluge-torrent/deluge#332
Closes: https://dev.deluge-torrent.org/ticket/3069
After downloading and resizing the new icon, we try to remove the downloaded
file, which is larger, but it fails because it tries to do so when the file
is still open, and therefor locked.
On close of the UI, we got `PermissionError` exceptions for each new icon.
When parsing the site's page in search for the FAVICON, the page gets opens.
The default file encoding in dependent on the running OS, and might not
be `UTF-8` on Windows.
Therefor, some trackers might not get their icon downloaded at all because of
an error:
`UnicodeDecodeError: 'charmap' codec can't decode byte 0x90 in position 2158: character maps to <undefined>`.
This fix adds a detection of file encoding using the optional `chardet` dependency, and also a test.
Closes: deluge-torrent/deluge#333
Closes: https://dev.deluge-torrent.org/ticket/3479
this switched was motivated by an error which happened each time the check
port button was clicked, and was caused by the GtkImage when loading the
loading.gif file on Windows:
cannot register existing type 'GdkPixbufGdipAnim'
Closes: deluge-torrent/deluge#329
Deluge fails to appear in some app launchers (GNOME app search, Albert launcher) when searching for just "torrent" or other keywords, rather than "bittorrent". This is due to the lack of a Keywords header/property in its desktop entry file. Adding this line should solve the issue.
I don't know if the underscore "_" is actually necessary for this line, I just copied the appearance of the lines above it when inserting. Please check that this comes out without the underscore in the final file after processing.
Closes: deluge-torrent/deluge#323
CI docs build was failing with the following error when using latest
sphinx-contrib-spelling 7.3.1
error: option -j not recognized
Fixed by pinning to previous version.
GitHub-ref: https://github.com/sphinx-contrib/spelling/issues/142
SVG files are supported by all browsers so need to support it as well,
according to https://www.w3schools.com/html/html_favicon.asp
Also, it appears as SEO.com site, which was dropped because of a cert issue,
has only SVG icon. So enabled it again.
Lastly, from python 3.2, `os.path.samefile` is supported on Windows.
So Windows will now test TrackerIcons as well.
* Removed all __future__ imports from code
* Removed all six dependencies
* Removed all future_builtins imports
* Removed all Python 2 related code
Closes: deluge-torrent/deluge#325
The sort for Ascending was putting longest eta first but seems more
intuitive that the smallest time to wait should be first. The WebUI
in previous commit swapped this behaviour so updating GtkUI.
When sorting the according to ETA values, all torrents with infinite value were being
considered a lower value (INF -> 12 -> 32) instead of largest (12 -> 32 -> INF).
This is due to the fact that the INF symbol is placed to lower value (<= 0).
Now the lower values are being treated as the largest JS number when sorting.
Closes: https://dev.deluge-torrent.org/ticket/3413
Closes: https://github.com/deluge-torrent/deluge/pull/321
With this change, we drop a core dependency from the UI. This will help group together
all related functionality in one place, i.e. all security related functions.
Also updated testssl.sh version to 3.0.6 (SECURITY_TEST)
Closes: deluge-torrent/deluge#288
The Web server config for language was set to an empty string which
resulted in an warning logged by i18n set_language.
* Changed set_language to ignore empty language string and do nothing.
We don't want to override the user's system language unless actually
specified by the user.
* Improved the translation warning message.
Some users encoutered a bug where WebUI in browser show a white screen,
which indicates a problem with loading javascript files. The problem was
due to closure minifying failure leaving a zero-length deluge-all.js
file which broke the usual fallback mechanism to debug files.
* Fixed usage of ES6 const declaration breaking closure minifying.
* Cleanup minified files upon errors so no zero length files left
* Replaced broken and unmaintained slimit with rjsmin.
* Fixed unable to set dev or debug query args due to request args
requiring bytes.
Rewrite install instructions to include more details on Deluge 2.0
install.
* Added other Linux distros
* Added stable PPA details
* Added link to forum for Windows and macOS community packages
Co-authored-by: Sergio M <sergio@example.com>
Co-authored-by: Ofry Linkovsky <15746116+OfryL@users.noreply.github.com>
Closes: deluge-torrent/deluge#296Closes: deluge-torrent/deluge#310
We used recommonmark so that we can use markdown in sphinx but it is
buggy and now so switch to better supported MyST-parser.
* Fixed incorrect heading warnings in markdown.
* Added sphinx toctree to markdown using directive as required by MyST.
* Upgraded Sphinx to 4.3
Ref: https://myst-parser.readthedocs.io
In case deluge GTK gets focus with a new torrent URL on the clipboard,
the "Add Torrent from URL" dialog will pop up automatically
Closes: deluge-torrent/deluge#306
Workaround lt 2.0 python bindings error when calling a torrent handle
file_progress:
```
Boost.Python.ArgumentError: Python argument types in
torrent_handle.file_progress(torrent_handle)
did not match C++ signature:
file_progress(libtorrent::torrent_handle {lvalue}, libtorrent:🎏:bitfield_flag<unsigned char, libtorrent::file_progress_flags_tag, void> flags=0)
```
Should be fixed in 2.0.5 release: https://github.com/arvidn/libtorrent/commit/3feba04e6d
When enabled in preferences the piecesbar was crashing the application.
This was narrowed down to an issue with text_font property and there was a
suggestion that the PangoFontDescription should be freed after getting
the result from get_style_context.
Fixed by creating a copy of the PangoFontDescription
Refs:
* https://trac.wxwidgets.org/ticket/15697#comment:1
Fixed the Stats GTKUI test not updated to the new GTK3 dir layout.
Fixed pygobject cairo ImageSurface error:
AttributeError: 'gi.repository.cairo' object has no attribute 'ImageSurface'
The documentation seems to suggest that using `import cairo` is the correct
usage and this fixed the issue, along with adding suggested gi.require_foreign
call.
References:
https://pygobject.readthedocs.io/en/latest/guide/cairo_integration.html
Unit tests are segfaulting and this is a result of a subsequent call to
pop_alert creating a dangling pointer to alert.message method.
Replace alert.message call with correct external_address property that
doesn't require any parsing and wonder trigger segfault to expired
pointer.
https://github.com/arvidn/libtorrent/issues/6437
If the primary clipboard was empty the fallback resulted in an unhandled
error due to missing arguments.
Fixed by using SELECTION_PRIMARY as fallback clipboard
Users were complaining about logs being flooded with `Session status key not valid`
which was a result of the Stats plugin using the wrong status keys.
Fixed by changing to debug log level since not useful in warning level
if spamming.
Since libtorrent 1.2.10 magnets save resume_data even with metadata not
yet downloaded. Unfortunately when using the deprecated
add_torrent_params key resume_data results in an error "missing
info-hash from URI"
The problem is due to lt session requiring an info_hash in
add_torrent_params but resume_data does not set or override this key and
resume_data overrides the add_torrent_params.url with an empty string.
The workaround is to specify the info_hash in add_torrent_params. We
require sha1_hash object or bytes and use of bytearray to maintain
python2 compatability.
https://dev.deluge-torrent.org/ticket/3478
The console tests are still failing on Windows due to an issue where the
sys args are not being correctly replaced in the tests so the pytest
args are being passed to console.
Fix user reported error:
Notification failure using email:
[Failure instance: Traceback: <class 'KeyError'>: 'name'
This was due to using empty dict used with get_status where a list of
keys is now required or the all_keys parameter is used.
Fixes: #3303
* Added required dependency setuptools to install_requires
* Remove optional dependency ipaddress from install_requires
* Created extras_require in setup.py. The optional dependencies should
not be included in install_requires so that users can either install
forked dependencies or remove problematic ones. Updated documentation to
detail how to install these optional dependencies.
* Fixed README badge
Refs:
* https://dev.deluge-torrent.org/ticket/3470
* https://dev.deluge-torrent.org/ticket/3282
* https://dev.deluge-torrent.org/ticket/3353
The modification of Python logging _findCaller args in Python 3.8 raises
TypeError in our custom Twisted Logger with Twisted <= 19 versions.
The actual issue for the custom logger was fixed in 18.9 so added a
version check to avoid usage.
Refs:
- https://twistedmatrix.com/trac/ticket/7927
- 6b894744e4
Due to new limitations for open-source projects on Travis we are
switching to GitHub actions.
* Notes about system site-packages
We had many problems with accessing system python packages on Travis for
libtorrent and GTK and the problems are harder on Github since there is
no more access. For now copying the python libtorrent binary into the
deluge source is the workaround. There is a pip package that could be
used in future.
Fixed failing tests with libtorrent 1.2 which required a non-zero length
file in torrent and workarounds for async alert delay.
Properly fix adding magnets, first attempted in previous commit 2e466101fc20a
add_torrent_magnet does not return a deferred so wrap in maybeDeferred.
Fixed broken test due to new deluge website icon
The autoadd function does not apply labels to torrents that are added via magnet files.
Those magnet files are also renamed ".Magnet.Invalid".
Here are two threads discussing the issue, which still exists.
https://forum.deluge-torrent.org/viewtopic.php?t=55539https://dev.deluge-torrent.org/ticket/3295
Here is what Deluged.log shows when the problem occurs:
21:51:38 [ERROR ][deluge_autoadd.core :333 ] Cannot Autoadd magnet: /Torrents/TorrentFiles/FileName.magnet: Torrent already in session (e1e0f33b656cb74532dcddc04f2ec52771ef1c26).
21:56:38 [ERROR ][deluge_autoadd.core :333 ] Cannot Autoadd magnet: /Torrents/TorrentFiles/FileName2.magnet: Torrent already in session (ef839d84d113cc35719b6fd616a4d8e220de7d32).
After looking at the code, what appears to be happening is the magnet link is added, but then a second scan of the folder occurs. Since the magnet file was never renamed, it will attempt to add it again, error out, then rename the file "magnet.invalid".
The only difference between the torrents working properly and magnets having the issue is the two lines I copy-pasted into the magnet IF statement. This should resolve the issue.
libtorrent 1.2 added endpoint struct to each tracker, to prevent false
updates we will need to verify that at least one endpoint to the errored
tracker is working. if there is at least one working, it will not set
the tracker status to
error and set it to `Announce OK`. otherwise, it will use the error
message from the alert.
Refs: https://dev.deluge-torrent.org/ticket/3384
Some torrent files built with py3createtorrent fail to produce a
file listing in the WebUI when uploading them.
This made it impossible to add such files.
Specifically this is caused by the additional metadata when using
py3createtorrent with the `--md5` flag.
* Added APPDATA to tox passenv so it is available to common module.
* Fixed windows path issue in httpdownloader tests
* Skipped torrentmanager test due to the following error from loading a
Linux pickled state file with a different line ending.
ModuleNotFoundError: No module named 'deluge.core.torrentmanager\r'
* Removed appveyor build
Torrent downloads from rutracker responds with the header:
Content-Type: application/x-bittorrent; charset=Windows-1251
The problem is that httpdownloader was using the charset to re-encode
the downloaded file, corrupting the binary torrent file download.
Fixed by only re-encoding text content types, since it is very rare
that non-text content types would actually have a non-utf8 codeset and
if there is a requirement we would need to determine it on a type by
type basis.
The GTKUI tests were failing and the saved config for the tab bar
position was not being restored.
Fixed by moving the setting of notebook.tabs_pos to TorrentDetail init.
Replaced more deprecated methods that were showing up in tests.
The tabs placement for the torrentdetails notebook might not be to
everyone's liking so add a menu item to configure it.
Default the position back to top.
Notifications plugin uses pygame for sound notifications however pygame
show a console message "Hello from the pygame community." whenever
starting deluge from console.
Refs: https://stackoverflow.com/a/55769463/175584
Users were encountering the following error while attempting to delete
magnet torrents and had the config 'Delete copy of torrent file'
enabled. This was due to removing a magnet before the metadata was
downloaded and the torrent.filename was still set to None so raises
exceptions when string operations are performed with it.
File "/usr/lib/python3/dist-packages/deluge/core/torrent.py", line 1317, in delete_torrentfile
os.path.join(self.config['torrentfiles_location'], self.filename)
...
TypeError: join() argument must be str or bytes, not 'NoneType'
Fixed by both setting a default empty string for self.filename and only
deleting the torrent file copy if filename is set.
The tests in ConsoleUIWithDaemonBaseTestCase could fail to the hard coded
port 58900 being busy.
Fix by using the proper port found in self.listen_port
Also convert unnecessary use of assertTrue where more appropriate
assert functions should be used, such as assertEqual and assertIn
Encoutering an error when webui attempts to download tracker icon:
Error occurred downloading file from "http://b'acg.rip'/": invalid
hostname: b'acg.rip'
Fixed by ensuring the request.tracker_name is decoded from bytes before
looking up the icon name.
* Fixed black hook requiring Py3.6 to installed locally. Will now assume
Py3.6+ in installed.
* Added isort traceback in pre-commit flake8 hook fails
* Updated versions of Black, Prettier and isort
* Keep Flake8 at 3.7.9 due to E402 issue: https://gitlab.com/pycqa/flake8/-/issues/638
* New pyproject config for isort v5 with fixes for Python 2 imports.
* Fixed travis config to run Python 3.6 for lint run. Replaced the
virtualenv with_system_site_packages config with Travis specific Python
config value so lint run doesn't attempt to append with_system_site_packages
to Python 3.6 command.
Comparisons on Python 3 are much stricter resulting in the following
error comparing with None:
TypeError: '>' not supported between instances of 'NoneType' and 'str'
Fix this by getting the type of the other value and getting it's default
value.
If a host in hostlist failed DNS lookup or other issue it was returning
a tuple instead of deferred. Fix this in hostlist by returning a
defer.succeed.
A race condition with BaseMode was also encountered when
update_hosts_status calls update_select_host_popup and
ConnectionManager does not have a rows attribute. Fix this by init
BaseMode before update_hosts_status and remove already called
update_select_host_popup.
Python3 has stricter type checking and passing a port as string results
in libtorrent raising a TypeError.
Fixed by casting port to int, along with refactoring to ensure ipv6 is
correctly parsing and a useful error is output to user with invalid ip
or port details.
https://dev.deluge-torrent.org/ticket/3348
If a password or other string contained a double-quote then the config
would fail to be loaded on startup and reset.
This occurred due to fixing a similar issue with curly braces for #3079
in commit 33e9545cd44 and the checking for double-quotes had unforseen
consequences.
To resolve both these issues the code to check for json objects in
config files was simplified and utilises the json module raw_decode
method to ensure the extracted string indexes are json objects.
Commit b32c5d824 changed the logged message in deluge/core/daemon_entry.py
when libtorrent fails to listen on the given port, without updating the
trigger expression in deluge/tests/common.py:start_core to match the new output.
Fix by updating the trigger match expressions to match the new log output
Accessing pytest.config is deprecated and produces:
PytestDeprecationWarning: the pytest.config global is deprecated. Please use
request.config or pytest_configure (if you're a pytest plugin) instead.
Fix by using a pytest.fixture
Currently, the dialog window is displayed until after the callback has returned.
The result is that if a new dialog is opened from the callback, the first dialog
is still displayed until the new dialog is destroyed.
Fix by destroying the dialog before running the callback.
The exception string "No module named libtorrent" was changed to
"No module named 'libtorrent'" in python 3.3, which results in a
"unknown Import Error" message being displayed instead of the
message meant for libtorrent import error.
Change to raising LibtorrentImportError in _libtorrent.py and
catch this error to display libtorrent specific import errors.
* Error occurring with Pytest 5.4 so pin to below that version.
* Fix minor issues with Travis config.
* Use full command-switches for pytest in tox config.
* Remove pin for pip as issue with pip-wheel-metadata was fixed in 19.3
* Remove tox-venv as causing issues of incompatible packages installed.
The latest versions of the virtualenv package should handle these
duties.
GitHub user JohnDoee reported that config settings are not decoded
correctly, this error can be reproduced with a command like
deluge-console -c /config/ "config --set download_location /downloads"
> AttributeError: 'str' object has no attribute 'decode'
The tokenize code was using 'string-escape' to decode strings but there
is no direct replacement in Python 3 but also unnecessary. However the
tokenize code is complex and buggy and not really suitable for the task
of evaluating config values.
A better alternative is to evaluate the config values using the json
decoder with some additional logic to allow for previous syntax usage,
such as parentheses.
Added a comprehensive set of tests to check for potential config values
passed in from command line.
Deluge's logger class extends Python's `logging.Logger`. Since Python
3.8, it takes an additional argument `stacklevel`.
The implementation in Deluge does not support that. Work around the
problem by ignoring additional arguments.
When trying to load a torrents.state from version 1.3 users were
encountering the following error:
UnicodeDecodeError: 'ascii' codec can't decode byte
This was due to the way that Python 2 was pickling state with torrent
filenames that contained non-ascii characters and Python 3 was
unpickling the state using ascii encoding and failing. The fix is to
specify utf-8 encoding when loading torrents.state.
When a user clicked ESC key or X button, the Options and Add windows
didn't open again. This happened because the windows were closed and
not hidden, which deleted the instance of those windows.
This fix changed the behavior of the close action to 'hide'.
Some users have been reporting unhandled UnicodeDecodeErrors and the
traces show it occuring in the call to `peer.client`. Although unable to
replicate it seems prudent to put a try..except around the call to
ensure it does not break the UIs.
Refs: https://github.com/arvidn/libtorrent/issues/3858Closes: #3279
If dbus org.freedesktop.FileManager1 service is missing then show_file
raised an unhandled exception. The service is not available on certain
desktop environments e.g. i3wm.
The solution is to fallback to xdg-open.
Fixes: #3272
- Use sphinxcontrib.spelling with custom wordlist.
- Skip the checking of the modules documents as they raise
false-positives.
- Add a setup.py spellcheck_docs command.
- Fix spelling and other issues.
- Add a doc favicon.
Include the correct usage for other display servers.
Still not sure how to get the proper timestamp for Wayland or Quartz but
I read that using 0 equals the GDK_CURRENT_TIME which suffices for now.
Hovering over a country flag resulted in an AttributeError.
This is due to get_tooltip_context now returning a bool value instead of
the tooltip object.
Fixes: #3219
A user reported a problem with setting base path resulting in this error:
encoding with 'idna' codec failed (UnicodeError: label too long)
It is likely the base path is longer than 63 chars, which is unusual,
however the idna codec is for domain name not paths so switch to utf-8.
Fixes: #3261
With the `deluge` user specified in the unit files it ties it to
that user and makes it unavailable for re-use by systemd user instance.
Remove the user and group from the unit files and put them in a separate
`user.conf` file that should be installed as an override file e.g. for
deluged.service this would be placed as follows:
/etc/systemd/service/deluge.service.d/user.conf
Add the systemd files to the tarball for package maintainers.
Closes: #2034
Use post segment instead of dev for non-dev tags.
Default to 'deluge-' and '.dev0' to simplify getting version.
Refactor to use subprocess.check_output
Use deluge.common.get_version as fallback in docs conf.
Changes in libtorrent 1.1 mean that alerts are no longer allowed to be
accessed after the next call to pop_alerts.
> It is safe to call pop_alerts from multiple different threads, as
long as the alerts themselves are not accessed once another thread
calls pop_alerts. Doing this requires manual synchronization between
the popping threads.
The solution is to copy the alert attributes and pass that to the
handlers.
Refs: https://github.com/arvidn/libtorrent/issues/2779#3159
Some changes between lt 1.1 and 1.2 require updates to core code.
- Switch from proxy_type to proxy_type_t
- Replace hardcoded flag value with add_torrent_params_flags_t since
1.2 uses different flag values.
- add_torrent_params requires flags set instead of dict values.
Refs: #3255
On macOS the Quartz windowing is used instead of X11 so make ensure
that the X11 window calls are optional.
Also if gtkosx_application is not available then don't create osxapp.
It would be useful to find out how to pass window timestamps on Quartz.
- Change build from Python 2.7 to 3.6 64-bit.
- Specify py36 for tox since using py3 will choose latest py3 e.g. 3.7!
- Use python 3.6 libtorrent.pyd build
- Use pre-installed OpenSSL 1.1 (matches libtorrent build)
- Add python version output to tox.ini for debugging.
- Updates to the sphinx conf
- Applied Mock fixes to build on Python 3.
- Group patches at bottom of conf file.
- Use just a major.minor for version.
- Specify Sphinx 2.0 version requirement.
- Move requirements.txt to docs dir.
- Add readthedocs config
- Fix docstring code block rst formatting issue.
Encoutered an error reordering files by dragging in the files tab:
TypeError: can't pickle TreePath objects
The issue was get_selected_row now returns a list of TreePath objects which
cannot be pickled. Also the set_text method only accept unicode text to
pickled bytes cannot be used.
The fix is to convert the TreePaths to strings and use json to encode
the list of strings for set_text.
When adding magnets that have been prefetched the tracker details were
lost. A result of returning only the lt.torrent_info.metadata which
does not contain full torrent details, such as trackers.
- Modified torrentmanager prefetch_metadata to return dict instead of
base64 encoded bencoded metadata dict...
- Used a namedtuple to ease identifying tuple contents.
- Updated tests to reflect changes with mock trackers added to
test_torrent.file.torrent.
- Refactor TorrentInfo to accept dict instead of bytes and add
a class method to accept metadata dict with lists of trackers.
- Rename class arg from metainfo to torrent_file, matching
lt.torrent_info.
- Rename metadata property to correct name; metainfo.
- Simplify class variable naming with _filedata and _metainfo for
torrent file contents encoded and decoded respectively.
- Update GTK Add torrent dialog to pass trackers to TorrentInfo.
When adding magnets (without prefetch) the trackers were missing.
The issue was that the magnet uri was being xml escaped twice so that
the ampersand was still escaped when passed to core and everything after
the magnet info_hash was ignored.
Also found unneeded call to core.add_torrent_files when only adding
magnets with core.add_torrent_magnet so check torrents_to_add before
calling.
Passing a non-bencoded dict to bdecode resulted in an unhandled
TypeError.
- Catch TypeError in decode_func.
- Add bdecode tests.
- Replace KeyError and IndexError with base LookupError.
Disable the warn_msg in daemon_entry since the argparse option are all
marked for translation and warnings are being output. The original
intent of this warn_msg was to identify anything in core code that was
incorrectly marked for translation.
This commit reverts namespace for the plugins and uses a module prefix
"deluge_" in it's place. The distribution package name remains the same
for now but will also be considered to use a prefix to help find the
third-party plugins e.g. Deluge-{Plugin} and the pluginmanager will
strip the prefix for displaying.
The change is a result of problems trying to package Deluge with
pyinstaller and the pkg_resources namespaces is not compatible.
Testing alternatives to using the pkgutil or PEP420 (native) namespaces
did not yield any joy either as importing eggs with namespaces does not
work. [1]
At this point importable eggs are considered deprecated but there is no
viable alternative yet. [2]
[1] https://github.com/pypa/packaging-problems/issues/212
[2] https://github.com/pypa/packaging-problems/issues/244
- Added a -m|--move-completed option for specifying a move completed
path when adding a torrent.
- Re-used existing console test and renamed for generic usage.
- Moved setup_translation to tests.__init__ so it is always setup
instead of relying on tests.common import.
Closes#2847
Co-authored-by: Calum Lind <calumlind+deluge@gmail.com>
- Move baseargparser out of deluge/ui since it is also used by the
Daemon and could cause packaging issues if UI code is not available.
- Renamed baseargparser to argparserbase to follow existing Deluge
naming.
- Renamed get_version to distinguish from deluge.common.get_version.
- Translation code is usable by more than just the UIs so also move it
to Deluge namespace and re-use i18n directory and make it a package.
- Renamed setup_translations to singular as it felt more correct.
- Renamed set_dummy_trans to be more descriptive.
Closes: #3081
Trying to display the files for magnet that has no metadata and thus no
files resulted in `'NoneType' object is not iterable` errors.
Only call file prio update method if we have a list of files.
Trying to remove a torrent had no effect and resulted in the following
error: `'TorrentList' object has no attribute 'clear_marked'`
* The clear_marked call needs to be made with torrentview instead.
* Ensure the popup dialog is closed upon deleting the torrent.
* Use EncodingResourceWrapper to replace compress function so that the
proper checks for accept-encoding header are made.
* Ensure only text is compressed and images are left uncompressed.
Should be setting header contents to string not ints and latest version
of Twisted raised an error encountering int. Also correct the header
name for setting length.
The Gdk threading code is causing issue on Windows and this method
of moving the main loop to a thread has been deprecated and advised
against so removing without adding replacement as it currently
only creates one main thread and should still be fine.
If a blocking operation occures and needs solving, see the pygobject
guide for recommened way to use threads in Gtk:
https://pygobject.readthedocs.io/en/latest/guide/threading.html
- Fix new flake8 warnings from latest version.
Note: The `addSlash` variable was orphaned with no reference in
Twisted or Deluge code so removed.
- Update pre-commit config
- New pinned versions.
- Fix prettier output.
- Use new flake8 hook config and add naming plugin.
Added 'TIMESTAMP' key to startup-id string for dbus method. Unsure if
this is the correct way to specify startup id but it seems to work.
Recreate the dbus session with each call since if there is an error
with the dbus method then it will crash and subsequent calls will fail
with a cryptic message:
dbus error the name was not provided by any .service files
Disable the testing with seo.com as the site certificate has expired.
Ideally should not be testing against live sites and instead use request
replay tool such as VCR.py.
The bad host id error usually occurs on webui when the 'default_daemon'
key in web.conf does not exist in hostlist.conf.
Added a errback method to output a more useful log message.
Removed previous workaround to ensure sync of file priorities with
libtorrent. This did not work when loading torrents as the status is
called before setting the file priorites and resets them to default.
Removed the call to set_file_priorities when writing the torrent file
to disk as it resets the options to default so although the torrent
file priorities do not change, the priorities for UIs is incorrect.
Replace the 'D' header with an unsigned byte that indicates the protocol version. This will allow easier changes to protocol in the future.
Replace the signed integer used for message length with an unsigned 32-bit integer. There is no need for a signed value here as a message length must always be positive. This also doubles the max message length.
- On Python 3 find_msvcrt returns None and _wputenv should be used with
unicode strings.
- Removed the alternative msvcrt set env since `cdll.msvcrt` should suffice.
- Removed the broad exception catching.
The main issue here is a user trying to start deluge and the XDG
`user-dirs.dirs` file contains dir names with non-ascii chars causing
a UnicodeDecodeError when comparing with unicode chars since Py2
default encoding is ascii.
The solution is to use io.open as used elsewhere in code with
encoding set to utf8. Applied to all usage of open in common.
When showing the main_window, Add dialog or file manager windows they
would not appear at the top of the display stack, always one below.
This is due to needing the windowing timestamp to be passed when making
these calls. The recommended Gtk solution to use present_with_time and
use an event.time timestamp. However, this does not always work so
instead used the lower level Gdk set_user_time and fetch timestamp from
X11 server.
Notes:
- Using int(time.time()) for timestamp is not correct as the
windowing timestamp is different.
- Gtk.get_current_event_time only works when there is an event being
processed.
- It might be useful for non-X11 windowing systems to store event
timestamps so that we have a value to use instead of 0.
- Fixed the sidebar position not being restored by applying the config
value in main_window first_show and updating config in position
callback.
- Renamed the main_window vpaned and hpaned widgets to aid identifying
purpose.
- Fixed filtertreeview KeyError when not conneted and hiding tabsbar.
- Fixed the tabsbar notebook not being hidden on restart by adding a
new config value.
When not connected the tray preferences should still be available.
There is no need to have the `is_connected` applied to widget
sensitivity here as that is set elsewhere in the code.
- Fixed the core not correctly settings the current file_priority
settings and added a test.
- Fixed the console not setting file priorities.
- Change the label for not downloading of a file to 'Skip'.
If the torrent.state was corrupted then loading would create a new
state with no backup to examine.
The solution is to use the archive function to save a copy of the
torrent.state.
Added a message argument to archive_files so that the error message
with a reason for archiving can be included in the tarball.
Users encounter issues when trying to install plugins with differing
python versions. If the plugin was built with Py2.6 but they are using
Py2.7 the plugin would not load. With the move to Python 3 this could
become more of an issue. The workaround is to let the plugin manager
to try to load the deluge plugin regardless of the python version it
was built with.
This will put the onus on plugin author to keep the plugin code
compatible with more Python versions.
There were issues with dependencies and tox environments under Python 3
so refactored the tox configuration to be more consistent and clearer.
- Moved travis to default to Python 3 for linting and tests.
- Fixed missing mock for cairo in sphinx config.
- Collated the base deps sections to improve readability.
- Added PYTEST_ADDOPTS env to override pytest verbosity in just tox
tests as this was a common option being used.
- Renamed env 'testcoverage' to the more concise 'coverage' and moved
html creation under single env as handy to have this output as well
as report.
- Cleaned up the isort config for gtk3.
- Added `bad-continuation` to pylint config as conflcts with black
formatting.
- Fix isort issue with bbfreeze script. This will likely be removed
in future so just skip sorting it.
To ensure properties are updated this is a simple open and save with the
glade designer. Always a bit messy with the diff but should not
change functionality.
The popup_at_pointer method is only available in GTK >=3.22 so for
compatibility restore using popup method.
Right-clicking on column headers popped-up torrent menu so only show
this menu when in torrentview.
The % substitution was causing the bytes prefix to become part of the
string and created a `b'/` prefixed config directory. Ensure the config
arg is byte prefixed too.
- Added a tooltip to show text status which also required translation
so created a new liststore column for the translated text to ensure
status is parsed correctly.
- Forced the status to lowercase to avoid translation issues and
simplify comparisons.
Replace the old appindicator imports with AppIndicator3.
- Only few changes required due to Enum renaming.
- Updated the preference import to include require_version and set a bool.
- The password preference needs to be encoded for hashlib on Python3 but
also need to keep Python 2 support so attempt decode then encode.
- Switch from pynotify to gi libnotify binding.
- Ideally would drop libnotify for [GNotification] but requires more
work with the desktop file needing renamed to DNS format.
e.g. `org.deluge-torrent.deluge`
[GNotification]: https://developer.gnome.org/GNotification/
Co-authored-by: Calum Lind calumlind+deluge@gmail.com
- Added new svg icons for cleaner look.
- Use widget get_allocated_width and get_allocated_height instead of window size.
- Tweaked margins to fix spacing issues.
- Removed yellow background from 'slow settings' and applied only to label.
Co-authored-by: Calum Lind <calumlind+deluge@gmail.com>
- Several of the FIXME comments seem to be outdated so removed.
- The status_icon comment was resolved by fixing the arguments supplied to
tray_menu.popup().
- The TreePath no longer returns a tuple so cast path to int.
- Fix an error with Pixbuf signature.
With move to GTK3 needed to update the mocking of external modules.
There is a new autodoc option `autodoc_mock_imports` so use this instead
of the custom mock class.
There are some build warnings output using autodoc mock:
TypeError: unsupported operand type(s) for |: '_MockObject' and '_MockObject'
Will resolve these later as the build passes.
In Python 3 builtin next function instead of the next method.
Unpickling with translated strings in state file causes ascii decode
error so ensure UTF-8 encoding is specified.
Right-clicking on column header resulted in this error:
TypeError: could not convert type EventButton to GdkEvent required for parameter 0
The following fixes and cleans up the issue:
- Move the signal creation to the class, using the __gsignals__ dict.
- Replace `Event` with `object` since we are passing an EventButton as
Gtk3 no longer accepts it as an Event.
- Replace deprecated menu `popup()` with `popup_at_pointer()` which also
fixes a critical gdk error when using `popup()`.
The filechooser dialog was wrongly transient to the main window causing
weird behaviour, namely the main window moving but dialog remaining in
place when attempting to move the child dialog.
The solution is to pass the parent dialog to PathChooser so it can be
properly set the filechooser dialog transient property.
Fixed the Preferences dialog not being set to be modal to main window.
My personal feeling is that GTK client-side decoration (CSD) putting
main dialog buttons in the titlebar is wrong so create a non-CSD dialog.
There was no simple way of changing GtkFileChooserDialog to play nice
with non-CSD buttons and resulting in these GTK warnings:
Gtk-WARNING : Content added to the action area of a dialog using header bars
There is an unwanted dialog border with this custom filechooser dialog
with no apparent way to remove them. Would require switching to a
GtkWindow implementation.
GObject.idle_add is deprecated using GLib.idle_add instead
GObject.timeout_add is deprecated using GLib.timeout_add instead
GObject.SIGNAL_RUN_LAST is deprecated; use GObject.SignalFlags.RUN_LAST instead
GObject.GError is deprecated; use GLib.GError instead
GObject.timeout_add is deprecated use GLib.timeout_add instead.
ListStore(str, str) using unicode_literals get_value return utf8.
- VBox is Box(vertical);
- HBox is Box;
- HButtonBox is ButtonBox;
- HSeparator is Separator;
- VPaned is Paned(vertical);
- Table is Grid;
- use_action_appearance is purged;
- yalign is purged;
- xalign is purged;
- xoptions are purged;
- yoptions are purged;
- add some align: start;
The apidoc modules were not being generated on ReadTheDocs because
there is no way to run sphinx-apidoc manually.
Moved the running of sphinx-apidoc into conf.py.
Added zope.interface minimum version to fix Readthedocs warning.
The use of pkg_resource.require caused an unwanted requirements lookup
that errored out the sphinx build when no dependencies are installed.
This is fixed by switching to pkg_resources.get_distribution.
Also changed the tox docs env to not install Deluge as the setup.py
now contains install_requires which is unwanted.
- Change the layout and contents of docs to be better organised and
follow ideas from: https://www.divio.com/blog/documentation/
- Use markdown for non-technical documents to speed up writing.
- Added new sections and imported documents from Trac wiki.
Build fixes:
- Added a patch to fix recommonmark 0.4 and doc referencing:
https://github.com/rtfd/recommonmark/issues/93
- Set docs build in tox to Py2.7 since there are problems with autodoc
mocking multiple inheritance on Python 3 resulting in metaclass errors.
- Supressed warning about `modules.rst` not in the toctree by creating
a static `modules.rst` with `:orphan:` file directive and add to git.
Also skip creating this toc file with sphinx-apidoc in setup and tox.
- Simplified finding exported RPC and JSON API methods by adding an
autodoc custom class directive. Removed unneeded __rpcapi.py.
- Fix applying the setting to libtorrent, passing the value without
modification so it decide when to enable it.
- Enable super_seeding option when adding torrents to core.
- Update UIs with option in tabs and add dialogs.
- Found an issue while fixing `get_name` where `handle.rename_file`
would raise a UnicodeDecodeError with non-ascii on Python 2. The
fix is to catch this and pass unicode string to method instead.
- Add a test `test_rename_unicode` to verify no errors are generated.
- Updated test to use core.session instead of creating another one.
The recent change to torrent.get_name does not handle non-ascii paths
on Python 2.
- Add a decode_bytes to resolve the issue.
- Add tests.
- Refactor to reduce nesting.
- Replace usage of `s` for variable names to make it easier to read the code.
- Remove unneeded and unused encoding parameter from parse_color_string
It should not be encoded by this function, only on output.
The following error was encountered by user:
...deluge/ui/console/modes/basemode.py, line 290, in add_string
screen.addstr(row, col, string, color)
UnicodeEncodeError: 'ascii' codec can't encode character...
The `add_str` method is defaulting to using the Python 2 ascii
encoding with a unicode string so use the encoding passed to the
function.
- Add an About window to see version details like GTKUI.
- The author and license text were left out as unnecessary.
- Added a daemon get_version method since daemon version was not
available through the json-api.
- Fix LookupResource to ensure path exists when rendering.
If a user keeps the deluge config file under source control and symlinks
to the config files in deluge config dir then when deluge saves config
files it will replace the symlink with actual file.
Using realpath will resolve these symlinks and file will be updated in
the correct location.
Use a temporary file for new config new before moving it to the
resolved location.
Co-authored-by: Calum Lind <calumlind+deluge@gmail.com>
- Use named placeholders to allow translators to change text order.
- Refactor fpcnt to use format() and markup strings properly.
- Remove gettext.js creatation from generate_pot script since this step
is now always done at build-time.
The following error was encountered in GTK3 which is a result of trying
to cast a very large ETA value to C int and raising an Overlflow error.
<type 'exceptions.OverflowError'>: 3072227291 not in range -2147483648 to 2147483647
The solution is to limit the ETA to 1 year and represent any values over
that as -1 which the UIs can display as infinity.
Remove extra_requires since requirements-*.txt files provides these now
plus the extras_requires is for extras at installation time which does
not apply to docs or dev.
For test_requires include the minimal requirements for pytest to run.
This is not the same as the longer tox test requirements that include
linting, docs etcs.
Fix license field.
- Add an install_requires list to allow dependencies to be automatically
installed via setuptools or pip installation.
- Needed a workaround for twisted service_identity install.
- Tweaked the layout a bit with optional part of dependency description.
- Updated descriptions to help understand dependency usage.
- Made intltool and chardet packages optional. This will help with
installation where these might be missing and are not crucial.
- Remove gettext from dependency as is part of Python.
- License should be GPL3+.
- Use the Deluge HTTPS URLs.
- Wrap the description long lines.
- Add launchable tag to launch from software centre after install.
- Removed name tag to use .desktop file name field instead.
The new get_name method needs to function as it did in 1.3-stable so
when renaming a torrent file or top-level folder update torrent name
to reflect that. If UI supports renaming the torrent then the options
value with be used instead.
The refactoring of the options code didn't update to use the new status
key `auto_managed` and `is_auto_managed` is not a valid torrent option.
Related: 1637da84e4
The exclude 'deluge.tests' in setup.py is for excluding from package
installation but we want the files when distributing as source so
include the entire deluge/tests dir (excluding .pyc files).
Use markdown to aid readability.
Update the README and use it for the long_description in setup.py
Add detailed requirement information to the DEPENDS files.
When installed as a development version there was no way to load the
normal js scripts so improve the debug arg handling by parsing for false
values to force use of normal type scripts. Since debug arg overrides dev,
leave dev as is.
All of the non-standard docstring file headers were being added to
minified files, increasing the file size. Replace with jsdoc `/**`.
Remove ext-extensions from git as will be generated by minify script.
Prettier removed too many parentheses in asIPAdress and when minifying
the plus unary combined with the plus operator to create an incorrect
increment operator. So skip prettier formatting this secion of code.
Also fix an ECMA5 warning from closure about function scope in FilesTab.
- When both minifying modules are missing, creating a copy of the debug
file is not actually desirable, a missing file is more obvious than a copy.
WebUI can handle a missing 'normal' script and fallback to 'debug' script so
modified script to skip and warn instead.
Packaging:
- Decided that the debug files are useful for end-user so keep them in
package installation. For debug script_type to be usable all debug
file need to be avaialble so extjs debug files also included.
Script type selection:
- Fixed dev and debug request args to be properly decoded on Python 3,
otherwise comparison would fail and allowed any case for values.
- Modified the choosing of the script type to pick debug if specified
as previously always choosing dev type if dev version was True. A rare
scenario but useful but now debug is used if specified otherwise use dev.
- Changed the order when looking for alternative script types to start
with dev so that if debug is specified but missing it uses a similar
script type as previously would fallback to normal which is likely
undesired.
In TorrentView and PeersTabView, when moving the mouse pointer through
rows, the value in download and upload speed columns can be overwritten
by value from previous row cell.
The solution is to disable return by cached condition in function
cell_data_speed.
Discussion: https://github.com/deluge-torrent/deluge/pull/200#issuecomment-424907571
Removed debugging code.
Co-authored-by: Calum Lind <calumlind+deluge@gmail.com>
Refactoring for Python 3 did not account for the `self._files` using an
updated info_dict so simplify code by updating in the files for loop.
Added test that TorrentInfo.files returns the correct structure.
In a previous commit d4023e7dde42 removed a decode for Python 3 but
with translated text returned by gettext encoded on Python 2 the
escape function would raise a UnicodeDecodeError trying to use ascii
to decode.
The fix is to decode the message returned by gettext on Python 2.
- Use the apt addon for installing libtorrent package.
- Start the py3 test sooner as it is slow to complete.
- Add if conditions for gtkui test dependencies.
- Remove Appveyor tests that are taken care of by Travis.
Add a new `multiple` field to FileUploadField to allow selecting
multiple files. Include a fallback for if browser does not support
multiple file selection.
Update Add window to upload and parse multiple torrent files at once.
This will remove the setup dependency in "slimit" package.
In case "slimit" is missing, the non-minified JS files will be copied
as is to the build.
"slimit" is marked as a dependency for development process only.
- Add lint section to tox.
- Replace flake8 with lint on Travis and remove commented out sections.
- Remove flake8 from appveyor to reduce sequential testing time.
- When running pre-commit on all files it is picking up minified js and
css files. Since prettier will format correctly the source files ignore
them in end-of-file fixer.
- The template files in web docs can be ignored too.
- Removed the unneeded `pre-commit-hooks` dependency as pre-commit
resolves that itself.
- Include files fixed by pre-commit.
- Add new requirements files to make it easier to install deps.
- Tox changes
- Update tox to use new requirements files.
- Tweak heading styles.
- Add development environment command `devenv`.
- Remove testenv command as it would run on devenv creation.
- Travis changes
- Now uses xenial as trusty is very old now.
- Trial run disabled to speed up tests.
- Add tox-venv for Python 3 support.
- Only install testssl if running security tests.
- Appveyor
- Add tox-venv for Python 3 support.
- Use requirements file for non-tox.
- Remove trial run to speed up testing.
- Added a pre-commit config for code linting and formatting. It will
auto-format python, javascript, CSS, YAML and markdown files to save
manually doing so. To install:
pip install pre-commit
pre-commit install
- Added a default virtual environment directory to gitignore.
- Use recommonmark to enable use of markdown files in docs.
- Fix theme not specified
- Remove unused spelling module.
- Cleanup mocking modules in conf so building docs requires only Sphinx.
- Simplify tox section, including use of requirements-docs file. Added
slimit dependency for sdist-ing deluge package.
With non-English languages this lookup would fail without gettext
translation of the column name.
A better solution is to not use the translatable column title as an
index but this is a quick fix for now.
The move to using auto-formatter makes it easier to read, submit and
speeds up development time. https://github.com/ambv/black/
Although I would prefer 79 chars, the default line length of 88 chars
used by black suffices. The flake8 line length remains at 120 chars
since black does not touch comments or docstrings and this will require
another round of fixes.
The only black setting that is not standard is the use of double-quotes
for strings so disabled any formatting of these. Note however that
flake8 will still flag usage of double-quotes. I may change my mind on
double vs single quotes but for now leave them.
A new pyproject.toml file has been created for black configuration.
Simplify the methods by initialising the session_status dict using
libtorrent session_stats_metrics and rate keys.
Instead of first looking for deprecated keys use exception then lookup.
Added a few more tests.
If a magnet is added to new Deluge state, then deleted, it will reappear
on restart.
The problem results from torrents requiring both state and torrent file
but magnet only rely on the state file and the save_state code not
saving if the torrent list is empty. So torrents won't be loaded as
their torrent files have been deleted but magnets details remain in
state file and are loaded again on restart.
The fix is to always save the state file even if the state is empty.
- Fix a potential scoping issue with callback function by moving to
class method and adding requried parameters.
- Remove unneeded return statements and variable.
- Disable the magnet from being auto_managed so it starts immediately.
- Reduce the default timeout to 30secs.
- Use the generic tempfile dir.
- Move callback method to be class method
A magnet that prefetched the metadata is added as a normal torrent but
with the filename set to the magnet URI. So we need to assign the URI to
magnet arg and set filename to None before creating Torrent object.
Updated the is_magnet function to prevent AttributeError with None type.
The file priorities were not updating correctly in the UI and it was
found that in lt 1.1 file priorities are now updated asynchonously so we
cannot get the values immediately. So only update the options
file_priorities if they are empty.
Python 3 raised a decoding error with the google page which appears to be
encoded with 'latin-1', so extract the content charset to decode and
re-encode in 'utf-8'.
This applies the following for both WebUI and Daemon:
1. Raised minimal TLS version to TLSv1.2
2. Added specific cipher suite list
3. Added support for ECDSA auth keys
4. Added support for ECDHE key exchange algorithm
We disabled the ability to perform TLS/SSL renegotiation and therefore
will prevent the clients from renegotiating, which can be exploit for
DoS attacks.
New security tests now will be skipped when running `pydef` and `trial`
testenvs. To run the test, use the testenv `security` or add the environment
variable `SECURITY_TESTS` before running the tests. Also should only run when
adding to the commit message the string `SECURITY_TEST`.
Add CSS background position and size for sidebar icons.
Without this change tracker icons that are too big, render as too big.
This restrains them to fit into the sidebar list item.
If the torrent_id argument received in the pause or resume methods is not a string, the methods execute with the un-parsed input and then with parsed input on a second call. A key error exception is thrown from the first call, and the second call succeeds.
Likely that the deprecation warning from cryptography is causing the
setup.py sphinx build command to return an error so the tox/travis job
is marked as failing. Changing to calling the sphinx-build command
directly solves this.
Also updated the sphinx config for built-in napoleon and faster builds
using jobs option.
Floor division will return a float if a float is provided so ensure int
when dividing by the stop_ratio. All other status values from libtorrent
are ints.
Added tests.
As of twisted 16.7.0, `twisted.web.client.HTTPDownloader` have been
marked as deprecated.
This caused the tests results to show many lines of warnings about it.
This refactor uses `twisted.web.client.Agent`, as suggested by Twisted.
- Replace usage of single char variable.
- Use max function to prevent negate lengths when calculating trim.
- Remove usage of insstr as the addstr exception when writing offscreen is
excpected behaviour so needs caught and passed. This fixes a similar
error with insstr.
The following error occured on Windows when switching to using HTTPS
url with Twisted Agent:
```
<class 'twisted.web._newclient.ResponseNeverReceived'>: [<twisted.python.failure.Failure OpenSSL.SSL.Error: [('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')]>
```
The fix is to install certifi and provide the path to the trust store as
env var for OpenSSL to pick up.
Also includes a simplication of the core test_listen_port code.
The usual minor fixes for unicode/bytes for library calls.
The minimum Twisted version is now 16 for Python 3 support so remove old
code and start replacing deprecated methods.
Raised the minimum TLS version to 1.2 for the web server.
* In Py3 base64.encodestring is deprecated so rather than use the
Py3 only encodebytes instead use b64encode. The other advantage is
that with issue a consistent TypeError is raised that we can catch.
Will the change to deluge.svg all the icons need recreated. I also
updated the script to losslessly compress the png files with zopflipng.
hicolor theme changes:
- Added a 512px icon.
- Added a deluge-panel.png for systray theming.
Added extra webui icons and updated index.html to use them
correctly.
Trying to connect to daemon B while still connected to A will cause
the torrents from A to be shown after connecting to B.
Therefor, checking if connected to any daemon before connecting to B.
The sort function used when no column is being sorted was a lambda
function that had no effect and had a bug. Instead default to sort by
the added date.
Also fixed the name column sort to lowercase and uppercase properly.
It can be useful to have the build folder available so zip it up for
download as an artifact.
Although the 7z has an exclude for the installer exe it doesn't seem to
be working.
There was a misunderstand about outgoing interface setting in libtorrent
and instead of being able to take both IP and adapater names, it only
accepts adapter names and errors with an IP address, which was the
default of '0.0.0.0' in code.
This fixes the code to not accept IP address and use empty string if it
is given one.
Also includes a bit of code cleanup.
Some new flake8 checkers were added so fix these new warnings and
any issues uncovered.
Use add-trailing-comma to fix missing trailing commas. It does not
format it as well as I would like however it was fast to change and
helps with git changes in future.
Removed pylint from tox due to large number of warnings.
Switching to Pipenv will speed up developement. See the docs for
details on using Pipenv.
- Added more flake8 checks.
- Added `detox` for running tests in parallel locally.
The tests on Python revealed a bug with comparing dev versions.
Switch to comparing by integers and setting non-dev version to infinity.
There is still an issue with suffix release comparisons beyond single
digits but will leave that for now.
Use a sha1 of time.time() can result in identical host_id. This was
evident with Travis tests randomly failing due to host_id collision
returning the wrong host details.
Using uuid4 to generate a random UUID in hex form should fix this issue.
The use of `{env:PWD}` is not available on Windows so switch to
`{toxworkdir}` which is the directory where virtual environments
are created and sub directories for packaging reside.
Instances of libtorrent with Local Service Discovery enabled are leaving
many sockets fd open with every test run and will fail with 'Too many files
open' if ulimit is >=1024.
Config values are either wrong, unused or default is better.
Disable logging of deluge log output in testing.
Newer versions of pytest now use `pytest` cmd so rename.
The synchonous add torrent method was replaced with async but this
break backward compatibility with 3rd party plugins and clients.
Added a new add_torrent_file_async method for adding single torrent.
Torrent manager has a new add_async method and split up code to prevent
duplication.
Update any use of add_torrent_file to add_torrent_file_async. Future
refactoring could use add_torrent_files instead.
There are some blocklists with encoded names that break upon importing
so decode lines to unicode.
Need to use decode_bytes as not all encoded lines are utf8!
This reverts commit 7b87a93862bae5bcb53d4134a111a308ec36f9e8.
After further discussion in the ticket this change is undesired.
> I wrongly assumed that private trackers will count how many bytes you
> download but they don't, they track how many parts(or chunks?) you
> have, when you announce it. So using total_done is fine, no change
> needed.
> Checking for private flag and using total_wanted_done for public
> enables users to be a bit more selfish. They can start a torrent,
> let it run for a bit then deselect the files they don't want and
> only upload enough to make up for what they wanted to download. This
> means they may upload less than they downloaded, hurting the swarm.
> So I personally don't think this would be a good change.
> Overall my suggestion is to close this as not a bug.
The parsing of the content-disposition in httpdownloader was not able to
handle missing parameters e.g. "Content-Disposition: attachment" and would
result in an IndexError. Added a test for this use-case.
Fixed the issue using the cgi.parse_header to extract the parameters.
The original fix was not correct as the strcoll function cannot
accept None only strings. This fix ensures that the value is an
empty string if None for comparison.
* The changes to core api now return a deferred instead of torrent_id
so need to update autoadd to use callbacks.
* Minor refactor to save one indentation level and reuse fail callback.
* Add exception handler for any errors from label plugin.
* setup.py sdist now creates a pristine tar which can be used for release.
* Uses the version currently checked-out in git.
* Removed unneeded lines in manifest.
Using common.resource_filename broke plugins so need to find a better solution for non-ascii dirs.
This reverts commit bdb3b509adf5915efa938be3871e65ee8a817093.
* Fix start_daemon using callback for non-deferred method.
* Ensure autostart checks daemon status before attempting to start it.
* Remove initial delay with autoconnect, it will retry anyway.
* Found method __connect that needed renaming to _connect.
* Tweak the timing for refresh and retries.
* Fix use of reason.trap instead of reason.check, causing code to silently error-out
and not retry connecting.
* Set the stop daemon button to insensitive when not connected. The client cannot stop
a daemon with daemon.shutdown() if daemon is not instatiated. Perhaps in future use
config and pidfile to allow shutdown without connecting to daemon.
- Use a BASE_PATH constant.
- pkg_resources caches the files in python_egg_cache which is not
required for plugins and causes issues with non-ascii paths.
* The verfication of timestamps of files on disc against those in resume data
can be buggy and sends torrents to error state for no apparent reason. It has
also been removed in latest version of libtorrent so disabling this check.
* Add host Edit button to WebUI.
* Updated and fixed associated tests.
* Refactored related gtkui code to better understand code flow.
* Removed dead code in gtkui.
* Continuation of updating code to Python 3 with Python 2 fallback.
* Using io.open allows files to be encoded and decoded automatically on write and read. This
maintains the python boundaries of unicode in code and bytes for output/files so less
explicit encoding or decoding.
* io.StringIO is the replacement for StringIO and will only accept unicode strings.
* io.BytesIO is used where bytes output is required by the enclosing method.
* Update bencode for full compatibility.
* In torrentview.stop the listview is cleared however this meant in thinclient mode
that listview sort details are empty and overwrites existing data when save_state is
then called in torrentview.shutdown.
* Move common code into Tab parent class
* The Tab init now accepts creation with name, child_widget and tab_label but
will still accept the 'oldstyle' contructor to keep backwards compatibility
with 3rd-party plugins.
* Create namedtuple TabWidget with widget, format func and status_keys. The
TabWidget are stored in a tab_widgets dict making it easier to create, save
and update large numbers of gtk widgets.
- Create new status entry `time_since_transfer` and getter that is
calculated from lt time_since_upload and time_since_download.
- Add/update all UIs and formatters.
- Included update to console layout to match other uis
- Preparation work for using six or future module for Py2/3 compat. The
code will be written in Python 3 with Python 2 fallbacks.
- Added some Py3 imports with Py2 fallbacks to make it easier to remove
Py2 code in future.
- Replace xrange with range (sort out import as top of files in future).
- Workaround Py2to3 basestring issue with inline if in instances. This means
every usage of basestring is more considered.
- Replace iteritems and itervalues for items and values. There might be a
performance penalty on Py2 so might need to revisit this change.
- An ImportError is raised if a module is listed in the entrypoint
but is not actually installed. The code will now catch this and
will de-list the ui module that failed.
There is a bug in Py2 setuptools where the build fails if unicode dict keys
are passed to package_data:
`package_data must be a dictionary mapping package names to lists of wildcard patterns`
The easiest workaround is to remove unicode_literals use in setup.py as it is not that important.
- Python 3 renames `unicode` type to `str` and introduces `bytes` type.
- Python 2.7 has `bytes` but is only an alias for `str` so restricted
to comparisons but helps keep compatibility.
- To test for unicode string on Py2 and Py3 uses the "''.__class__" type.
- Remove usage of utf8encode and just encode, problems with bytes being passed
in code will be picked up faster.
- Where possible refactor out isinstance for try..except duck-typing.
- Switch to using Python 3 naming convention where str now refers to unicode
and bytes are encoded strings.
- Cleanup docs and code
- Also rename convert_to_utf8 to utf8_encode_structure to clarify functionality.
* Added a new convert_to_utf8 function to common that is handy for
any nested dictionaries etc.
* Small refactor to get rid of duplicate code and comment will be
encoded by convert_to_utf8 function.
* Passes test_maketorrent.
* Twisted methods require byte-string arguments.
* The headers str conversion in httpdownloader _download_file was
incorrent and left the dict key still as unicode so replaced with
a dict comprehension (py2.7 requirement).
* Added `from __future__ import unicode_literals` to every file so
now all strings in code are forced to be unicode strings unless
marked as byte string `b'str'` or encoded to byte string `'str'.encode('utf-8')`.
This is a large change but we have been working towards the goal of unicode
strings passed in the code so decoding external input and encoding
output as byte strings (where applicable).
Note that in Python 2 the `str` type still refers to byte strings.
* Replaced the use of `str` for `basestring` in isinstance comparison as
this was the original intention but breaks code when encoutering unicode strings.
* Marked byte strings in gtkui as the conversion to utf8 is not always handled, mostly
related to gobject signal names.
- Using DYLD_LIBRARY_PATH seems to have the unintended effect of making associated apps
unusable (unable to locate dylds) when opening a file from within Deluge. The workaround
for now is to switch to using DYLD_FALLBACK_LIBRARY_PATH.
* There is a problem with Twisted 17 and the setup for travis and tox
using site-packages with an old openssh package.
AttributeError: 'module' object has no attribute 'OP_NO_TLSv1_1'
* The simplest workaround for now is to pin Twisted to 16.6.
- With libtorrent 1.1 dht is enabled from startup and the returned status
contains DHT node values (i.e. non-zero). Should be sufficient to only test for start
and end of the status string to be correct.
- libtorrent 1.1 changes default piece priorty to 4 so changes to
the UIs are required. Some refactoring and improvements were made as well:
- A new 'Low' priority introduced that is values 1-3.
- 'Normal' priority is now value 4.
- Removed 'Highest' with the addition of 'Low' and 'High' is now values 5-7.
- Renamed 'Do not download' to 'Ignore' so it is more succinct.
- Moved file priority constant to ui.common.
* With new version of Sphinx 1.5 the warning below was generated, caused
by incorrect formatting of return type in docstring.
docstring of deluge.config.find_json_objects:None:
WARNING: more than one target found for cross-reference u'start'
* Revert changes made to fix 'too many files open' as Image.open does
not return a file descriptor and generated the following error:
exceptions.AttributeError: 'NoneType' object has no attribute 'startswith'
- The name needed to be more descriptive of it's function.
- Moved into ui directory because of upcoming changes being made to setup.py
meant it would be easier to include all the 'common' ui files if there
are no sub-dirs such as 'util'.
- The slimit package is now widely available so make the script
only rely on it and closure. Keeping closure as it makes the most
compact and lints the javascript but it is not as easy to install
as slimit.
- There is a version.py included with buildd that is conflicting
with the deluge one. Rather than messing with sys.path it is
simplest to rename version.py to calc_version.py
Made a mistake with types of window, get_window actually refers to GdkWindow
rather than GtkWindow... The use of self.window.window is confusing and is
still deprecated in Gtk3 so will fix that in following commit.
This reverts commit ccfe6b3c80e054893ae6a626c46be5e3024d8a45.
* Where possible use 'from gtk import ...', i.e. if repeated often or under 10 individual imports.
* Remove osx_check to not show svg. It's only an issue on Windows so should work fine...
* Rearrange and deduplicate code into d.u.g.common for getting pixbuf from files.
* Use 'from gtk.gdk import...' to make it cleaner to apply GTK3 changes in future.
* Move generic icon code from torrent_data_funcs to common.
* Fix pylint import warnings and add WindowsError to pylintrc file.
* A rather disruptive change but for a few reasons such as easier to read,
easier type, keep consistent and javascript code uses single quotes.
* There are a few exceptions for the automated process:
* Any double quotes in comments
* Triple double quotes for docstrings
* Strings containing single quotes are left e.g. "they're"
* To deal with merge conflicts from feature branches it is best to follow
these steps for each commit:
* Create a patch: `git format-patch -1 <sha1>`
* Edit the patch and replace double quotes with single except those in
comments or strings containing an unescaped apostrophe.
* Check the patch `git apply --check <patchfile>` and fix any remaining
issues if it outputs an error.
* Apply the patch `git am < <patchfile>`
* Merge in pylint 1.6.4 rcfile changes.
* Add future_builtins to redefined-builtins-modules ignore list. (should be pylint default!)
- Removed pylint disable comments from files.
* Rearrange disable section, comments must be at start of line but can be
interspersed to highlight categories.
* Conventions enabled:
wrong-import-position
wrong-import-order
This commit is a rewrite of larger parts of the console code. The
motivation behind the rewrite is to cleanup the code and reduce code
duplication to make it easier to understand and modify, and allow any
form of code reuse. Most changes are to the interactive console, but
also to how the different modes (BaseMode subclasses) are used and set
up.
* Address [#2097] - Improve match_torrent search match:
Instead of matching e.g. torrent name with name.startswith(pattern)
now check for asterix at beginning and end of pattern and search
with startswith, endswith or __contains__ according to the pattern.
Various smaller fixes:
* Add errback handler to connection failed
* Fix cmd line console mixing str and unicode input
* Fix handling delete backwards with ALT+Backspace
* Fix handling resizing of message popups
* Fix docs generation warnings
* Lets not stop the reactor on exception in basemode..
* Markup for translation arg help strings
* Main functionality improvements:
- Add support for indentation in formatting code in popup messages (like help)
- Add filter sidebar
- Add ComboBox and UI language selection
- Add columnsview to allow rearranging the torrentlist columns
and changing column widths.
- Removed Columns pane in preferences as columnsview.py is sufficient
- Remove torrent info panel (short cut 'i') as the torrent detail view
is sufficient
* Cleanups and code restructuring
- Made BaseModes subclass of Component
- Rewrite of most of basic window/panel to allow easier code reuse
- Implemented better handling of multple popups by stacking popups. This
makes it easier to return to previous popup when opening multiple popups.
* Refactured console code:
- modes/ for the different modes
- Renamed Legacy mode to CmdLine
- Renamed alltorrent.py to torrentlist.py and split the code into
- torrentlist/columnsview.py
- torrentlist/torrentsview.py
- torrentlist/search_mode.py (minor mode)
- torrentlist/queue_mode.py (minor mode)
- cmdline/ for cmd line commands
- utils/ for utility files
- widgets/ for reusable GUI widgets
- fields.py: Base widgets like TextInput, SelectInput, ComboInput
- popup.py: Popup windows
- inputpane.py: The BaseInputPane used to manage multiple base widgets in a panel
- window.py: The BaseWindow used by all panels needing a curses screen
- sidebar.py: The Sidebar panel
- statusbars.py: The statusbars
- Moved option parsing code from main.py to parser.py
The env variable ESCDELAY specifies the time in ms which ncurses waits
for a character sequence. With a default value of 1000, it produces a
1 second delay when pressing the ESC key to close dialogs.
Set this variable to 0 to get instant respons when pressing ESC.
Add wrapper around the stream passed to the loggers streamhandler
when no log file is specified. Console in interactive mode now
ignores the log output with no logfile specified.
* Testing the torrent with other bencode libs doesn't raise exceptions
so just revert the 'small fix' applied in b193d87499.
* Add BTFailure exception so bdecode issue can be caught in deluge code.
* Move Private label to Trackers Tab.
* Move Owner to Options Tab with a future plan for a dropdown box
to change ownership.
* Put the torrent status message into the progress bar.
* Remove duplicate Shared label in Details Tab.
* Details Tab allow more horizontal room for long folder paths
and fix horizontal scrolling.
* Use print function
* Fix except as statements
* Remove old twisted 8 code
* Remove empty docstring
* Refactor try statement to only contain the relevant import and
disable pylint import msgs.
* Use flake8 noqa and pylint comment and drop pyflakes workarounds.
The builtin cmp() and the __cmp__() special method is no longer used in Python 3, instead we use functools.total_ordering decorator and the __lt__/__eq__ special methods to get the same effect.
* Replace the uses of long with int.
* Replace im_func with __func__ as it has been provided for Python 3 forward-compatibility.
* Fix next/__next__ for Python 3 compatibility.
* Remove the long number literal
* Ensure freespace() returns int
To make the code more Python 3 compatible, I've made a few changes to how we handle keys() or iterkeys() calls on dictionaries. All functionality should remain the same.
* Remove the use of .keys() or .iterkeys() when iterating through a dictionary.
* Remove the use of .keys() when checking if key exists in dictionary.
* Replace dict.keys() with list(dict) to obtain a list of dictionary keys. In Python 3 dict.keys() returns a dict_keys object, not a list.
* Use markup in gtkui to reduce font size of displayed units.
* Reduced statusbar item sizes using markup and <small> tag. Provides an
interim solution to #1326 and has reduced width from 930px to ~600px.
* Integer value for Progress bar value in Peers and Files Tabs.
* Remove trailing zeros for Pieces size in Details Tab.
* Change position of Share Ratio in Status Tab.
* Increase minimum width of column from 10px to 20px for listview.
* Use shortform units e.g. Columns, Title speed, Status tab, Status bar.
* Use less precision displaying values in columns.
* libtorrent >= 1.1 dropped support for GeoIP so this adds support
again using MaxMind GeoIP Legacy Python Extension API.
For reference it is known by the following package names:
* Maxmind: geoip-api-python
* Linux: python-geoip
* PyPi: GeoIP
* #2133 Add flags for port reuse and disable binding to system port.
* #2122 For random port, use single port and store it for reuse.
* #2343 Fix 'Invalid Arg' from listen_on, likely due to whitespace as interface value.
* Consolidate listen_on and outgoing_port into single '__set...' methods.
* Copy-pasting from web page can include extra space at end of string.
* Also make minor change to populate the magnet name with infohash
for nicer UI display.
* Ensure all file descriptors are closed. Using the with statement ensures
closure.
* The main problem was with thousands of unclosed file desciptors from
tracker_icons mkstemp.
* Use a prefix 'deluge_ticon.' to identify created tracker_icon tmp files.
When installed to the system, not using .app, error is raised on startup
as nsapp_open_file is ignoring Deluge-bin but not deluge or deluge-gtk for
potential 'filename' when connecting NSApplicationOpenFile.
Due to the nature of passing a command and args to cmd.exe and then
to a batch file in Windows any ampersands in execute args need to be
double-escaped so prefixing with tripe-caret (^^^&) is the fix for this.
* The main fix here is adding os.environ to the command call otherwise in some configurations
the extraction would fail. Was unable to reproduce locally but users confirm this fix works.
* Refactored the code to properly report errors if the extract command fails along with actual
command output.
* Bump version to 0.5.
* Testcases in test_torrent.py and test_torrentmanager.py creates
components and should therefore inherit from BaseTestCase.
* Cleanup in test_json_api.py
Current solution for passing arguments to UI when invoking deluge
entry script is to select an UI with the --ui option and supply quoted
arguments with the --args option.
This patch cleans this up by removing both options and change to using
subparsers for valid UIs. All command line options are now parsed
directly by the child UI which is chosen by a positional argument,
i.e. the UI name.
The help text now also shows the current default UI.
To avoid unnecessarily importing modules from gtkui.py, move Gtk
console entry point class to __init__.py. This reduces load time
when showing help (deluge -h) with many hundred miliseconds
Also cleanup unnecessary WebUI code.
* To help user's encountering a blank web page, log warnings if script
files for a selected mode are missing and attempt to fallback to a working mode.
* There is no logging for dev version detection to prevent spamming output.
* Add slimit dependency to tox
By combining the background-* css styles into background it overrides background
settings in ext-all-notheme.css resulting in incorrect placement of grid header gif.
- Any plugins that were started before the WebUI plugin would not be loaded
upon starting the web server and would be not show up. The fix is to use
web.pluginmanager.start to get all enabled plugins from core.
- Update log message output for enable/disable in pluginmanager
This fixes the display of which plugins are currently running. The old
code was returned a list of enabled plugins containing WebUI code so
switched to calling the entire list of a plugins from core.
Also updated the docstring in json api to reflect actual usage.
- Reduced height from 575px to 495px
- Low resolution screen users (600px high) will be unable to click
the add button with a dialog height of >550px. Keeping the height
to less than 500px leaves more room for large size themes.
There is some discrepency between pep8 and pylint for line
continuation (https://github.com/PyCQA/pylint/issues/747) but
with some minor layout changes both can pass and code looks fine,
if not better in places.
commit 1a2ff9b089cd2 introduced a bug when loading GTKUI
column states due to changing ListViewColumnState class type.
Fixed by reverting ListViewColumnState to old style class
The daemon status is not retrieved when showing the connection manager at
startup on Windows and shows it as offline.
This commit restores the removal of simulate call in commit 058b0e41d2
but applies it only to Windows OS as there were no problems in Ubuntu testing.
It would suggest then that the issue is isolated to PortableGtkReactor
but the exact cause of the problem is still unknown.
For some reason errors are logged by twisted as
'Unhandled error in Deferred', but without a following
stacktrace. This can happen in a deferred callback that e.g.
raises an ImportError. Without an excplicit error handler for a
deferred to log such errors, finding the error can be very tricky.
Fix this by using a custom twisted.python.log.PythonLoggingObserver,
PythonLoggingObserver, that also logs the traceback in addition to
the error message.
When specifying the --base option to work with reverse proxy
the WebUI is no longer accessible locally since it listens
on the server root, but serves on the path specified to work
for the reverse proxy.
Change this to also handle local requests to the base path
such that the WebUI will be available both for the reverse proxy
as well as locally on the interface/port which the twisted sever
listens on.
In GTKUI standalone mode, WebApi.enable would try to connect to
daemon if web.conf had the 'default_daemon' option set, causing
the client calls to break.
Fix by leaving shutdown procedure to gtkui.py:
* Daemon no longer calls component.shutdown() in GTKUI classic mode
* Mainwindow no longer calls reactor.stop but instead fires a
'gtkui_close' signal.
* gtkui.py installs custom SIGINT handler to initiate shutdown before
stopping reactor.
This should fix problems with errors occuring when failing to
enable plugins. Errors in plugin handling are handled better
and properly logged.
WebUI plugin in particular had issues when being enabled and disabled
multiple times because it was trying to create DelugeWeb component
each time it was enabled. If deluge-web is already listening on
the same port, enabling the WebUI plugin will fail, and the checkbox
will not be checked.
There are still some issues when enabling/disabling plugins by
clicking fast multiple times on the checkbox.
Add --profile to commonoptions making the option now available for
daemon and all UIs. --profile option now prints to stdout unless an
optional filename is specified.
Add entry points into setup for each of the UIs and then use this
information to determine which client UI to run.
This ensures that custom UIs may be written and run without
the need to modifify deluge source code.
Handle child args and -a args in a common way so that all children
accept the same input format. Modify UIs to pass through setup
arguments to the base class.
Instead of launching the UI directly launch the UI via the _UI
subclasses in the same way that the scripts launch the clients.
The only use of the ui.UI class is a base for Web which never calls
__init__ and at the beginning when choosing which UI to launch,
however that doesn't need to be an object.
* pylintrc is now compatible with pylint 1.6.
* Add to ignore wrong-import-position and wrong-import-order as
we use isort and pylint is raising too many incorrect messages.
* Replace Popen with reactor.spawnProcess and read process
output with twisted.internet.protocol.ProcessProtocol
* Implement support for running custom script code
* Now logs to stdout instead of stderr when not logging to file
Exceptions raised by calls performed by a JSON request would
not always be handled properly resulting in no reply to be sent
leading to browser timeouts.
Fix this by including the raised error in the JSON data of a
regular (successful) HTTP response.
For some reason, the time.sleep calls in the tests in
test_sessionproxy did not sleep for the expected amount
of time causing the results to differ from the expected.
Fixed by replacing time.time function with twisted's
task.clock.seconds and advancing the clock manually.
Also minor changes to test_client.py
Add __str__ to WrappedException so that the stacktrace is printed when a
unit test raises a WrappedException.
Change the log output from error to warning in DelugeRPCProtocol.dispatch
when sending back a raised exception on an RPC request.
With large amounts of torrents, saving the state file becomes
a performance bottleneck, mainly due to the required processing
in pickle.dump. When run in the main thread, the server will
hang and be unresponsive for a significant time.
Solve this issue by running the save state job in a separate thread.
* Replace weak hashing functions, key sizes, and random number
generation techniques with less weak versions to prevent
crashes when running with the fips module loaded.
* Can't see any issue removing the twisted similate call and it
seems to already be done by gtk2reactor so duplicated.
* The gnome die handled never appears to be called and most signals
are handled by twisted so remove this code as well.
* Fix for pluginmanager multiple inheritance which in this case is using super incorrectly.
* Explicitly disable pylint 'pointless-except' and 'super-on-old-class' that prospector
tool somehow runs.
* Make __all__ a tuple to supress pep257 warning.
* Add a noqa for older versions of pyflakes.
Selected Warning messages disabled in pylintrc:
* unused-argument: Quite a large and disruptive change if enabled.
* broad-except: Most required in-depth investigation to determine type.
* fixme: Not important
* protected-access: Complicated to fix
* import-error: Too many false-positives
* unidiomatic-typecheck: Should be fixed in the next round of checks.
* unused-variable: Again large and disruptive changes.
* global-statement: Most usage is required.
* attribute-defined-outside-init: Should be fixed in next round of checks.
* arguments-differ: Possible false-positives, needs revisited.
* no-init, non-parent-init-called, super-init-not-called: False-positives?
* signature-differs: False-positives?
Disabled Conventions messages:
* missing-docstring: Not likely all methods/funcs will ever have docstrings.
* invalid-name: Far too many too fix so will simply have to ensure submitted
or altered code keeps to the convention.
* old-style-class: Not a priority but would be nice to eventually fix this.
* bad-continuation: Occasionally conflicts with pep8, not worth enabling if using
pyflakes and pep8 as these will catch most continuation issues.
* Include a pylintrc config file
* This commit provides a basic error-only pylint config as a starting
point with a view to adding more checks incrementally to keep the volume
of changes low and the code able to pass pylint at each stage.
* Further whitespace fixes by autopep8
* Using pep8 v1.6.2 (not currently used by pyflakes)
* Update config for pep8 and flake8 in tox.ini
* A separate pep8 entry for running autopep8. The ignores prevent
blank lines being added after docstrings.
* .tox and E133 are ignored in flake8 by default.
Previously, the process for uploading a file in the Web-UI required three
steps. Click 'File' to open the 'Add from File' window. Click 'Browse' to
select the file. Finally, click 'Add' to upload the file. These steps have
been combined into one, making the process much easier. Now, clicking 'File'
opens the file browser directly. After a file is selected, it is uploaded
automatically.
* The paused state of torrents is now correctly stored on shutdown if the session is paused.
* Resume session refreshes all the torrents' state. This fixes only torrents that changed state being
updated so queued torrents would be incorrectly displayed as paused.
* bundle_contents now appends 'Contents' without adding it twice.
* Remove reference to non-existent gdk-pixbuf.loaders
* Separate libtorrent in new module.
* Update lib versions for bundle file.
* New message box popup if VC 2008 Redist package not detected.
* Add Start Menu page to choose where/if to install items.
* Add desktop shortcut install option to finish page.
* Clean up spacing and use consistent 4 spaces to indent.
* Exclude as many unneeded pygame libraries as possible.
* Webui will try to use debug files if deluge version contains 'dev'.
* Include webui debug files in sdist.
* Use exclude_package_data to remove debug files in release versions.
* Modify `git archive` to include all source code so that creating a
release source tarball is now done with `setup.py sdist` which uses the
MANIFEST.in file to determine files to be included.
By removing the components after they shut down, KeyErrors are raised when
trying to acccess the component. Unit tests now clear the component registry
on tear down.
* version.py script requires git tags but detached HEAD in travis clone
requires manually creating the RELEASE-VERSION.
* Also fix relative path issue building docs.
* In setup.py put web and deluged back into console_script as the gtkui hack in
bbfreeze is a windows only issue for popup cmd windows showing.
* Altered the bbreeze script to find any deluge scripts in pythonpath.
* Use setIcon now in bbfreeze and use icon from package.
* Use version stamp from pywin32.
* Create a 'minified' gettext.js by removing comments from file and simplifying js code.
* Added creating the file to generate_pot.py, so it is not forgotten about.
* Update path for ignoreing tests directory.
* The deluge-all and ext-extensions source code should not be ignored.
* Remove entries for non-existent build script and debug js files.
* Ignore the new packaging directory.
* Remove labelSeparator and manually add ':' so text matches gtk translations.
* Use consistent quotes around strings. This can affect gettext script picking up
marked strings.
* Added the equivalent deffered translation as gtkui for Filters and Progressbar
The status strings were incorrectly marked for translation which when combined with
some translations using 'connected' and 'online' as the same word resulted in
users being unabe to connect to running daemon.
* Removed translation markup from json_api but left as original capitalised word in
case other third-party scripts do comparison on these status strings.
* Added translation markup prior to displaying ConnectionManager using template.
* Reworded password prompt and added translation markup.
* Update gettext.js
Display settings for the WebUI are persisted using cookies created by
Ex.state.CookieProvider. When no expiration date is provided, a default
value of (now + 7 days) is used. This causes display settings to be
lost frequently.
This fix adds an 'expires' parameter with a value of (now + 10 years).
This change does not affect the lifespan of the session cookie, which
is created by a separate system.
The order of the js files matters when minifying.
* Use the '.order' files to put specified files top of the file list.
* Sub-directory files inserted in list before root directory files.
* Sort everything else alphabetically for consistant ordering.
With xgettext set to python it will parse the comments in javascript files, so
single apostrophes or quotes are flagged as 'warning: untermined string'.
This change just rewrites js comments to not use apostrophes.
Removing multiple torrents with remove_torrents will be faster
than calling remove_torrent for each torrent, as the state file
will be written only once, after all the torrents are deleted.
Use a context manager to wrap the common steps:
1) disconnect the treestore from the listview
2) disable treestore sorting
3) add rows (different in add dialog vs files tab)
4) enable treestore sorting
5) connect model to listview
* Added custom trial reporter for TODO with test example in test_torrentmanager.py
* Set Stats plugin tests as todo
* Disable new_release_check when running unit tests
* Added pytest.mark.slow to test_core.test_test_listen_port
* Get rid of unit test warnings (Caused by bad names in test classes)
* Removed warnings.filterwarnings in test files.
* Added separate tox target for generating test coverage HTML report.
* component registry shutdown() now cleans up the component list
this ensures that no old components are left when running unit
tests.
* Added class BaseTestCase that all tests that create components
should inherit from. It verifies the compoent list before and
after the tests are run.
This issue was caused by an unclean shutdown of Deluge, usually on system shutdown, and upon rebooting
the PID stored in the lockfile is in used by another process thus the lockfile is never removed. It
affects users with Deluge set in startup applications as the PIDs are more likely to be reused.
* Lockfile is removed if Deluge is restarted in IPC.
* Renamed the old_tempfile variable to make it clearer as to it's role.
* Removed unused mock dep
* Modified flake8 to run entire codebase (fixed exclude)
* Change isort to shows files that need attention (no diff)
* Uniform layout for tox.ini
* Change flake8 complexity to 15
Targets:
* Runs the unit-tests for python 2.7
* Tests unit-test coverage
* Try to build docs
* Code style checks:
* flake8
* isort
Codes changes:
* Fixed tests for httpdownloader (using tmp dir)
* Implemented a couple of tests for Stats plugin but they fail to run on travis
Issues:
* Can't get py26 to work because of installing libtorrent through apt and
the option system_site_packages fails for 2.6.
* Tabs can now be scrolled if too many for height.
* Change window_pane_position default to 235, based on default 480 window height.
* Set the vpaned size before show call.
* Reduce top padding and set bottom padding to 2, to account for decender letters.
* Added N802 to flake8 ignore as certain inherited funcs cannot be changed
to lowercase and this unresolved warning hides other errors/warnings.
* Include new header
* Changed variable names to be less confusing.
* Flake8'd.
* Move the 'count' to a separate render cell.
* Reduced size of expander icon to make it less intrusive.
* Enabled ellipsis on labels so count is still visible.
* Used pango markup on cell labels and count.
* No longer set a fixed colour to fix#1193.
* Remove duplicate entry in init.
* Call update if empty config and prevent potential loop in update method.
* Ensure that the queue Add button is sensitive, even when automatically adding.
* Remove unnessary page headers to save space
* Reordered pages to be lightly grouped
* Other changes to utilise space better
* Fixed the plugin info panel collapsing on startup
* Changed layout of Status, Details and Options tabs.
* Moved the Tracker translations to ui.common.
* Created a new Trackers tab.
* Added State to progressbar.
* Translate State in piecesbar.
* Status key tracker can be empty so use tracker_host instead, also tracker_host
is nicely formatted.
* Remove unneeded tracker_host string from tracker_status.
* Replace pause_all and resume_all with pause_session and resume_session
* Pausing all the torrents individually loses the original paused status
so use the libtorrent session pause instead.
* Added a SessionPausedEvent to the method.
* Replaced the deprecated use of torrent status save_path with download_location.
* UIs now use 'Download Folder', replaces 'Save Path', 'Download Path', '... Storage', etc.
* Will show/highlight a file path in system file manager. *nix uses dbus with an xdg_open fallback.
* [GTKUI] Open Folder still opens the download location but now shows the torrent data file/folder
* [GTKUI] Files_tab now has a second menu item 'Show' to show a file's location
* The open_file and show_file functions now use timestamps on *nix so that windows open in front, this fixes recent desktop changes that prevent windows randomly stealing focus.
* Removed utf8 decode for Windows. All paths should be unicode
string, any resulting errors should be traced to source and corrected.
This negates the need for quoting a single command with an arg e.g.
deluge-console del --remove_data torrrent_file
Multiple commands separated by semi-colon still require quoting.
* Add error_statusmsg to TorrentState
* Adds a new set_error_statusmsg() method to force torrent error state.
* Any torrent in error state will remain in that state on restart with
additional message in status.
* Any new libtorrent errors will override manually set ones.
When magnet metadata is received a torrent file will also be written
to 'copy of' location if requested.
Modified the code for saving torrent file to state in Torrent class for
use by TorrentManager.
* Using Shift+Del will now pre-select removing files.
* Will now show the name of the individual torrent being removed or the
total count if multiple torrents selected.
Uses attr Torrent.moving_storage for now but can be replaced with
future lt1.0 status field.
Refactored the code to use the common.TORRENT_STATE list.
Added a translating dict to ui.common to aid translation of state text.
json.dumps attempts to decode (utf8) the 'path' entry which had a
alternative encoding. The solution is to ensure the 'path' entry is
utf8 encoded and remove the unneeded 'path.utf-8' entry.
As self.__m_metadata["info"]["files"] is updated the later code
checking and decoding the 'path' entry can be removed.
When adding a torrent already in session any new trackers are merged
to the exiting torrent but this is an unwanted feature for private
flagged torrents.
Created a generic password dialog and moved the unlock code out of
systemtray so any call to window.present will now show the dialog.
Also fixed the appindicator not showing the correct visible status
This adds a new OtherDialog to dialogs so that will use Deferred to prevent
the dialog loop locking up the mainwindow.
Remove old `Other` dialog from common and cleanup up the file.
Fixes#2401, context menus for torrents not showing current value.
Fixes#2400, add a stop_at_ratio context menu.
Change the protocol rate to display as int.
Updated Sphinx conf and tested with Sphinx 1.2.1
Moved webui gen_gettext script
Fixed docstring warning in code
Renamed console update-tracker to update_tracker
On Mavericks the application path passed to scripts only has single leading slash
compared to previous double slash.
Renamed and changed shebang to bash to prevent any issues.
Updated README to rst format for display in trac wiki.
Rename 'Seeders' to 'Seeds'
Hide seconds from fdate unless wanted
'Last Seen Complete' renamed to 'Complete Seen'
Added columns and status for Completed date
Rename 'Seeders/Peers' to 'Seeds:Peers'
For translation added colon to WebUI status strings to match GTK
Compact allocation is deprecated and a new pre-allocation is available.
Any torrents already using compact will continue to do so but any newly
added only can use sparse (default) or allocate options.
The UIs have been updated to only display a checkbox in preferences for
the user to enable 'Pre-allocate disk space'.
This ensures that only ip addresses are accepted for
listen_interface as libtorrent cannot accept interface
names (eth0) and will cause unexpected results for user.
By design alert.msg will be empty if the error code is '-1' so use
a.e.message() to get the message as fallback. It was not used at
replacement because when error code is not '-1' then a.e.message()
will also include the error code, which we do not want.
The delete-text event was triggered when setting the text in the text entry.
The completion popup was then displayed when it shouldn't. Fixed by blocking
the signal while setting the text.
A 3rd party plugin broke because using _() in core files so reverting
to prevent issues and may also be useful in future for translating
the help text.
Changing translation tested and works on:
* Windows 7
* OSX 10.8
* Ubuntu 13.04
* Updated the OSX menubar to gtkbuilder
* Added language names to the Language dropdown in Preferences
* Fix for #1885 (Wrong tracker icon in torrent list)
* Moved the data functions from torrentview/listview into
torrentview_data_funcs.py
* Added caching the current value of the cell renderer for the data functions
* Reordered if-tests in deluge.common.fsize
* Disable data funcs when column is hidden
Having a LoopingCall for each torrent is expencive with a lot of torrents.
The LoopingCall in torrent.py has been moved to torrentmanager.py
which runs through all the torrents and calls cleanup_prev_status.
* All state files have a backup created before saving
* The backup will now be used if saving or loading fails
* GTKUI state files stored in new gtkui_state dir and common load/save functions created
* Detects bad shutdown and archives timestamped state files in separate config directory.
There is an issue with the Label plugin where a new label would 'disappear'
and you could not change the options for the new label with zero hits hidden.
Fixes bug introduced in 5cd86aa5bcbd246f4ed6b4bed026cd72045304a3 where the diff
argument passed to torrentmanager.torrents_status_update is always False
instead of the value passed into get_torrents_status. This causes the sessionproxy
not to function properly which in turn increases CPU usage in the UIs.
cell_data_trackericon would load the tracker icon with
gtk.gdk.pixbuf_new_from_file_at_size each time it's requested.
These regular requests acumulating to thousands calls to
pixbuf_new_from_file_at_size with a big torrent list.
Now, read the tracker icon from disk once, and cache it.
Replaced some try/except-decoding with decode_string.
Removed redundant methods ti_name and apply_options.
In decode_string - changed last encoding (with ignore) from
chardet-detected to the encoding specified in key-argument.
* Implemented torrent updates with libtorrent post_torrent_updates.
This required some changes to how core/torrenthandler
handles get_torrent_status
* Reworked how torrent.py handles torrent info
* Removed some unneeded RPC message requests from client.
* Added tests for some expensive log prints.
set_prioritize_first_last is rewritten for better performance, and is now only called when necessary. It should now properly set the priority for the beginning and end of each file in the torrent.
bbfreeze script:
* Creates a VERSION.tmp file for use by nsis script
* Includes all theme, icon and locale files. Closes#2096 & #2145
* Add email.mime.multipart and email.mime.text. Closes#2074
* deluged.exe and deluge-web.exe will no longer show a cmd window and created
deluged-debug.exe and deluge-web-debug.exe as replacements if still needed
* Overridden bbfreeze gtk recipe thus no longer requiring file editing.
* Remove unnecessary python module includes
nsis script:
* Deluge version now based upon bbfreeze output
* Installer will warn if deluge already running. Closes#1217
* Removed deluged and deluge-web shortcuts from start menu
* Increased compression level for lzma
Using get_current_folder() in the file chooser will use the default folder when a folder path has been typed into the Location field rather than selected with mouse. The solution is to replace it with get_filename().
Conflicts:
deluge/ui/gtkui/addtorrentdialog.py
Found this in the trac
http://dev.deluge-torrent.org/ticket/1858
description:
This patch adds a command to deluge-console to show and set per-torrent options. I have called the command "torrent_option" and mostly modeled it on the "config" command. A better name for the command would be nice, but I have no better suggestion at this time.
Added a quick line to let the user know to user the up & down arrows when adding a host[it isn't as intuitive as you might think]
Using tab to switch input fields when adding a host is something that *should* be added in the future… [more intuitive]
Change .clear() to -> .erase() should eliminate flicker issues.
I'm unsure whether I should've changed line 105 of popup.py.. we can revert if there is any issues.
Note: we only want to erase() during refreshes, if we are changing modes we do want to clear() the screen(at least I think we do… it might make sense to just use erase() everywhere for consistency… I/we should look into this)
This commit updates help information when you run `help info`. We inform user of Tab Completion, and of `info *`.
There is also some removal of duplicate information(no need for line about `info -s <state>` since we tell the user that when they read the option about '-s')
Implemented a protocol layer above twisted.internet.protocol.Protocol
which guarantees correct transfer of RPC messages. The network messages
are transfered with a header containing the length of the message.
Using the setproctitle module the process name displayed in top
and other places will correctly reflect the binary name. This is an
optional dependency
Found an additional glade object from the previous instance of Autoadd
calling cb_get_config resulting in an exceptions.AttributeError.
This workaround simply checks that get_widget is not None.
Disabled options and remove for filters No Label and All
Removed All from torrent menu
Fixed No Label not working in torrent menu
Bumped version to 0.2
When first loading webui is browser this.style is undefined and p.style
contains the width of the progress column however after this point
p.style contains the width of the previous column so need to use
this.style which now represents the progress column width.
Added Download,Uploaded,Down Limit, Up Limit & Seeder/Peeds. Also selected
columns start out hidden to match gtkui and the name column has a minimum
width of 150.
There are numerous fixes to the framework between 3.1.1 and 3.4.0 and
since there are no obvious bugs introduced it's only sensible to pull
the update in to the stable branch
* Implemented whitelist support to both core and GTK UI.
* Implemented ip filter cleaning before each update. Restarting the deluge
daemon is no longer needed.
* If "check_after_days" is 0(zero), the timer is not started anymore. It would
keep updating one call after the other. If the value changed, the timer is
now stopped and restarted using the new value.
File priorities stored in torrent options were based upon the supplied
funtion values rather than the current values stored in libtorrent. So
if the priorities failed to be set by libtorrent the settings would be
out of sync.
The script for generating the gettext.js file was outdated and needed
a fix to work with the newer layout of the javascript source code, it
was still looking for Deluge.Something files which no longer exist.
When dynamically loading the content panels in the details panel they
would sometimes look quite bad since the only font they have been
told to use is verdana. Fix this why using the same as extjs.
The fix specifically applied to on_alert_save_resume_data by moving function call str(alert.handle.info_hash()) into the try statement. For completeness any calls to str(alert.handle.info_hash()) also moved into try statements.
This probably broke some behaviour because converting and splitting from libglade to GtkBuilder is not as perfect as it should be. What I noticed was fixed.
Also, GtkBuilder only allow calling `connect_signals()` once. Some code had to change to handle this and a "handlers proxy class" was created to keep the behaviour we had, ie, connect signals from where it was needed. Then I monkey patch the main windows GtkBuilder to not allow anyone to connect signals through it since it would break behaviour. Connecting signals to the main window builder instance is now done like `component.get("MainWindow").connect_signals()`. The best solution will probably break the main window ui into the needed parts in order to not have to monkey patch main windows builder.
Plugin's trying to get the main windows `main_glade` are now broken, on purpose, ie, the code they have needs to change since the calls to the builder are not the same as the calls to libglade. The plugins we ship with deluge will be fix as soon as possible.
Removing a column from the treeview on shutdown causes all the
column widths to be zero which are saved to the state file.
The workaround is to not save the state file if all columns are zero.
Support progress information when creating torrents remotely. For this to be possible, a method was added to the `RPCServer`, `emit_event_for_session_id()`, which does exactly what is says. This is needed because the event created, `CreateTorrentProgressEvent` needs to be addressed to a single session id, not all session ids interested in that event.
Fixed a bug that apparently was not found yet. When creating torrents locally, we defer that task to a thread. Since this thread updates UI widgets, namely the progress bar info and since we can't guarantee that it's the main thread, updating the widgets must be done by calling `gobject.iddle_add()`.
Additionally creating a torrent and saving it on a remote path now mimics the behaviour on doing it locally. Need to evaluate to see if it's possible to also show a progress when doing this remotely as now, the progress is only seen when doing it locally.
The speedups work is being separated into 2 different phases and possibly branches. The idea is to have this minimal speedup merged into master as soon as possible since it's pretty simple. Reduces initial data transfer to about 10% of what was previously being transfered when client connected.
The second phase is regarding row updates, ie, reduce them to what's actually being seen. This part is way more tricky.
When a plugin is enabled, disabled and then enabled again, on that second enable, that instance is being garbage collected causing the loading of the plugin to fail. Work around that until we can narrow down why is this is happening on the second enable.
Two more commands were added to setup.py:
* develop_plugins - Installs each of the plugins in development mode
* egg_info_plugins - Create the '.egg-info' distribution directories for each plugin. This will make the plugin discoverable by deluge
Both these commands are intended to be used while developing deluge.
Translations are now setup on `deluge.common`. Where they used to be setup, a call to `setup_translations(setup_pygtk=False)` is now made.
Every call to `pkg_resources.resource_filename()` is now made through `deluge.common.resource_filename` to make sure that we're loading data from the right deluge install.
While developing, if there's a second deluge package, installed globally and another in develop mode somewhere else, while pkg_resources.require("Deluge") returns the proper deluge instance, pkg_resources.resource_filename does not, it returns the first found on the python path, which is not good enough. Work around this issue.
Since the plugins namespace was merged into master, calling "logging.getLogger(__name__)" will result in a properly named logger for plugins which will allow logging filtering.
The previous workaround "getPluginLogger()", is now deprecated.
Implement a pre-filter for the search-box which will filter the currently visible torrents while waiting for the filter request to sent to the demon. This will make the searches seem way faster :)
Now, instead of permanently having a search box to filter the visible torrents by name, we now, mimic a toolbar just for that, mapped to CTRL-F. There's also a menu item in the "View" menu and a toolbar icon to toggle it. Implemented "Match Case" for the search.
When adding new entries, the dialog is auto-filled with what's defined for the Downloads entry in the preferences.
When showing errors, use the dialogs module.
Added some tooltips to the dialog.
In console the warning "g_object_set_qdata: assertion `G_IS_OBJECT (object)' failed" will appear. Quick investigation could find no solution with suggestions a python issue.
The right-click torrent menu would move/jump around when the option submenu was opened with the mouse, possibly due to a conflict between glade file and append menuitem code in menubar.py. Solution was to create a menuitem entry for Change Owner in glade file and update code to add submenu to this new entry.
The drawings made on the pieces bar are now cached in "sub-drawings" kept in memory. If no data has changed, those "sub-drawings" are used. If data changed, redraw whatever is necessary.
We now provide an option to the user to see the states of a torrent's pieces, ie, completed, downloading, waiting, missing.
If the user has this option enabled, another 3 will be shown to him(on the GTK UI), which will allow him to choose the colors for each piece state.
While adding the multiuser auth related stuff, RPC_AUTH_EVENT was added, simply to not touch how RPC_ERROR was handled. It was created to allow recreating the exception on the client side. Instead of adding another rpc event type, extend RPC_ERROR to send the proper data to recreate the exception on the client side.
Add magnet mimetype and tryexec key
Fix exec key to handle files and urls to conform with new desktop-entry spec
Update name, comment and category keys
We now upgrade the core's config to include 'sequential_download'.
On the auto add plugin, if there are no watchdir, provide a default that will allow the GTK UI not to thrown an exception.
Now `set_prioritize_first_last()` sets the first 2% and the last 2% of the pieces of each file on a torrent at a high priority, ie, it no longer works on just single file torrents.
Remove some un-necessary `lt.version_minor` checks since these checks will remain for a while, at least until deluge depends on libtorrent >= 0.16 which should preferrably not happen.
Update last_seen_complete when a status is queried for and that key is on the keys to get or it's a full status query. Either way, only "calculate" last seen at a minimum of one time per 60 seconds(simple caching).
Warn the user if he's trying to connect to a local daemon that's not running and "start local daemon if necessary" is not enabled.
Extend and reuse the connection callbacks on the connection manager to re-use code.
When connected to a client, and then trying to connect to another, the connection manager component will be stopped(while the connect deferred is still running), so, the ConnectionManager.connection_manager reference will be deleted. If that's not the case, close the dialog.
Auto-connecting on start of the gtk ui is now fully working.
Auto-staring localhost if needed is now also working.
Authentication failures now get passed correctly to the client implementation which will allow the user to enter username and/or password to complete authentication.
It's now possible to shutdown the daemon from the connection manager even if not on localhost, it just needs all required information to be present on the liststore.
Auto-connecting to daemon now works. Fixes#1815.
Auto-starting a `localhost` daemon now also works, the reconnecting attempts were not being "triggered".
When not connected to a daemon, "Quit & Shutdown Daemon" is not present. So #1818 is also fixed.
Some more work regarding #1819 was done.
Client now disconnects before shutting down the GTK UI.
Moved some auth stuff to `deluge.common` because they're also used on the GTK UI.
Now, if a user starts deluge in classic mode and tries to change it to client/daemon mode, he see's a dialog stating that the current session will be stopped. If he answers no, nothing is done, the classic mode pref is set back as it was. If he answers yes, all components are stopped and client is disconnected. At this stage the user can open the connection manager to start the daemon and connect.
If the user starts in client/daemon mode and switches to classic mode he see's a dialog stating that deluge must be restarted.
The GTK UI connection manager now loads it's default config with the localclient username and password. If not present in the auth file, the auth file will be recreated.
All test were adapted, and some more were added to comply with the new multiuser support in deluge.
Regarding #1814, host entries in the Connection Manager UI are now migrated from the old format were automatic localhost logins were possible, which no longer is.
On the core, the code was not adapted to the new AuthManager. On The GtkUI, nothing was being shown to the user when errors occurred while changing ownership.
Account management is now implemented for the GTK UI. Some changes to the core were required since the clients need to know which authentication levels exist, and, to expose account creation, update, and removal to the clients. The best effort is done to try not to compromise the auth file.
Implement tooltips on treeview's headers when adding columns.
Renamed the "public" state of a torrent to "shared", ie, shared among other deluge users. Allow changing shared state from clients and currently from the GtkUi.
Now, calling connect on client has two behaviours, if username/password is passed the client connects, authenticates and returns daemon info, if username/password is not passed, only the daemon info is returned. This might change a bit later on though.
It also asks for a password prior to attemting to connect in case the password is null, this alows host entries not to store the passwords on file like it has done so far.
NOTE: This is not yet the desired behaviour, ie, the daemon should simply complain if the authentication details are incomplete and the client should act accordingly. I had an issue with this though, I catched the errback the daemon was sending, asked the user for the password and re-tried to authenticate again. However, twisted always locked when I tried this. I'm investigating it.
We now make sure that a state file exists when trying to restore an order from it.
The best effort to restore the previous order is made, though, in some cases, since we're matching against names which are translatable, a match might not be found, in that case, continue the effort though skip the non matching column name. On next load, everything should be fine since the state file will include the, now in use, translation.
On the TorrentView's treeview, the column's position stored on state was being ignored, but event if that info was not being ignored and passed to the several `add_column`'s the order could not be added because the order the columns are added does not(might not) match what was stored in state. So, we now restore the ordering once all columns are added.
Passing `-r` to the cli's while also passing `-l` will make the logfile rotate when reaching 5Mb in size. Three backups will be kept at all times.
All deluge's code is now using this new style logging along with the git hosted plugins. For other plugins not hosted by deluge, which still imports `LOG` as the logger, a deprecation warning will be shown explaining the required changes needed to use the new style logging. New plugins created by the `create_plugin` script will use the new logging facilities.
The caching of state filters has been removed to simplify things a bit. This shouldn't have too much
impact since the torrent status requests are still using diffs.
rename Deluge.Torrent to Deluge.data.Torrent
add new file Deluge.data.Peer that contains records in the Peers grid
add a singleton that contains sort functions
Blinks might need some changes because, there's no need to formar or gather extra info, so, it might not be needed to allow plugin developers to register custom handlers for it.
d="M 23.942923,0.9561338 L 37.330543,18.266721 C 46.998995,29.84687 41.49692,43.923891 26.7742,45.000491 C 6.0597413,45.582655 6.5086231,27.37483 11.255313,18.609381 L 23.942923,0.9561338 z "
d="M 35.111358,26.143133 C 28.972772,13.030586 17.560684,17.697957 17.274449,26.949974 C 16.894738,39.223415 34.748874,37.615429 36.715244,41.468778 C 28.821643,47.675479 14.973233,45.226508 10.962289,39.715204 C 6.9574776,34.212326 7.2383598,25.630263 10.784249,19.587632 C 24.158625,0.978654 39.749127,24.383766 35.111358,26.143133 z "
d="M 23.996861,3.5433428 L 36.057351,19.151045 C 44.769741,29.58253 39.419346,42.414092 26.125181,43.508521 C 7.3917365,44.015286 7.4275065,28.119221 12.17284,20.333442 L 23.996861,3.5433428 z "
d="M 23.940758,0.96491709 L 34.727367,14.909752 C 42.647208,24.392311 40.447304,20.283975 28.362481,21.278846 C 25.083165,11.203805 18.13871,11.859899 13.523802,15.675236 L 23.940758,0.96491709 z "
d="M 35.159701,26.173667 C 29.021115,13.06112 18.734027,17.978491 18.447792,27.230508 C 18.068081,39.503949 34.797217,37.645963 36.763587,41.499312 C 28.869986,47.706013 15.021576,45.257042 11.010632,39.745738 C 7.0058197,34.24286 7.2867027,25.660797 10.832592,19.618166 C 24.206968,1.0091879 39.79747,24.4143 35.159701,26.173667 z "
d="M 35.120795,26.14195 C 28.553327,12.814962 15.685968,17.224233 15.399733,26.47625 C 15.020022,38.749691 32.874158,37.141705 34.840528,40.995054 C 26.946927,47.201755 13.098517,44.752784 9.0875727,39.24148 C 5.0827617,33.738602 5.3636437,25.156539 8.9095327,19.113908 C 22.315509,0.47615954 40.03233,23.660113 35.120795,26.14195 z "
d="M 792.51261,596.13496 C 1787.1961,462.38583 1788.2786,460.03989 1788.2786,460.03989 L 2050.3447,889.51678 C 1692.1626,1024.6476 1428.8778,1128.1462 1119.6165,1246.9702 L 792.51261,596.13496 z"
d="M 792.51261,596.13496 C 1787.1961,462.38583 1788.2786,460.03989 1788.2786,460.03989 L 2050.3447,889.51678 C 1692.1626,1024.6476 1428.8778,1128.1462 1119.6165,1246.9702 L 792.51261,596.13496 z"
d="M 792.51261,596.13496 C 1787.1961,462.38583 1788.2786,460.03989 1788.2786,460.03989 L 2050.3447,889.51678 C 1692.1626,1024.6476 1428.8778,1128.1462 1119.6165,1246.9702 L 792.51261,596.13496 z"
d="M 335.10794,116.43168 L 610.53935,447.76408 C 809.45408,669.41324 696.25675,938.85368 393.35753,959.46028 C -32.813273,970.60316 -9.7709676,623.52458 107.82928,464.31364 L 335.10794,116.43168 z"
d="M 337.67292,165.87552 L 585.22638,464.67366 C 773.96211,684.57988 653.37942,910.02774 383.88559,930.97978 C 4.1291863,940.68143 29.040179,639.21796 125.2355,490.1649 L 337.67292,165.87552 z"
d="M 359.0208,369.47132 C 289.64507,437.53055 219.98727,505.41409 150.61154,573.47313 C 187.93874,573.54143 225.35922,573.40503 262.68661,573.47313 C 262.68661,654.06643 262.68661,734.65974 262.68661,815.25304 C 329.00806,815.25304 395.32971,815.25304 461.65134,815.25304 C 461.65134,734.86969 461.65134,654.48632 461.65134,574.10276 C 496.04273,574.16582 530.52013,574.0399 564.91152,574.10276 C 496.30183,505.79126 427.63028,437.78301 359.0208,369.47132 z"
d="M 1211.4629,48.95108 L 1486.8943,380.28348 C 1685.809,601.93264 1572.6117,871.37308 1269.7125,891.97968 C 843.5417,903.12256 866.584,556.04398 984.1842,396.83304 L 1211.4629,48.95108 z"
d="M 1214.0279,98.39492 L 1461.5813,397.19306 C 1650.317,617.09928 1529.7344,842.54714 1260.2405,863.49918 C 880.4842,873.20083 905.3951,571.73736 1001.5905,422.6843 L 1214.0279,98.39492 z"
d="M 1235.158,785.66485 C 1165.4485,716.69801 1095.4555,647.90922 1025.7459,578.94258 C 1063.2527,578.87336 1100.8533,579.01159 1138.3603,578.94258 C 1138.3603,497.27453 1138.3603,415.60647 1138.3603,333.93841 C 1205.0008,333.93841 1271.6416,333.93841 1338.2823,333.93841 C 1338.2823,415.39371 1338.2823,496.84903 1338.2823,578.30455 C 1372.8392,578.24065 1407.4825,578.36825 1442.0394,578.30455 C 1373.0995,647.52701 1304.0976,716.44219 1235.158,785.66485 z"
d="M 335.10794,116.43168 L 610.53935,447.76408 C 809.45408,669.41324 696.25675,938.85368 393.35753,959.46028 C -32.813273,970.60316 -9.7709676,623.52458 107.82928,464.31364 L 335.10794,116.43168 z"
d="M 337.67292,165.87552 L 585.22638,464.67366 C 773.96211,684.57988 653.37942,910.02774 383.88559,930.97978 C 4.1291863,940.68143 29.040179,639.21796 125.2355,490.1649 L 337.67292,165.87552 z"
style="font-size:1091.49255371px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;opacity:1;fill:#ff7878;fill-opacity:1;stroke:#000000;stroke-width:13.65081787;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Bitstream Vera Sans"
x="20.453644"
y="1303.4996"
id="text2767"
transform="scale(1.4928735,0.6698491)"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan2769"
x="20.453644"
y="1303.4996"
style="font-size:1091.49255371px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;stroke-width:13.65081787;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;font-family:Bitstream Vera Sans">!</tspan></text>
d="M 23.942923,0.9561338 L 37.330543,18.266721 C 46.998995,29.84687 41.49692,43.923891 26.7742,45.000491 C 6.0597413,45.582655 6.5086231,27.37483 11.255313,18.609381 L 23.942923,0.9561338 z"
d="M 23.996861,3.5433428 L 36.057351,19.151045 C 44.769741,29.58253 39.419346,42.414092 26.125181,43.508521 C 7.3917365,44.015286 7.4275065,28.119221 12.17284,20.333442 L 23.996861,3.5433428 z"
style="font-size:55.97062302px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;opacity:1;fill:#ff7878;fill-opacity:1;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Bitstream Vera Sans"
xml:space="preserve"><tspan
style="font-size:55.97062302px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;font-family:Bitstream Vera Sans"
d="M 23.854535,1.0445221 L 37.242155,18.355109 C 46.910607,29.935258 41.408532,44.012279 26.685812,45.088879 C 5.971353,45.671043 6.4202348,27.463218 11.166925,18.697769 L 23.854535,1.0445221 z"
d="M 23.996861,3.5433428 L 36.057351,19.151045 C 44.769741,29.58253 39.419346,42.414092 26.125181,43.508521 C 7.3917365,44.015286 7.4275065,28.119221 12.17284,20.333442 L 23.996861,3.5433428 z"
d="M 23.854535,1.0445221 L 37.242155,18.355109 C 46.910607,29.935258 41.408532,44.012279 26.685812,45.088879 C 5.971353,45.671043 6.4202348,27.463218 11.166925,18.697769 L 23.854535,1.0445221 z"
d="M 23.996861,3.5433428 L 36.057351,19.151045 C 44.769741,29.58253 39.419346,42.414092 26.125181,43.508521 C 7.3917365,44.015286 7.4275065,28.119221 12.17284,20.333442 L 23.996861,3.5433428 z"
d="M 24.821384,15.512309 C 22.21433,17.952223 19.604921,20.381297 16.997867,22.821211 C 18.304685,22.818964 19.61477,22.823457 20.921589,22.821211 C 20.921589,25.684801 20.921589,28.548391 20.921589,31.411981 C 19.61477,31.409734 18.304685,31.414228 16.997867,31.411981 C 19.604921,33.851895 22.21433,36.280969 24.821384,38.720883 C 27.457552,36.289986 30.104432,33.865368 32.740602,31.43447 C 31.322226,31.432031 29.900305,31.43691 28.481929,31.43447 C 28.481929,28.555887 28.481929,25.677306 28.481929,22.798722 C 29.900305,22.796282 31.322226,22.80116 32.740602,22.798722 C 30.104432,20.367823 27.457552,17.943206 24.821384,15.512309 z"
d="M 23.942923,0.9561338 L 37.330543,18.266721 C 46.998995,29.84687 41.49692,43.923891 26.7742,45.000491 C 6.0597413,45.582655 6.5086231,27.37483 11.255313,18.609381 L 23.942923,0.9561338 z"
d="M 23.996861,3.5433428 L 36.057351,19.151045 C 44.769741,29.58253 39.419346,42.414092 26.125181,43.508521 C 7.3917365,44.015286 7.4275065,28.119221 12.17284,20.333442 L 23.996861,3.5433428 z"
d="M 24.3125,14.9375 C 20.869248,18.315409 17.412003,21.684591 13.96875,25.0625 C 15.821373,25.065889 17.678627,25.059111 19.53125,25.0625 C 19.53125,29.0625 19.53125,33.0625 19.53125,37.0625 C 22.822917,37.0625 26.114582,37.0625 29.40625,37.0625 C 29.40625,33.072917 29.40625,29.083333 29.40625,25.09375 C 31.113161,25.096872 32.824339,25.090627 34.53125,25.09375 C 31.126025,21.703313 27.717725,18.327937 24.3125,14.9375 z"
d="M 23.942923,0.9561338 L 37.330543,18.266721 C 46.998995,29.84687 41.49692,43.923891 26.7742,45.000491 C 6.0597413,45.582655 6.5086231,27.37483 11.255313,18.609381 L 23.942923,0.9561338 z"
d="M 23.996861,3.5433428 L 36.057351,19.151045 C 44.769741,29.58253 39.419346,42.414092 26.125181,43.508521 C 7.3917365,44.015286 7.4275065,28.119221 12.17284,20.333442 L 23.996861,3.5433428 z"
d="M 19.34375,17.5625 C 19.34375,21.552083 19.34375,25.541668 19.34375,29.53125 C 17.636839,29.528128 15.925661,29.534372 14.21875,29.53125 C 17.623975,32.921687 21.032275,36.297063 24.4375,39.6875 C 27.880752,36.309591 31.337996,32.94041 34.78125,29.5625 C 32.928627,29.559111 31.071373,29.565889 29.21875,29.5625 C 29.21875,25.5625 29.21875,21.562501 29.21875,17.5625 C 25.927083,17.5625 22.635418,17.562501 19.34375,17.5625 z"
d="M 335.10794,116.43168 L 610.53935,447.76408 C 809.45408,669.41324 696.25675,938.85368 393.35753,959.46028 C -32.813273,970.60316 -9.7709676,623.52458 107.82928,464.31364 L 335.10794,116.43168 z"
d="M 337.67292,165.87552 L 585.22638,464.67366 C 773.96211,684.57988 653.37942,910.02774 383.88559,930.97978 C 4.1291863,940.68143 29.040179,639.21796 125.2355,490.1649 L 337.67292,165.87552 z"
d="M 170.93275,447.12091 C 174.01359,451.92804 181.6932,659.85017 179.71907,656.9136 C 178.40947,654.12718 411.7223,649.25335 412.30092,648.76646 C 411.08134,648.85003 338.31478,584.63588 338.93986,585.53435 C 410.72174,567.77973 462.65633,588.73801 481.03861,645.01437 C 484.19544,690.33553 466.3409,711.71891 434.77285,736.14895 C 385.89389,754.17146 322.59241,745.84878 312.37017,673.09575 C 312.32389,674.48492 156.52907,675.28833 153.0572,676.51233 C 202.03372,799.5504 269.9646,882.62913 421.73005,870.01325 C 463.0283,867.02946 568.27041,836.89042 606.41655,717.64626 C 627.84208,623.51263 596.80367,549.4096 547.34944,496.26853 C 457.7753,416.4389 296.11292,421.8444 245.11698,507.64417 C 247.55313,508.23771 173.58263,449.35852 170.93275,447.12091 z"
d="M 23.942923,0.9561338 L 37.330543,18.266721 C 46.998995,29.84687 41.49692,43.923891 26.7742,45.000491 C 6.0597413,45.582655 6.5086231,27.37483 11.255313,18.609381 L 23.942923,0.9561338 z "
d="M 35.111358,26.143133 C 28.972772,13.030586 17.560684,17.697957 17.274449,26.949974 C 16.894738,39.223415 34.748874,37.615429 36.715244,41.468778 C 28.821643,47.675479 14.973233,45.226508 10.962289,39.715204 C 6.9574776,34.212326 7.2383598,25.630263 10.784249,19.587632 C 24.158625,0.978654 39.749127,24.383766 35.111358,26.143133 z "
d="M 23.996861,3.5433428 L 36.057351,19.151045 C 44.769741,29.58253 39.419346,42.414092 26.125181,43.508521 C 7.3917365,44.015286 7.4275065,28.119221 12.17284,20.333442 L 23.996861,3.5433428 z "
d="M 23.940758,0.96491709 L 34.727367,14.909752 C 42.647208,24.392311 40.447304,20.283975 28.362481,21.278846 C 25.083165,11.203805 18.13871,11.859899 13.523802,15.675236 L 23.940758,0.96491709 z "
d="M 35.159701,26.173667 C 29.021115,13.06112 18.734027,17.978491 18.447792,27.230508 C 18.068081,39.503949 34.797217,37.645963 36.763587,41.499312 C 28.869986,47.706013 15.021576,45.257042 11.010632,39.745738 C 7.0058197,34.24286 7.2867027,25.660797 10.832592,19.618166 C 24.206968,1.0091879 39.79747,24.4143 35.159701,26.173667 z "
d="M 35.120795,26.14195 C 28.553327,12.814962 15.685968,17.224233 15.399733,26.47625 C 15.020022,38.749691 32.874158,37.141705 34.840528,40.995054 C 26.946927,47.201755 13.098517,44.752784 9.0875727,39.24148 C 5.0827617,33.738602 5.3636437,25.156539 8.9095327,19.113908 C 22.315509,0.47615954 40.03233,23.660113 35.120795,26.14195 z "
d="M 337.34641,113.574 L 612.77782,444.9064 C 811.69255,666.55556 698.49522,935.996 395.596,956.6026 C -30.5748,967.74548 -7.5325,620.6669 110.06775,461.45596 L 337.34641,113.574 z"
d="M 339.91139,163.01784 L 587.46485,461.81598 C 776.20058,681.7222 655.61789,907.17006 386.12406,928.1221 C 6.36766,937.82375 31.27865,636.36028 127.47397,487.30722 L 339.91139,163.01784 z"
d="M 362.09611,847.31541 C 292.72038,779.25618 223.06258,711.37264 153.68685,643.3136 C 191.01405,643.2453 228.43453,643.3817 265.76192,643.3136 C 265.76192,562.7203 265.76192,482.12699 265.76192,401.53369 C 332.08337,401.53369 398.40502,401.53369 464.72665,401.53369 C 464.72665,481.91704 464.72665,562.30041 464.72665,642.68397 C 499.11804,642.62091 533.59544,642.74683 567.98683,642.68397 C 499.37714,710.99547 430.70559,779.00372 362.09611,847.31541 z"
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.