mirror of
https://github.com/freedomofpress/dangerzone.git
synced 2025-04-28 09:52:37 +02:00
Add UpdaterThread class
Add a new Python module called "updater", which contains the logic for prompting the user to enable updates, and checking our GitHub releases for new updates. This class has some light dependency to Qt functionality, since it needs to: * Show a prompt to the user, * Run update checks asynchronously in a Qt thread, * Provide the main window with the result of the update check Refs #189
This commit is contained in:
parent
0ad489f80b
commit
5ae8b871b6
5 changed files with 468 additions and 47 deletions
263
dangerzone/gui/updater.py
Normal file
263
dangerzone/gui/updater.py
Normal file
|
@ -0,0 +1,263 @@
|
|||
"""A module that contains the logic for checking for updates."""
|
||||
|
||||
import logging
|
||||
import platform
|
||||
import sys
|
||||
import time
|
||||
import typing
|
||||
from typing import Any, Optional
|
||||
|
||||
from packaging import version
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
from PySide2 import QtCore
|
||||
else:
|
||||
try:
|
||||
from PySide6 import QtCore
|
||||
except ImportError:
|
||||
from PySide2 import QtCore
|
||||
|
||||
import markdown
|
||||
import requests
|
||||
|
||||
from ..util import get_version
|
||||
from .logic import Alert, DangerzoneGui
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# TODO: Create a wiki page that explains how updates work for Dangerzone, before
|
||||
# merging this.
|
||||
MSG_CONFIRM_UPDATE_CHECKS = """\
|
||||
<p>Do you want to be notified about new Dangerzone releases?</p>
|
||||
|
||||
<p>If <i>"Yes"</i>, Dangerzone will check GitHub for new releases on startup. If
|
||||
<i>"No"</i>, Dangerzone will make no network requests and won't inform you about new
|
||||
releases.</p>
|
||||
|
||||
<p>If you prefer another way of getting notified about new releases, we suggest adding
|
||||
to your RSS reader our
|
||||
<a href="https://fosstodon.org/@dangerzone.rss">Mastodon feed</a>. For more information
|
||||
about updates, check our
|
||||
<a href="https://github.com/freedomofpress/dangerzone/wiki/Updates">wiki page</a>.</p>
|
||||
"""
|
||||
|
||||
UPDATE_CHECK_COOLDOWN_SECS = 60 * 60 * 12 # Check for updates at most every 12 hours.
|
||||
|
||||
|
||||
class UpdateReport:
|
||||
"""A report for an update check."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
version: Optional[str] = None,
|
||||
changelog: Optional[str] = None,
|
||||
error: Optional[str] = None,
|
||||
):
|
||||
self.version = version
|
||||
self.changelog = changelog
|
||||
self.error = error
|
||||
|
||||
def empty(self) -> bool:
|
||||
return self.version is None and self.changelog is None and self.error is None
|
||||
|
||||
|
||||
class UpdaterThread(QtCore.QThread):
|
||||
"""Check asynchronously for Dangerzone updates.
|
||||
|
||||
The Updater class is mainly responsible for the following:
|
||||
|
||||
1. Asking the user if they want to enable update checks or not.
|
||||
2. Determining when it's the right time to check for updates.
|
||||
3. Hitting the GitHub releases API and learning about updates.
|
||||
|
||||
Since checking for updates is a task that may take some time, we perform it
|
||||
asynchronously, in a Qt thread. This thread then triggers a signal, and informs
|
||||
whoever has connected to it.
|
||||
"""
|
||||
|
||||
finished = QtCore.Signal(dict)
|
||||
|
||||
GH_RELEASE_URL = (
|
||||
"https://api.github.com/repos/freedomofpress/dangerzone/releases/latest"
|
||||
)
|
||||
|
||||
def __init__(self, dangerzone: DangerzoneGui):
|
||||
super().__init__()
|
||||
self.dangerzone = dangerzone
|
||||
|
||||
###########
|
||||
# Helpers for updater settings
|
||||
#
|
||||
# These helpers make it easy to retrieve specific updater-related settings, as well
|
||||
# as save the settings file, only when necessary.
|
||||
|
||||
@property
|
||||
def check(self) -> Optional[bool]:
|
||||
return self.dangerzone.settings.get("updater_check")
|
||||
|
||||
@check.setter
|
||||
def check(self, val: bool) -> None:
|
||||
self.dangerzone.settings.set("updater_check", val, autosave=True)
|
||||
|
||||
def prompt_for_checks(self) -> bool:
|
||||
"""Ask the user if they want to be informed about Dangerzone updates."""
|
||||
log.debug("Prompting the user for update checks")
|
||||
# FIXME: Handle the case where a user clicks on "X", instead of explicitly
|
||||
# making a choice. We should probably ask them again on the next run.
|
||||
check = Alert(
|
||||
self.dangerzone,
|
||||
message=MSG_CONFIRM_UPDATE_CHECKS,
|
||||
ok_text="Yes",
|
||||
cancel_text="No",
|
||||
).launch()
|
||||
return bool(check)
|
||||
|
||||
def should_check_for_updates(self) -> bool:
|
||||
"""Determine if we can check for updates based on settings and user prefs.
|
||||
|
||||
Note that this method only checks if the user has expressed an interest for
|
||||
learning about new updates, and not whether we should actually make an update
|
||||
check. Those two things are distinct, actually. For example:
|
||||
|
||||
* A user may have expressed that they want to learn about new updates.
|
||||
* A previous update check may have found out that there's a new version out.
|
||||
* Thus we will always show to the user the cached info about the new version,
|
||||
and won't make a new update check.
|
||||
"""
|
||||
log.debug("Checking platform type")
|
||||
# TODO: Disable updates for Homebrew installations.
|
||||
if platform.system() == "Linux" and not getattr(sys, "dangerzone_dev", False):
|
||||
log.debug("Running on Linux, disabling updates")
|
||||
self.check = False
|
||||
return False
|
||||
|
||||
log.debug("Checking if first run of Dangerzone")
|
||||
if self.dangerzone.settings.get("updater_last_check") is None:
|
||||
log.debug("Dangerzone is running for the first time, updates are stalled")
|
||||
self.dangerzone.settings.set("updater_last_check", 0, autosave=True)
|
||||
return False
|
||||
|
||||
log.debug("Checking if user has already expressed their preference")
|
||||
if self.check is None:
|
||||
log.debug("User has not been asked yet for update checks")
|
||||
self.check = self.prompt_for_checks()
|
||||
return self.check
|
||||
elif not self.check:
|
||||
log.debug("User has expressed that they don't want to check for updates")
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def can_update(self, cur_version: str, latest_version: str) -> bool:
|
||||
if version.parse(cur_version) == version.parse(latest_version):
|
||||
return False
|
||||
elif version.parse(cur_version) > version.parse(latest_version):
|
||||
# FIXME: This is a sanity check, but we should improve its wording.
|
||||
raise Exception("Received version is older than the latest version")
|
||||
else:
|
||||
return True
|
||||
|
||||
def _get_now_timestamp(self) -> int:
|
||||
return int(time.time())
|
||||
|
||||
def _should_postpone_update_check(self) -> bool:
|
||||
"""Consult and update cooldown timer.
|
||||
|
||||
If the previous check happened before the cooldown period expires, do not check
|
||||
again.
|
||||
"""
|
||||
current_time = self._get_now_timestamp()
|
||||
last_check = self.dangerzone.settings.get("updater_last_check")
|
||||
if current_time < last_check + UPDATE_CHECK_COOLDOWN_SECS:
|
||||
log.debug(f"Cooling down update checks")
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def get_latest_info(self) -> UpdateReport:
|
||||
"""Get the latest release info from GitHub.
|
||||
|
||||
Also, render the changelog from Markdown format to HTML, so that we can show it
|
||||
to the users.
|
||||
"""
|
||||
try:
|
||||
# TODO: Set timeout.
|
||||
info = requests.get(self.GH_RELEASE_URL).json()
|
||||
except Exception as e:
|
||||
# TODO:: Handle errors.
|
||||
raise
|
||||
|
||||
version = info["tag_name"].lstrip("v")
|
||||
changelog = markdown.markdown(info["body"])
|
||||
|
||||
return UpdateReport(version=version, changelog=changelog)
|
||||
|
||||
# XXX: This happens in parallel with other tasks. DO NOT alter global state!
|
||||
def _check_for_updates(self) -> UpdateReport:
|
||||
"""Check for updates locally and remotely.
|
||||
|
||||
Check for updates in two places:
|
||||
|
||||
1. In our settings, in case we have cached the latest version/changelog from a
|
||||
previous run.
|
||||
2. In GitHub, by hitting the latest releases API.
|
||||
"""
|
||||
log.debug(f"Checking for Dangerzone updates")
|
||||
latest_version = self.dangerzone.settings.get("updater_latest_version")
|
||||
if version.parse(get_version()) < version.parse(latest_version):
|
||||
log.debug(f"Determined that there is an update due to cached results")
|
||||
return UpdateReport(
|
||||
version=latest_version,
|
||||
changelog=self.dangerzone.settings.get("updater_latest_changelog"),
|
||||
)
|
||||
|
||||
# If the previous check happened before the cooldown period expires, do not
|
||||
# check again. Else, bump the last check timestamp, before making the actual
|
||||
# check. This is to ensure that even failed update checks respect the cooldown
|
||||
# period.
|
||||
if self._should_postpone_update_check():
|
||||
return UpdateReport()
|
||||
else:
|
||||
self.dangerzone.settings.set(
|
||||
"updater_last_check", self._get_now_timestamp(), autosave=True
|
||||
)
|
||||
|
||||
log.debug(f"Checking the latest GitHub release")
|
||||
report = self.get_latest_info()
|
||||
log.debug(f"Latest version in GitHub is {report.version}")
|
||||
if report.version and self.can_update(latest_version, report.version):
|
||||
log.debug(
|
||||
f"Determined that there is an update due to a new GitHub version:"
|
||||
f" {latest_version} < {report.version}"
|
||||
)
|
||||
return report
|
||||
|
||||
log.debug(f"No need to update")
|
||||
return UpdateReport()
|
||||
|
||||
##################
|
||||
# Logic for running update checks asynchronously
|
||||
|
||||
def check_for_updates(self) -> UpdateReport:
|
||||
"""Check for updates and return a report with the findings:
|
||||
|
||||
There are three scenarios when we check for updates, and each scenario returns a
|
||||
slightly different answer:
|
||||
|
||||
1. No new updates: Return an empty update report.
|
||||
2. Updates are available: Return an update report with the latest version and
|
||||
changelog, in HTML format.
|
||||
3. Update check failed: Return an update report that holds just the error
|
||||
message.
|
||||
"""
|
||||
try:
|
||||
res = self._check_for_updates()
|
||||
except Exception as e:
|
||||
log.exception("Encountered an error while checking for upgrades")
|
||||
res = UpdateReport(error=str(e))
|
||||
|
||||
return res
|
||||
|
||||
def run(self) -> None:
|
||||
self.finished.emit(self.check_for_updates())
|
|
@ -54,7 +54,7 @@ def main():
|
|||
|
||||
print("* Building RPM package")
|
||||
subprocess.run(
|
||||
f"python3 setup.py bdist_rpm --requires='{platform_dependant_packages},python3-pyside2,python3-appdirs,python3-click,python3-pyxdg,python3-colorama'",
|
||||
f"python3 setup.py bdist_rpm --requires='{platform_dependant_packages},python3-pyside2,python3-appdirs,python3-click,python3-pyxdg,python3-colorama,python3-requests,python3-markdown,python3-packaging'",
|
||||
shell=True,
|
||||
cwd=root,
|
||||
check=True,
|
||||
|
|
243
poetry.lock
generated
243
poetry.lock
generated
|
@ -1,10 +1,9 @@
|
|||
# This file is automatically @generated by Poetry 1.4.1 and should not be changed by hand.
|
||||
# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand.
|
||||
|
||||
[[package]]
|
||||
name = "altgraph"
|
||||
version = "0.17.3"
|
||||
description = "Python graph (network) package"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -16,7 +15,6 @@ files = [
|
|||
name = "appdirs"
|
||||
version = "1.4.4"
|
||||
description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -28,7 +26,6 @@ files = [
|
|||
name = "attrs"
|
||||
version = "22.2.0"
|
||||
description = "Classes Without Boilerplate"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
|
@ -47,7 +44,6 @@ tests-no-zope = ["cloudpickle", "cloudpickle", "hypothesis", "hypothesis", "mypy
|
|||
name = "black"
|
||||
version = "23.1.0"
|
||||
description = "The uncompromising code formatter."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -94,11 +90,105 @@ d = ["aiohttp (>=3.7.4)"]
|
|||
jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
|
||||
uvloop = ["uvloop (>=0.15.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "certifi"
|
||||
version = "2023.5.7"
|
||||
description = "Python package for providing Mozilla's CA Bundle."
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
{file = "certifi-2023.5.7-py3-none-any.whl", hash = "sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716"},
|
||||
{file = "certifi-2023.5.7.tar.gz", hash = "sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "charset-normalizer"
|
||||
version = "3.1.0"
|
||||
description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
|
||||
optional = false
|
||||
python-versions = ">=3.7.0"
|
||||
files = [
|
||||
{file = "charset-normalizer-3.1.0.tar.gz", hash = "sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5"},
|
||||
{file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b"},
|
||||
{file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60"},
|
||||
{file = "charset_normalizer-3.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1"},
|
||||
{file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0"},
|
||||
{file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f"},
|
||||
{file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0"},
|
||||
{file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795"},
|
||||
{file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c"},
|
||||
{file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203"},
|
||||
{file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1"},
|
||||
{file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137"},
|
||||
{file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce"},
|
||||
{file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a"},
|
||||
{file = "charset_normalizer-3.1.0-cp310-cp310-win32.whl", hash = "sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448"},
|
||||
{file = "charset_normalizer-3.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8"},
|
||||
{file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19"},
|
||||
{file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017"},
|
||||
{file = "charset_normalizer-3.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df"},
|
||||
{file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a"},
|
||||
{file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41"},
|
||||
{file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1"},
|
||||
{file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62"},
|
||||
{file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6"},
|
||||
{file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5"},
|
||||
{file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be"},
|
||||
{file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb"},
|
||||
{file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac"},
|
||||
{file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324"},
|
||||
{file = "charset_normalizer-3.1.0-cp311-cp311-win32.whl", hash = "sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909"},
|
||||
{file = "charset_normalizer-3.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755"},
|
||||
{file = "charset_normalizer-3.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373"},
|
||||
{file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab"},
|
||||
{file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9"},
|
||||
{file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f"},
|
||||
{file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28"},
|
||||
{file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d"},
|
||||
{file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d"},
|
||||
{file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d"},
|
||||
{file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6"},
|
||||
{file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84"},
|
||||
{file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c"},
|
||||
{file = "charset_normalizer-3.1.0-cp37-cp37m-win32.whl", hash = "sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974"},
|
||||
{file = "charset_normalizer-3.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23"},
|
||||
{file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531"},
|
||||
{file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c"},
|
||||
{file = "charset_normalizer-3.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14"},
|
||||
{file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb"},
|
||||
{file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1"},
|
||||
{file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b"},
|
||||
{file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0"},
|
||||
{file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649"},
|
||||
{file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326"},
|
||||
{file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11"},
|
||||
{file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b"},
|
||||
{file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd"},
|
||||
{file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8"},
|
||||
{file = "charset_normalizer-3.1.0-cp38-cp38-win32.whl", hash = "sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0"},
|
||||
{file = "charset_normalizer-3.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59"},
|
||||
{file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e"},
|
||||
{file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31"},
|
||||
{file = "charset_normalizer-3.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f"},
|
||||
{file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e"},
|
||||
{file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f"},
|
||||
{file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854"},
|
||||
{file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706"},
|
||||
{file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e"},
|
||||
{file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0"},
|
||||
{file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230"},
|
||||
{file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7"},
|
||||
{file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e"},
|
||||
{file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f"},
|
||||
{file = "charset_normalizer-3.1.0-cp39-cp39-win32.whl", hash = "sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1"},
|
||||
{file = "charset_normalizer-3.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b"},
|
||||
{file = "charset_normalizer-3.1.0-py3-none-any.whl", hash = "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "click"
|
||||
version = "8.1.3"
|
||||
description = "Composable command line interface toolkit"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -114,7 +204,6 @@ importlib-metadata = {version = "*", markers = "python_version < \"3.8\""}
|
|||
name = "colorama"
|
||||
version = "0.4.6"
|
||||
description = "Cross-platform colored terminal text."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
|
||||
files = [
|
||||
|
@ -126,7 +215,6 @@ files = [
|
|||
name = "coverage"
|
||||
version = "7.2.2"
|
||||
description = "Code coverage measurement for Python"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -193,7 +281,6 @@ toml = ["tomli"]
|
|||
name = "cx-freeze"
|
||||
version = "6.13.2"
|
||||
description = "Create standalone executables from Python scripts"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
|
@ -250,7 +337,6 @@ test = ["nose (==1.3.7)", "pygments (>=2.11.2)", "pytest (>=7.0.1)", "pytest-cov
|
|||
name = "cx-logging"
|
||||
version = "3.1.0"
|
||||
description = "Python and C interfaces for logging"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -281,7 +367,6 @@ files = [
|
|||
name = "exceptiongroup"
|
||||
version = "1.1.1"
|
||||
description = "Backport of PEP 654 (exception groups)"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -296,7 +381,6 @@ test = ["pytest (>=6)"]
|
|||
name = "execnet"
|
||||
version = "1.9.0"
|
||||
description = "execnet: rapid multi-Python deployment"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
files = [
|
||||
|
@ -307,11 +391,21 @@ files = [
|
|||
[package.extras]
|
||||
testing = ["pre-commit"]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "3.4"
|
||||
description = "Internationalized Domain Names in Applications (IDNA)"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
files = [
|
||||
{file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"},
|
||||
{file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "importlib-metadata"
|
||||
version = "6.1.0"
|
||||
description = "Read metadata from Python packages"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -332,7 +426,6 @@ testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packag
|
|||
name = "iniconfig"
|
||||
version = "2.0.0"
|
||||
description = "brain-dead simple config-ini parsing"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -344,7 +437,6 @@ files = [
|
|||
name = "isort"
|
||||
version = "5.11.5"
|
||||
description = "A Python utility / library to sort Python imports."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7.0"
|
||||
files = [
|
||||
|
@ -362,7 +454,6 @@ requirements-deprecated-finder = ["pip-api", "pipreqs"]
|
|||
name = "lief"
|
||||
version = "0.12.3"
|
||||
description = "Library to instrument executable formats"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
|
@ -406,7 +497,6 @@ files = [
|
|||
name = "macholib"
|
||||
version = "1.16.2"
|
||||
description = "Mach-O header analysis and editing"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -417,11 +507,27 @@ files = [
|
|||
[package.dependencies]
|
||||
altgraph = ">=0.17"
|
||||
|
||||
[[package]]
|
||||
name = "markdown"
|
||||
version = "3.4.3"
|
||||
description = "Python implementation of John Gruber's Markdown."
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "Markdown-3.4.3-py3-none-any.whl", hash = "sha256:065fd4df22da73a625f14890dd77eb8040edcbd68794bcd35943be14490608b2"},
|
||||
{file = "Markdown-3.4.3.tar.gz", hash = "sha256:8bf101198e004dc93e84a12a7395e31aac6a9c9942848ae1d99b9d72cf9b3520"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""}
|
||||
|
||||
[package.extras]
|
||||
testing = ["coverage", "pyyaml"]
|
||||
|
||||
[[package]]
|
||||
name = "mypy"
|
||||
version = "1.1.1"
|
||||
description = "Optional static typing for Python"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -469,7 +575,6 @@ reports = ["lxml"]
|
|||
name = "mypy-extensions"
|
||||
version = "1.0.0"
|
||||
description = "Type system extensions for programs checked with the mypy type checker."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
files = [
|
||||
|
@ -481,7 +586,6 @@ files = [
|
|||
name = "packaging"
|
||||
version = "23.0"
|
||||
description = "Core utilities for Python packages"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -493,7 +597,6 @@ files = [
|
|||
name = "pathspec"
|
||||
version = "0.11.1"
|
||||
description = "Utility library for gitignore style pattern matching of file paths."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -505,7 +608,6 @@ files = [
|
|||
name = "platformdirs"
|
||||
version = "3.2.0"
|
||||
description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -524,7 +626,6 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.2.2)", "pytest-
|
|||
name = "pluggy"
|
||||
version = "1.0.0"
|
||||
description = "plugin and hook calling mechanisms for python"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
|
@ -543,7 +644,6 @@ testing = ["pytest", "pytest-benchmark"]
|
|||
name = "py"
|
||||
version = "1.11.0"
|
||||
description = "library with cross-python path, ini-parsing, io, code, log facilities"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
files = [
|
||||
|
@ -555,7 +655,6 @@ files = [
|
|||
name = "pyinstaller"
|
||||
version = "5.9.0"
|
||||
description = "PyInstaller bundles a Python application and all its dependencies into a single package."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "<3.12,>=3.7"
|
||||
files = [
|
||||
|
@ -588,7 +687,6 @@ hook-testing = ["execnet (>=1.5.0)", "psutil", "pytest (>=2.7.3)"]
|
|||
name = "pyinstaller-hooks-contrib"
|
||||
version = "2023.1"
|
||||
description = "Community maintained hooks for PyInstaller"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -600,7 +698,6 @@ files = [
|
|||
name = "pyside6"
|
||||
version = "6.4.3"
|
||||
description = "Python bindings for the Qt cross-platform application and UI framework"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "<3.12,>=3.7"
|
||||
files = [
|
||||
|
@ -621,7 +718,6 @@ shiboken6 = "6.4.3"
|
|||
name = "pyside6-addons"
|
||||
version = "6.4.3"
|
||||
description = "Python bindings for the Qt cross-platform application and UI framework (Addons)"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "<3.12,>=3.7"
|
||||
files = [
|
||||
|
@ -641,7 +737,6 @@ shiboken6 = "6.4.3"
|
|||
name = "pyside6-essentials"
|
||||
version = "6.4.3"
|
||||
description = "Python bindings for the Qt cross-platform application and UI framework (Essentials)"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "<3.12,>=3.7"
|
||||
files = [
|
||||
|
@ -660,7 +755,6 @@ shiboken6 = "6.4.3"
|
|||
name = "pytest"
|
||||
version = "7.2.2"
|
||||
description = "pytest: simple powerful testing with Python"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -685,7 +779,6 @@ testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.
|
|||
name = "pytest-cov"
|
||||
version = "3.0.0"
|
||||
description = "Pytest plugin for measuring coverage."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
|
@ -704,7 +797,6 @@ testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtuale
|
|||
name = "pytest-forked"
|
||||
version = "1.6.0"
|
||||
description = "run tests in isolated forked subprocesses"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -720,7 +812,6 @@ pytest = ">=3.10"
|
|||
name = "pytest-mock"
|
||||
version = "3.10.0"
|
||||
description = "Thin-wrapper around the mock package for easier use with pytest"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -738,7 +829,6 @@ dev = ["pre-commit", "pytest-asyncio", "tox"]
|
|||
name = "pytest-xdist"
|
||||
version = "2.5.0"
|
||||
description = "pytest xdist plugin for distributed testing and loop-on-failing modes"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
|
@ -760,7 +850,6 @@ testing = ["filelock"]
|
|||
name = "pywin32"
|
||||
version = "306"
|
||||
description = "Python for Window Extensions"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -784,7 +873,6 @@ files = [
|
|||
name = "pyxdg"
|
||||
version = "0.28"
|
||||
description = "PyXDG contains implementations of freedesktop.org standards in python."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -792,11 +880,31 @@ files = [
|
|||
{file = "pyxdg-0.28.tar.gz", hash = "sha256:3267bb3074e934df202af2ee0868575484108581e6f3cb006af1da35395e88b4"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "requests"
|
||||
version = "2.31.0"
|
||||
description = "Python HTTP for Humans."
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"},
|
||||
{file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
certifi = ">=2017.4.17"
|
||||
charset-normalizer = ">=2,<4"
|
||||
idna = ">=2.5,<4"
|
||||
urllib3 = ">=1.21.1,<3"
|
||||
|
||||
[package.extras]
|
||||
socks = ["PySocks (>=1.5.6,!=1.5.7)"]
|
||||
use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
|
||||
|
||||
[[package]]
|
||||
name = "setuptools"
|
||||
version = "65.7.0"
|
||||
description = "Easily download, build, install, upgrade, and uninstall Python packages"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -813,7 +921,6 @@ testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (
|
|||
name = "shiboken6"
|
||||
version = "6.4.3"
|
||||
description = "Python/C++ bindings helper module"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "<3.12,>=3.7"
|
||||
files = [
|
||||
|
@ -829,7 +936,6 @@ files = [
|
|||
name = "strip-ansi"
|
||||
version = "0.1.1"
|
||||
description = "Strip ANSI escape sequences from a string"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6,<4.0"
|
||||
files = [
|
||||
|
@ -841,7 +947,6 @@ files = [
|
|||
name = "tomli"
|
||||
version = "2.0.1"
|
||||
description = "A lil' TOML parser"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -853,7 +958,6 @@ files = [
|
|||
name = "typed-ast"
|
||||
version = "1.5.4"
|
||||
description = "a fork of Python 2 and 3 ast modules with type comment support"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
|
@ -883,22 +987,56 @@ files = [
|
|||
{file = "typed_ast-1.5.4.tar.gz", hash = "sha256:39e21ceb7388e4bb37f4c679d72707ed46c2fbf2a5609b8b8ebc4b067d977df2"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "types-markdown"
|
||||
version = "3.4.2.9"
|
||||
description = "Typing stubs for Markdown"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "types-Markdown-3.4.2.9.tar.gz", hash = "sha256:0930057bea0a534e06bbc021d57520720ad2a65b363612614ab0599cc7f606a9"},
|
||||
{file = "types_Markdown-3.4.2.9-py3-none-any.whl", hash = "sha256:c23a8a4dd9313539a446ba3dc673a6a920d79580c406de10a5c85a16733890a7"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "types-pyside2"
|
||||
version = "5.15.2.1.3"
|
||||
description = "The most accurate stubs for PySide2"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "types_PySide2-5.15.2.1.3-py2.py3-none-any.whl", hash = "sha256:a1f3e64d248037f426d3542c1cb693fe64fa783f552efba52347cd1a328fe552"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "types-requests"
|
||||
version = "2.31.0.1"
|
||||
description = "Typing stubs for requests"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "types-requests-2.31.0.1.tar.gz", hash = "sha256:3de667cffa123ce698591de0ad7db034a5317457a596eb0b4944e5a9d9e8d1ac"},
|
||||
{file = "types_requests-2.31.0.1-py3-none-any.whl", hash = "sha256:afb06ef8f25ba83d59a1d424bd7a5a939082f94b94e90ab5e6116bd2559deaa3"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
types-urllib3 = "*"
|
||||
|
||||
[[package]]
|
||||
name = "types-urllib3"
|
||||
version = "1.26.25.13"
|
||||
description = "Typing stubs for urllib3"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "types-urllib3-1.26.25.13.tar.gz", hash = "sha256:3300538c9dc11dad32eae4827ac313f5d986b8b21494801f1bf97a1ac6c03ae5"},
|
||||
{file = "types_urllib3-1.26.25.13-py3-none-any.whl", hash = "sha256:5dbd1d2bef14efee43f5318b5d36d805a489f6600252bb53626d4bfafd95e27c"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typing-extensions"
|
||||
version = "4.5.0"
|
||||
description = "Backported and Experimental Type Hints for Python 3.7+"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -906,11 +1044,27 @@ files = [
|
|||
{file = "typing_extensions-4.5.0.tar.gz", hash = "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "urllib3"
|
||||
version = "2.0.3"
|
||||
description = "HTTP library with thread-safe connection pooling, file post, and more."
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "urllib3-2.0.3-py3-none-any.whl", hash = "sha256:48e7fafa40319d358848e1bc6809b208340fafe2096f1725d05d67443d0483d1"},
|
||||
{file = "urllib3-2.0.3.tar.gz", hash = "sha256:bee28b5e56addb8226c96f7f13ac28cb4c301dd5ea8a6ca179c0b9835e032825"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"]
|
||||
secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"]
|
||||
socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
|
||||
zstd = ["zstandard (>=0.18.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "zipp"
|
||||
version = "3.15.0"
|
||||
description = "Backport of pathlib-compatible object wrapper for zip files"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -925,4 +1079,3 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more
|
|||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = ">=3.7,<3.12"
|
||||
content-hash = "6f9d5cf06f7f00efbf05fe3531356e29796538a990ed43f2638541dd66003428"
|
||||
|
|
|
@ -12,6 +12,9 @@ appdirs = "*"
|
|||
PySide6 = "^6.4.1"
|
||||
colorama = "*"
|
||||
pyxdg = {version = "*", platform = "linux"}
|
||||
requests = "*"
|
||||
markdown = "*"
|
||||
packaging = "*"
|
||||
|
||||
[tool.poetry.scripts]
|
||||
dangerzone = 'dangerzone:main'
|
||||
|
@ -31,6 +34,8 @@ black = "*"
|
|||
isort = "*"
|
||||
mypy = "*"
|
||||
types-PySide2 = "*"
|
||||
types-Markdown = "*"
|
||||
types-requests = "*"
|
||||
|
||||
# Dependencies required for testing the code.
|
||||
[tool.poetry.group.test.dependencies]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[DEFAULT]
|
||||
Package3: dangerzone
|
||||
Depends3: podman, python3, python3-pyside2.qtcore, python3-pyside2.qtgui, python3-pyside2.qtwidgets, python3-appdirs, python3-click, python3-xdg, python3-colorama
|
||||
Depends3: podman, python3, python3-pyside2.qtcore, python3-pyside2.qtgui, python3-pyside2.qtwidgets, python3-appdirs, python3-click, python3-xdg, python3-colorama, python3-requests, python3-markdown, python3-packaging
|
||||
Build-Depends: dh-python, python3, python3-setuptools, python3-stdeb
|
||||
Suite: bionic
|
||||
X-Python3-Version: >= 3.6
|
||||
|
|
Loading…
Reference in a new issue