aboutsummaryrefslogtreecommitdiff
path: root/desktop/setup-freeze.py
diff options
context:
space:
mode:
Diffstat (limited to 'desktop/setup-freeze.py')
-rw-r--r--desktop/setup-freeze.py232
1 files changed, 232 insertions, 0 deletions
diff --git a/desktop/setup-freeze.py b/desktop/setup-freeze.py
new file mode 100644
index 00000000..6026a9cd
--- /dev/null
+++ b/desktop/setup-freeze.py
@@ -0,0 +1,232 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""
+OnionShare | https://onionshare.org/
+
+Copyright (C) 2014-2021 Micah Lee, et al. <micah@micahflee.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+"""
+import os
+import sys
+import platform
+import shutil
+import cx_Freeze
+from cx_Freeze import setup, Executable
+
+# There's an obscure cx_Freeze bug that I'm hitting that's preventing the macOS
+# package from getting built. This is some monkeypatching to fix it.
+
+if platform.system() == "Darwin" or platform.system() == "Linux":
+ import importlib_metadata
+ import pathlib
+ from pathlib import Path
+ from tempfile import TemporaryDirectory
+
+ class CustomPackagePath(pathlib.PurePosixPath):
+ def __init__(self, filename):
+ self.long_filename = str(filename)
+ self.short_filename = "/".join(filename.as_posix().split("/")[-2:])
+ super(CustomPackagePath, self).__init__()
+
+ def read_text(self, encoding="utf-8"):
+ with self.locate().open(encoding=encoding) as stream:
+ return stream.read()
+
+ def read_binary(self):
+ with self.locate().open("rb") as stream:
+ return stream.read()
+
+ def locate(self):
+ return Path(self.long_filename)
+
+ def as_posix(self):
+ return self.short_filename
+
+ class DistributionCache(importlib_metadata.PathDistribution):
+ _cachedir = TemporaryDirectory(prefix="cxfreeze-")
+
+ @staticmethod
+ def at(path):
+ return DistributionCache(Path(path))
+
+ at.__doc__ = importlib_metadata.PathDistribution.at.__doc__
+
+ @classmethod
+ def from_name(cls, name):
+ distribution = super().from_name(name)
+ temp_dir = Path(cls._cachedir.name)
+ dist_dir = None
+ files = distribution.files or []
+ prep = importlib_metadata.Prepared(distribution.name)
+ normalized = prep.normalized
+ legacy_normalized = prep.legacy_normalized
+ for file in files:
+ # patch: the onionshare and onionshare_cli files are using absolute paths, which break everything
+ if name in ["onionshare", "onionshare_cli"]:
+ if ".dist-info" not in file.as_posix():
+ continue
+
+ file = CustomPackagePath(file)
+
+ if (
+ not file.match(f"{name}-*.dist-info/*")
+ and not file.match(f"{distribution.name}-*.dist-info/*")
+ and not file.match(f"{normalized}-*.dist-info/*")
+ and not file.match(f"{legacy_normalized}-*.dist-info/*")
+ ):
+ continue
+ src_path = file.locate()
+ if not src_path.exists():
+ continue
+ dst_path = temp_dir / file.as_posix()
+ if dist_dir is None:
+ dist_dir = dst_path.parent
+ dist_dir.mkdir(exist_ok=True)
+ shutil.copy2(src_path, dst_path)
+ if dist_dir is None:
+ raise importlib_metadata.PackageNotFoundError(name)
+ return cls.at(dist_dir)
+
+ from_name.__doc__ = importlib_metadata.PathDistribution.from_name.__doc__
+
+ cx_Freeze.module.DistributionCache = DistributionCache
+
+
+# Discover the version
+with open(os.path.join("..", "cli", "onionshare_cli", "resources", "version.txt")) as f:
+ version = f.read().strip()
+
+
+# Build
+include_files = [(os.path.join("..", "LICENSE"), "LICENSE")]
+
+if platform.system() == "Windows":
+ include_msvcr = True
+ gui_base = "Win32GUI"
+ exec_icon = os.path.join("onionshare", "resources", "onionshare.ico")
+
+elif platform.system() == "Darwin":
+ import PySide2
+ import shiboken2
+
+ include_msvcr = False
+ gui_base = None
+ exec_icon = None
+ include_files += [
+ (
+ os.path.join(PySide2.__path__[0], "libpyside2.abi3.5.15.dylib"),
+ "libpyside2.abi3.5.15.dylib",
+ ),
+ (
+ os.path.join(shiboken2.__path__[0], "libshiboken2.abi3.5.15.dylib"),
+ "libshiboken2.abi3.5.15.dylib",
+ ),
+ ]
+
+elif platform.system() == "Linux":
+ include_msvcr = False
+ gui_base = None
+ exec_icon = None
+
+ if not shutil.which("patchelf"):
+ print("Install the patchelf package")
+ sys.exit()
+
+setup(
+ name="onionshare",
+ version=version,
+ description="Securely and anonymously share files, host websites, and chat with friends using the Tor network",
+ options={
+ # build_exe, for Windows and macOS
+ "build_exe": {
+ "packages": [
+ "cffi",
+ "engineio",
+ "engineio.async_drivers.gevent",
+ "engineio.async_drivers.gevent_uwsgi",
+ "gevent",
+ "jinja2.ext",
+ "onionshare",
+ "onionshare_cli",
+ "PySide2",
+ "PySide2.QtCore",
+ "PySide2.QtGui",
+ "PySide2.QtWidgets",
+ ],
+ "excludes": [
+ "test",
+ "tkinter",
+ "PySide2.Qt3DAnimation",
+ "PySide2.Qt3DCore",
+ "PySide2.Qt3DExtras",
+ "PySide2.Qt3DInput",
+ "PySide2.Qt3DLogic",
+ "PySide2.Qt3DRender",
+ "PySide2.QtCharts",
+ "PySide2.QtConcurrent",
+ "PySide2.QtDataVisualization",
+ "PySide2.QtHelp",
+ "PySide2.QtLocation",
+ "PySide2.QtMultimedia",
+ "PySide2.QtMultimediaWidgets",
+ "PySide2.QtNetwork",
+ "PySide2.QtOpenGL",
+ "PySide2.QtOpenGLFunctions",
+ "PySide2.QtPositioning",
+ "PySide2.QtPrintSupport",
+ "PySide2.QtQml",
+ "PySide2.QtQuick",
+ "PySide2.QtQuickControls2",
+ "PySide2.QtQuickWidgets",
+ "PySide2.QtRemoteObjects",
+ "PySide2.QtScript",
+ "PySide2.QtScriptTools",
+ "PySide2.QtScxml",
+ "PySide2.QtSensors",
+ "PySide2.QtSerialPort",
+ "PySide2.QtSql",
+ "PySide2.QtTest",
+ "PySide2.QtTextToSpeech",
+ "PySide2.QtUiTools",
+ "PySide2.QtWebChannel",
+ "PySide2.QtWebEngine",
+ "PySide2.QtWebEngineCore",
+ "PySide2.QtWebEngineWidgets",
+ "PySide2.QtWebSockets",
+ "PySide2.QtXml",
+ "PySide2.QtXmlPatterns",
+ ],
+ "include_files": include_files,
+ "include_msvcr": include_msvcr,
+ },
+ # bdist_mac, making the macOS app bundle
+ "bdist_mac": {
+ "iconfile": os.path.join("onionshare", "resources", "onionshare.icns"),
+ "bundle_name": "OnionShare"
+ },
+ },
+ executables=[
+ Executable(
+ "package/onionshare.py",
+ base=gui_base,
+ icon=exec_icon,
+ ),
+ Executable(
+ "package/onionshare-cli.py",
+ base=None,
+ icon=exec_icon,
+ ),
+ ],
+)