Merge pull request #486 from lbryio/electron

Electron
This commit is contained in:
Job Evers‐Meltzer 2017-02-21 13:19:55 -06:00 committed by GitHub
commit 04b36e2252
64 changed files with 183 additions and 2629 deletions

View file

@ -1,11 +1,5 @@
version: 1.0.{build} version: 1.0.{build}
environment:
key_pass:
secure: u6DydPcdrUJlxGL9uc7yQRYG8+5rY6aAEE9nfCSzFyNzZlX9NniOp8Uh5ZKQqX7bGEngLI6ipbLfiJvn0XFnhbn2iTkOuMqOXVJVOehvwlQ=
pfx_key:
secure: 1mwqyRy7hDqDjDK+TIAoaXyXzpNgwruFNA6TPkinUcVM7A+NLD33RQLnfnwVy+R5ovD2pUfhQ6+N0Fqebv6tZh436LIEsock+6IOdpgFwrg=
notifications: notifications:
- provider: Slack - provider: Slack
@ -15,51 +9,5 @@ notifications:
clone_folder: c:\projects\lbry clone_folder: c:\projects\lbry
install:
- cmd: dir C:\projects\lbry\packaging\windows\
- ps: .\packaging\windows\init.ps1
- nuget install secure-file -ExcludeVersion
- secure-file\tools\secure-file -decrypt packaging\windows\certs\lbry2.pfx.enc -secret %pfx_key%
- ps: .\packaging\windows\install.ps1
build_script: build_script:
- ps: .\packaging\windows\build.ps1 - echo "Not currently building on appveyor"
test_script:
- ps: .\packaging\windows\test.ps1
artifacts:
- path: dist/*.msi
name: msi
- path: build/exe.win32-2.7/
name: lbry-portable
- path: packaging/windows/lbry-win32-app/LBRY-URI.reg
name: LBRY-URI
deploy:
- provider: GitHub
release: $(APPVEYOR_REPO_TAG_NAME)
description: 'Release'
auth_token:
secure: 28gMVxQkXr2iXP4F+5kVwefUtKCfS1ePZ97PVfaSR8UDupjAvKhSJx862TnEjukb
artifact: /.*\.msi/
draft: false
prerelease: true
on:
appveyor_repo_tag: true # deploy on tag push only
- provider: S3
access_key_id:
secure: E25iHvmHiJP56GWFTe14L3pS8QKb5ZcyWZLY0zqh6BA=
secret_access_key:
secure: YwZe6fCv29akFYjMCCBJBF7LtI6mxPrxbq7SSoAbn1BPdqjATFegeteGAsqHur/C
bucket: lbrynet-master
region: us-west-2
artifact: /.*\.msi/
on:
branch: master

View file

@ -1,5 +1,5 @@
[bumpversion] [bumpversion]
current_version = 0.8.7 current_version = 0.9.0rc6
commit = True commit = True
tag = True tag = True
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)((?P<release>[a-z]+)(?P<candidate>\d+))? parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)((?P<release>[a-z]+)(?P<candidate>\d+))?
@ -7,18 +7,18 @@ serialize =
{major}.{minor}.{patch}{release}{candidate} {major}.{minor}.{patch}{release}{candidate}
{major}.{minor}.{patch} {major}.{minor}.{patch}
[bumpversion:file:lbrynet/__init__.py]
[bumpversion:file:packaging/ubuntu/lbry.desktop]
[bumpversion:part:release] [bumpversion:part:release]
optional_value = production optional_value = production
values = values =
rc rc
production production
[bumpversion:file:lbrynet/__init__.py]
[bumpversion:file:CHANGELOG.md] [bumpversion:file:CHANGELOG.md]
search = [Unreleased] search = [Unreleased]
replace = [Unreleased] replace = [Unreleased]
\#\# [{new_version}] - {now:%Y-%m-%d}
\#\# [{new_version}] - {now:%Y-%m-%d}

View file

@ -1,93 +1,40 @@
matrix: os: linux
include: dist: trusty
- os: linux language: python
sudo: required python: 2.7
dist: trusty
# dh-virtualenv requires that we use the same python interpreter
# that comes with the system, so we don't want to use anything that
# travis would try to set-up for us in python
language: generic
- os: osx
# Use generic language for osx
# python 2.7 is broken on osx on travis, so follow we have to specify the installation ourselves
# https://github.com/travis-ci/travis-ci/issues/2312#issuecomment-195620855
language: generic
osx_image: xcode7.3
notifications: notifications:
slack: slack:
secure: "Am13HPtpgCMljh0MDVuoFHvQXB8yhf4Kvf/qAeSp5N0vsHGL70CSF9Ahccw8dVPE6mbuak1OGtSUb6/UaErLHkpz3ztaRLkDa9x7CmBB3Kynnh8oO2VbB7b/2ROULqkhF4VZmAnNfwrQrbC3gs8Sybp261Nyc7y4ww15xDYBrk2fyq4ds2DCaJdRxfJUJFonrZ6KXr3fVaXosO6cjuyS8eRodcmrqsT4cCtinjNTD1hGWoH107E4ObSmpVelxQO193KhNJMRiLlEcVkvYUOqIWBtwdGHbNE/6Yeuq1TXgKJ0KeJWAmW3wTfUYNngGXNAsyCnrhul5TKNevNzfIAQZHvRsczYiWPJV6LtohHT0CcUiCXJtvEPOyahEBfwK3etY/xxFqny7N9OEmpdW2sgsEPNPX2LJynJti2rQA9SuAD1ogR3ZpDy/NXoaAZf8PTdPcuNUMULV9PGG7tVrLBecO/W1qO6hdFxwlLdgqGLxAENZgGp++v/DhPk/WvtmHj7iTbRq0nxaTWyX5uKOn2ADH+k/yfutjv6BsQU9xNyPeZEEtuEpc6X6waiYn/8G9vl9PecvKC5H0MgsZ6asAxmg7mZ3VSMFG7mo8ENeOhSZ0Oz6ZTBILL3wFccZA9uJIq7NWmqC9dRiGiuKXBB62No7sINoHg3114e2xYa9qvNmGg=" secure: "Am13HPtpgCMljh0MDVuoFHvQXB8yhf4Kvf/qAeSp5N0vsHGL70CSF9Ahccw8dVPE6mbuak1OGtSUb6/UaErLHkpz3ztaRLkDa9x7CmBB3Kynnh8oO2VbB7b/2ROULqkhF4VZmAnNfwrQrbC3gs8Sybp261Nyc7y4ww15xDYBrk2fyq4ds2DCaJdRxfJUJFonrZ6KXr3fVaXosO6cjuyS8eRodcmrqsT4cCtinjNTD1hGWoH107E4ObSmpVelxQO193KhNJMRiLlEcVkvYUOqIWBtwdGHbNE/6Yeuq1TXgKJ0KeJWAmW3wTfUYNngGXNAsyCnrhul5TKNevNzfIAQZHvRsczYiWPJV6LtohHT0CcUiCXJtvEPOyahEBfwK3etY/xxFqny7N9OEmpdW2sgsEPNPX2LJynJti2rQA9SuAD1ogR3ZpDy/NXoaAZf8PTdPcuNUMULV9PGG7tVrLBecO/W1qO6hdFxwlLdgqGLxAENZgGp++v/DhPk/WvtmHj7iTbRq0nxaTWyX5uKOn2ADH+k/yfutjv6BsQU9xNyPeZEEtuEpc6X6waiYn/8G9vl9PecvKC5H0MgsZ6asAxmg7mZ3VSMFG7mo8ENeOhSZ0Oz6ZTBILL3wFccZA9uJIq7NWmqC9dRiGiuKXBB62No7sINoHg3114e2xYa9qvNmGg="
cache: cache:
directories: directories:
- $HOME/.cache/pip - $HOME/.cache/pip
- $HOME/Library/Caches/pip - $HOME/Library/Caches/pip
- $TRAVIS_BUILD_DIR/cache/wheel - $TRAVIS_BUILD_DIR/cache/wheel
addons:
apt:
packages:
- libgmp3-dev
- build-essential
- git
- libssl-dev
- libffi-dev
before_install: before_install:
- if [[ "$TRAVIS_OS_NAME" == "osx" && "$TRAVIS_PULL_REQUEST" == "false" ]]; then ./packaging/travis/setup_osx.sh; fi - virtualenv venv
- mkdir -p lbrynet/resources/ui - source venv/bin/activate
- ./packaging/travis/setup_build.sh
install: install:
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./packaging/travis/install_dependencies_and_run_tests.sh; fi - pip install -U pip
- pip install -r requirements.txt
before_script: - pip install git+https://github.com/lbryio/lbryum.git
- if [[ "$TRAVIS_OS_NAME" == "osx" && "$TRAVIS_PULL_REQUEST" == "false" ]]; then openssl aes-256-cbc -k "$ENCRYPTION_SECRET" -in packaging/osx/certs/dist.cer.enc -d -a -out packaging/osx/certs/dist.cer; fi - pip install .
- if [[ "$TRAVIS_OS_NAME" == "osx" && "$TRAVIS_PULL_REQUEST" == "false" ]]; then openssl aes-256-cbc -k "$ENCRYPTION_SECRET" -in packaging/osx/certs/dist.p12.enc -d -a -out packaging/osx/certs/dist.p12; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" && "$TRAVIS_PULL_REQUEST" == "false" ]]; then ./packaging/osx/add-key.sh; fi
script: script:
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then bash packaging/ubuntu/ubuntu_package_setup.sh -t; fi - pip install cython
- if [[ "$TRAVIS_OS_NAME" == "osx" && "$TRAVIS_PULL_REQUEST" == "false" ]]; then cd packaging/osx/lbry-osx-app && ./setup_app.sh && cd $TRAVIS_BUILD_DIR; fi - pip install mock pylint unqlite
# fail the build if this is a build for a tag and we don't have the versions matching; allow tags that start with 'test' to pass - ./run_pylint.sh
- if [[ -n "${TRAVIS_TAG}" ]]; then if [[ "${TRAVIS_TAG}" == test* ]] || [[ "v`python setup.py -V`" = "${TRAVIS_TAG}" ]]; then true; else false; fi; fi - ./run_tests.sh
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then rvm use 2.3.1 && gem install danger --version '~> 4.0' && danger; fi - rvm use 2.3.1 && gem install danger --version '~> 4.0' && danger
before_deploy:
# s3 release can only upload a folder so move the package into an upload folder
- mkdir "${TRAVIS_BUILD_DIR}/upload"
- if [[ "$TRAVIS_OS_NAME" == "osx" && "$TRAVIS_PULL_REQUEST" == "false" ]]; then mv "${TRAVIS_BUILD_DIR}/packaging/osx/lbry-osx-app/`python setup.py --name`.`python setup.py -V`.dmg" "${TRAVIS_BUILD_DIR}/upload"; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then mv "${TRAVIS_BUILD_DIR}/`python setup.py --name`_`python setup.py -V`_amd64.deb" "${TRAVIS_BUILD_DIR}/upload"; fi
deploy:
- provider: releases
file: "${TRAVIS_BUILD_DIR}/upload/`python setup.py --name`_`python setup.py -V`_amd64.deb"
skip_cleanup: true
prerelease: true
on:
tags: true
condition: "$TRAVIS_OS_NAME = linux"
# this is the oauth token for the lbry-ci user
api_key:
secure: nKdWGROnLNodx9k9nWvq2wezkPvSVL8zF63qjPXjhdOe9kCUbcLp7WnFDYpn9EJj4Pofq/ejeCHwjA+5x7JUP3Szk7SlJV61B4c/5hl64rl7oSKOoKskjdE2jaOG3CJuOUrh0yQ59U3vMMABcsnw/wJaCIuu/erdPIm8g8R+stu1YHOGtl5Y9WiW+zLJn2vc3GooV1TWtki9EnrmFfw0Vrqc4RMVMFB1ojE7ggrK1LIwcmGSbLIYzker1ZRz8SCy+84sGk4//V+2i2NNiz5AkPuG7BBGrU2twE9nD23IlruJAdVdi71P3ytAmi0kKyvxIU4VeNaqyTk9zeL5IB9J5IIgvekHgKcsKhFUZ6QcXT1Xfxl4ELftvWCTHWiewnXFdqLcG9GZiUaE6+7wdalwDAP3tqS2emiibetlBZERHR+RMR00ej+1MBYWGMlTse/0Tglndv0a2qqgAJYLKPRT02hTRYGxZ1MrJe+WGnChRmzwgLVTIgZuiDciFOahN0TYGSORk6OpnZBsxvpzSqDw5UDJx0BmbJ1xMNDFbOs8ubZ9yIpB9yNMGw66FPacOF61XNYnmA68ILC28UtOFKuuHLrUPbM5JmQkDVhtTfFbBnyHefyCLAL4MHvJJKGi1oaOXjYaJ/J095h636/kQ0cHHuVMgoWUQZOQ44xRAz7tMuc=
- provider: releases
file: "${TRAVIS_BUILD_DIR}/upload/`python setup.py --name`.`python setup.py -V`.dmg"
skip_cleanup: true
prerelease: true
on:
tags: true
condition: "$TRAVIS_OS_NAME = osx"
# this is the oauth token for the lbry-ci user
api_key:
secure: nKdWGROnLNodx9k9nWvq2wezkPvSVL8zF63qjPXjhdOe9kCUbcLp7WnFDYpn9EJj4Pofq/ejeCHwjA+5x7JUP3Szk7SlJV61B4c/5hl64rl7oSKOoKskjdE2jaOG3CJuOUrh0yQ59U3vMMABcsnw/wJaCIuu/erdPIm8g8R+stu1YHOGtl5Y9WiW+zLJn2vc3GooV1TWtki9EnrmFfw0Vrqc4RMVMFB1ojE7ggrK1LIwcmGSbLIYzker1ZRz8SCy+84sGk4//V+2i2NNiz5AkPuG7BBGrU2twE9nD23IlruJAdVdi71P3ytAmi0kKyvxIU4VeNaqyTk9zeL5IB9J5IIgvekHgKcsKhFUZ6QcXT1Xfxl4ELftvWCTHWiewnXFdqLcG9GZiUaE6+7wdalwDAP3tqS2emiibetlBZERHR+RMR00ej+1MBYWGMlTse/0Tglndv0a2qqgAJYLKPRT02hTRYGxZ1MrJe+WGnChRmzwgLVTIgZuiDciFOahN0TYGSORk6OpnZBsxvpzSqDw5UDJx0BmbJ1xMNDFbOs8ubZ9yIpB9yNMGw66FPacOF61XNYnmA68ILC28UtOFKuuHLrUPbM5JmQkDVhtTfFbBnyHefyCLAL4MHvJJKGi1oaOXjYaJ/J095h636/kQ0cHHuVMgoWUQZOQ44xRAz7tMuc=
- provider: s3
access_key_id:
secure: "gmJNW8bda2snpA2F+0gucjgO/orvZL0a348QmiffYdtXleIseyY+C4ZI9llWm+s8n2TxiqBYpc/A3Bv7JM0yIccjF0CWQb8pu4HkVT2xLT/1p28EdfxKhR0H5sLtkxOCvLIuf3ppZWac8IzRWvh9TDER1TVxbIGvbOJCtKJ+sUKGCWVkxJY6lzAy7+YHwY9sLV6GvarbkfcnbwNh0qPEROcc6JXUQRKCjWOoZLSZHx4dwxlDiXaG1GyUSm2bwtB11VbMZqaP5eO2zypcUr24J0WkzuAOFIUMDERQnY6eSR62T88BjVjL+07kQufSTtnHC49uHsylyQLwkphkwi2Ei3c/fJ5XI1gY0Med/WOHuy99LAaaHQvHxVa9Zxvrgivvu1oa2QdLir05asMCB0G6Yjgz38Fl8jzdKN/PLHs/lhgBGOJfMN+0UR7hOrLeXdJcMriVfwzYrCl6KkFgTe50rcMx8vv6SH15AqZ5sceksy+maA4O8Mxq1hEe2qJABgRdRZK3FnFKNnQOxfrlU6N9zMNsicVcRwH6WNBtoL4BK3KeMproWnorh9rXmdoSG2Fh5X636cudYhLrAbO5yaoZAXFxHqOV1n63v3tgv4MKrB999OF9V9HyYXv3ro9WZTTsH7LskLA7YmTvXtpMVgBK8SfnvqCjLim5qpVvIVPQIOY="
secret_access_key:
secure: "pS28jMSNV8HUSa8P8pReXgBtHW0OSWDZMAlZhBrtUI05goUnK6buXadvzCynZWgDiXPHuEuLZOLDVj5yL8N3eCa+sG1tEDcCjPxrBFxHisng8atgn3FaL15MBOdXn0qOBUr+vQ4jbUozsBYGqmoZQV0/Af53tU55KK5HJrotkd++SNTEQrFbWZavM+Wvhw4yJN2hmRer9II72DCZkayUjpvBq+irnGeU0g9SrX8VULCg+sqcnbqdLWd+VALHzQr+O74MaWE8mu2PA8A1GKWZZ/a+LoTh1T2bArpX94q0ueea1eEcUA154vC1azkKK5vy9hzENt5qiiEleBDE31DhbGaeEoakEXvHWrdI3DYiakD6prj0necD8aAK6VhPtqwiTtTf7E4BE9hxY4nJRDuZckvFI4LYFMvHlbdqBieeZPflStkws7VgsfrGV7EberYIbSEohUGGUBg3rdaCIPsn8W4nQAixq39Dcfm0orGo4BgargT6FFtAeDzsfYdbKBk/F8BOPMDJz9P1utAZ/ZeBexic16aeIbk7+wtaQUd0Hswm+2QUHddshvp9IzNniFb1BLvRR/lOVl0HdUkJj/haR2M8XhwcRFIKpL2oMZHwRmLW4c1kkEx+KSfAB77arjgrCzq3y5MlKUSliL5qZZMIJX0ReRQ2dcy3DCY0Fxdj014="
bucket: lbrynet-master
skip_cleanup: true
local_dir: "${TRAVIS_BUILD_DIR}/upload"
region: us-west-2
on:
branch: master
env:
global:
# needed to unlock the identity file when its on the keychain
- secure: "aqgVNHfeh6JUqTTWG5+W+tTsIJkePS6HyLkcZlq6ODYrfdGKa90EeV4q4wdGfP5IkrBbf+WBFACDGVp574E7vfMLMNKUDuUtgnGVPwqOIhjG82ud8Xa7qF7lsw50QOnRYYVd2GLlCIzk8sffT5ncjSPN2ClNVM5iTwCkC8TNSAVnEJxu6bG6hcaT4uCWWjs0m+39O1xJwxJ4vTjpE/gy+j2FTSaUR5cNavOVCyJqpeKlga9aoBVsQHWvxlYurdWbwRLwVIV7bDE+sYPnwn1nMFQpx5RZ1AX1Z2UxNFKcYzLJgcWe85OjxLyT4udX+XZ9SLsdOjm1n201OLEKsmTxmHS8yqpbu6+pKQ1rLMEVpgPGfS8DdtqZyb3z0u6q4jztpm+uBe8hnFgwQFGXO63nOQsI0n1PMR3evAnVx7jYt7y/UALs2A9yjosMwDqgql1FMhyd0OJGo8Ky8YpDsr2J5zGVvIqt2/N+lP+SOe2D1J/5EhGlY0o4tqIAFskh3q8/GR6UGm70KT2l4LJqrU1WGrGxPJ+HoOEmvG6eqLesk03fAX3v5+DgXZWErnzXMIOGDPaFVpmx+G9VZTIlmf+3Wbu9TnZE5PRwFTdP1rqjGpjUhHeF0VTc2qgNq1OfL98CBO1wLgA195+em58cELalnwDMWUTmY1Jt1kUuAtCc11U="
# used to decypt the aes decrypt the certificate and identity files
- secure: "FzftiEBFMngQIci5KZ+tpKs/BubalhWXJ9f8yogGNVa3XplLheUXYgcsNU8sYT2MJaKAHN9fSjHWb67UtKT7yXddXxeOPnW6wJ3ua/FXnpynsmeGKTfh3stvgjpzdXous67uHmCWMMklfb6z7UuDohjUMAe5n5HKw5tq1RzTKpc2kJacOC6qUT5laUOvULyCaO9E9HmbHeR5ZeXAC6pnzX2ccsSrcXvPozHzBIZ9RyothKs+CZw8PEuJo07RRL8meboegqYOUrOYuz6A2gS2mZJoy59ivZKOFxS5shEuv2Jt80RyfyxBoUpKFq8OG3Am5nAEzDiTIGzmIoKDEGKeTagk/sEtSZXiMDkzDT4GX/j1rUNLCBU87bXEFS2zfRsrfg8c1XZPIzDYBT1PY2QtLBdddF5zzDoKdPLJ3sjN+fZFE5RlnwfwnMHriVRZZlzjcdk0Z06gKTBCxUg5BZamnOOK+K8qunMJXVS+Vmi5u4RoTZZiCosUlYKnSKJ8suO9C0+znxoViusPqP4ONprNHgDoZw+UKio84QW3PrZv9h4zH/D+msDgJRZ0ceqDD+6Wz1J8Mm5ptW1GOLh/IU12TPXjxteqh0Um2vv5eIPmjK9uEK666kK7PqtPDkYhAfWvF+nmOOyPMJfbP4MW/i9WHNF4ghsIMbPKfqNhgSmfrYw="

View file

@ -33,6 +33,9 @@ at anytime.
## [0.8.4rc0] - 2017-02-17 ## [0.8.4rc0] - 2017-02-17
### Changed ### Changed
* Remove unused upload_allowed option * Remove unused upload_allowed option
* Remove code related to packaging as that step is now done in the electron client
* Remove lbryum version check; use lbry-electron as version source
* Include download url in version check
### Fixed ### Fixed
* add misssing traceback to logging * add misssing traceback to logging

View file

@ -3,19 +3,30 @@
# LBRY # LBRY
LBRY is a fully decentralized, open-source protocol facilitating the discovery, access, and (sometimes) purchase of data. LBRY is a fully decentralized, open-source protocol facilitating the
discovery, access, and (sometimes) purchase of data.
## Installing LBRY This repo is a reference implementation of the LBRY protocol and
provides daemon that can interact with the network via a json-rpc
interface.
We provide binaries for Windows, macOS, and Debian-based Linux. ## Installing the LBRY App
The LBRY App is a decentralized content marketplace built on top of
the LBRY protocol. We provide binaries for Windows, macOS, and
Debian-based Linux.
| Windows | macOS | Linux | | Windows | macOS | Linux |
| --- | --- | --- | | --- | --- | --- |
| [Download MSI](https://lbry.io/get/lbry.msi) | [Download DMG](https://lbry.io/get/lbry.dmg) | [Download DEB](https://lbry.io/get/lbry.deb) | | [Download](https://lbry.io/get/lbry.msi) | [Download](https://lbry.io/get/lbry.dmg) | [Download](https://lbry.io/get/lbry.deb) |
Our [releases page](https://github.com/lbryio/lbry/releases/latest) also contains the latest release, pre-releases, and past builds. Our [releases page](https://github.com/lbryio/lbry-app/releases/latest) also contains the latest release, pre-releases, and past builds.
## Using the LBRY daemon
See our quickstart guide at http://lbry.io/quickstart for details on how to install and use the `lbrynet-daemon`.
For instructions on building from source, see [INSTALL.md](INSTALL.md).
## What is LBRY? ## What is LBRY?
@ -23,61 +34,23 @@ LBRY is a fully decentralized network for distributing data. It consists of peer
and downloading data from other peers, possibly in exchange for payments, and a distributed hash and downloading data from other peers, possibly in exchange for payments, and a distributed hash
table, used by peers to discover other peers. table, used by peers to discover other peers.
On LBRY, data is broken into chunks, and each chunk is specified by its sha384 hash sum. This On LBRY, data is broken into chunks, and each chunk is content
guarantees that peers can verify the correctness of each chunk without having to know anything addressable, specified by its sha384 hash sum. This guarantees that
about its contents, and can confidently re-transmit the chunk to other peers. Peers wishing to peers can verify the correctness of each chunk without having to know
transmit chunks to other peers announce to the distributed hash table that they are associated anything about its contents, and can confidently re-transmit the chunk
with the sha384 hash sum in question. When a peer wants to download that chunk from the network, to other peers. Peers wishing to transmit chunks to other peers
it asks the distributed hash table which peers are associated with that sha384 hash sum. The announce to the distributed hash table that they are associated with
distributed hash table can also be used more generally. It simply stores IP addresses and the sha384 hash sum in question. When a peer wants to download that
ports which are associated with 384-bit numbers, and can be used by any type of application to chunk from the network, it asks the distributed hash table which peers
help peers find each other. For example, an application for which clients don't know all of the are associated with that sha384 hash sum. The distributed hash table
necessary chunks may use some identifier, chosen by the application, to find clients which do can also be used more generally. It simply stores IP addresses and
know all of the necessary chunks. ports which are associated with 384-bit numbers, and can be used by
any type of application to help peers find each other. For example, an
application for which clients don't know all of the necessary chunks
may use some identifier, chosen by the application, to find clients
which do know all of the necessary chunks.
## For Developers ## Contributions
The bundled LBRY application uses the lbrynet JSONRPC api found in `lbrynet.lbrynet_daemon.LBRYDaemon`. This api allows for applications and web services like the lbry browser UI to interact with lbrynet. If you've installed lbrynet, you can run `lbrynet-daemon` without running the app. While the app or `lbrynet-daemon` is running, you can use the following to show the help for all the available commands:
```
import sys
try:
from lbrynet import conf
from lbrynet.lbrynet_daemon.auth.client import LBRYAPIClient
except ImportError:
print "You don't have lbrynet installed!"
sys.exit(0)
conf.initialize_settings()
api = LBRYAPIClient.get_client()
try:
status = api.status()
except:
print "lbrynet-daemon isn't running!"
sys.exit(0)
if not status['is_running']:
print "lbrynet-daemon hasn't finished starting up, here's the status message:"
print status
sys.exit(0)
else:
for cmd in api.commands():
print "%s:\n%s" % (cmd, api.help({'command': cmd}))
```
If you've installed lbrynet, it comes with a file sharing application, called `lbrynet-daemon`, which breaks
files into chunks, encrypts them with a symmetric key, computes their sha384 hash sum, generates
a special file called a 'stream descriptor' containing the hash sums and some other file metadata,
and makes the chunks available for download by other peers. A peer wishing to download the file
must first obtain the 'stream descriptor' and then may open it with his `lbrynet-daemon` client,
download all of the chunks by locating peers with the chunks via the DHT, and then combine the
chunks into the original file, according to the metadata included in the 'stream descriptor'.
For instructions on installing from source, see [INSTALL.md](INSTALL.md).
Source code: https://github.com/lbryio/lbry
To contribute, [join us on Slack](https://lbry-slackin.herokuapp.com/) or contact jeremy@lbry.io. Pull requests are also welcome. To contribute, [join us on Slack](https://lbry-slackin.herokuapp.com/) or contact jeremy@lbry.io. Pull requests are also welcome.

View file

@ -1,6 +1,6 @@
import logging import logging
__version__ = "0.8.7" __version__ = "0.9.0rc6"
version = tuple(__version__.split('.')) version = tuple(__version__.split('.'))
logging.getLogger(__name__).addHandler(logging.NullHandler()) logging.getLogger(__name__).addHandler(logging.NullHandler())

View file

@ -2,10 +2,8 @@ import base64
import datetime import datetime
import logging import logging
import random import random
import os
import socket import socket
import string import string
import sys
import pkg_resources import pkg_resources
@ -104,12 +102,6 @@ def check_connection(server="www.lbry.io", port=80):
return False return False
def setup_certs_for_windows():
if getattr(sys, 'frozen', False) and os.name == "nt":
cert_path = os.path.join(os.path.dirname(sys.executable), "cacert.pem")
os.environ["REQUESTS_CA_BUNDLE"] = cert_path
def random_string(length=10, chars=string.ascii_lowercase): def random_string(length=10, chars=string.ascii_lowercase):
return ''.join([random.choice(chars) for _ in range(length)]) return ''.join([random.choice(chars) for _ in range(length)])

View file

@ -18,8 +18,8 @@ from twisted.internet.task import LoopingCall
from twisted.python.failure import Failure from twisted.python.failure import Failure
# TODO: importing this when internet is disabled raises a socket.gaierror # TODO: importing this when internet is disabled raises a socket.gaierror
from lbryum.version import LBRYUM_VERSION as lbryum_version from lbryum.version import LBRYUM_VERSION
from lbrynet import __version__ as lbrynet_version from lbrynet import __version__ as LBRYNET_VERSION
from lbrynet import conf, analytics from lbrynet import conf, analytics
from lbrynet.conf import LBRYCRD_WALLET, LBRYUM_WALLET, PTC_WALLET from lbrynet.conf import LBRYCRD_WALLET, LBRYUM_WALLET, PTC_WALLET
from lbrynet.reflector import reupload from lbrynet.reflector import reupload
@ -33,7 +33,6 @@ from lbrynet.lbryfile.StreamDescriptor import save_sd_info
from lbrynet.lbryfile.EncryptedFileMetadataManager import DBEncryptedFileMetadataManager from lbrynet.lbryfile.EncryptedFileMetadataManager import DBEncryptedFileMetadataManager
from lbrynet.lbryfile.StreamDescriptor import EncryptedFileStreamType from lbrynet.lbryfile.StreamDescriptor import EncryptedFileStreamType
from lbrynet.lbryfilemanager.EncryptedFileManager import EncryptedFileManager from lbrynet.lbryfilemanager.EncryptedFileManager import EncryptedFileManager
from lbrynet.lbrynet_daemon.UIManager import UIManager
from lbrynet.lbrynet_daemon.Downloader import GetStream from lbrynet.lbrynet_daemon.Downloader import GetStream
from lbrynet.lbrynet_daemon.Publisher import Publisher from lbrynet.lbrynet_daemon.Publisher import Publisher
from lbrynet.lbrynet_daemon.ExchangeRateManager import ExchangeRateManager from lbrynet.lbrynet_daemon.ExchangeRateManager import ExchangeRateManager
@ -83,11 +82,9 @@ STREAM_STAGES = [
] ]
CONNECTION_STATUS_CONNECTED = 'connected' CONNECTION_STATUS_CONNECTED = 'connected'
CONNECTION_STATUS_VERSION_CHECK = 'version_check'
CONNECTION_STATUS_NETWORK = 'network_connection' CONNECTION_STATUS_NETWORK = 'network_connection'
CONNECTION_MESSAGES = { CONNECTION_MESSAGES = {
CONNECTION_STATUS_CONNECTED: 'No connection problems detected', CONNECTION_STATUS_CONNECTED: 'No connection problems detected',
CONNECTION_STATUS_VERSION_CHECK: "There was a problem checking for updates on github",
CONNECTION_STATUS_NETWORK: "Your internet connection appears to have been interrupted", CONNECTION_STATUS_NETWORK: "Your internet connection appears to have been interrupted",
} }
@ -127,40 +124,55 @@ class CheckInternetConnection(object):
self.daemon.connected_to_internet = utils.check_connection() self.daemon.connected_to_internet = utils.check_connection()
class CheckRemoteVersions(object): class CheckRemoteVersion(object):
def __init__(self, daemon): URL = 'https://api.github.com/repos/lbryio/lbry-electron/releases/latest'
self.daemon = daemon def __init__(self):
self.version = None
def __call__(self): def __call__(self):
d = threads.deferToThread(self._get_lbrynet_version) d = threads.deferToThread(self._get_lbry_electron_client_version)
d.addErrback(self._trap_and_log_error, 'lbrynet') d.addErrback(self._trap_and_log_error, 'lbry-electron')
d.addCallback(lambda _: threads.deferToThread(self._get_lbryum_version))
d.addErrback(self._trap_and_log_error, 'lbryum')
d.addErrback(log.fail(), 'Failure checking versions on github') d.addErrback(log.fail(), 'Failure checking versions on github')
def _trap_and_log_error(self, err, module_checked): def _trap_and_log_error(self, err, module_checked):
# KeyError is thrown by get_version_from_github # KeyError is thrown by get_version_from_github
# It'd be better to catch the error before trying to parse the response # It'd be better to catch the error before trying to parse the response
err.trap(requests_exceptions.RequestException, KeyError) err.trap(requests_exceptions.RequestException, KeyError)
if err.check(requests_exceptions.RequestException, KeyError): log.warning("Failed to check latest %s version from github", module_checked)
log.warning("Failed to check latest %s version from github", module_checked)
def _get_lbryum_version(self): def _get_lbry_electron_client_version(self):
self.daemon.git_lbryum_version = get_lbryum_version_from_github() # We'll need to ensure the lbry-electron version is in sync
log.info( # with the lbrynet-daemon version
"remote lbryum %s > local lbryum %s = %s", self._set_data_from_github()
self.daemon.git_lbryum_version, lbryum_version,
utils.version_is_greater_than(self.daemon.git_lbryum_version, lbryum_version)
)
def _get_lbrynet_version(self):
self.daemon.git_lbrynet_version = get_lbrynet_version_from_github()
log.info( log.info(
"remote lbrynet %s > local lbrynet %s = %s", "remote lbrynet %s > local lbrynet %s = %s",
self.daemon.git_lbrynet_version, lbrynet_version, self.version, LBRYNET_VERSION,
utils.version_is_greater_than(self.daemon.git_lbrynet_version, lbryum_version) utils.version_is_greater_than(self.version, LBRYNET_VERSION)
) )
def _set_data_from_github(self):
release = self._get_release_data()
# githubs documentation claims this should never happen, but we'll check just in case
if release['prerelease']:
raise Exception('Release {} is a pre-release'.format(release['tag_name']))
self.version = self._get_version_from_release(release)
def _get_release_data(self):
response = requests.get(self.URL, timeout=20)
release = response.json()
return release
def _get_version_from_release(self, release):
"""Return the latest released version from github."""
tag = release['tag_name']
return get_version_from_tag(tag)
def is_update_available(self):
try:
return utils.version_is_greater_than(self.version, LBRYNET_VERSION)
except TypeError:
return False
class AlwaysSend(object): class AlwaysSend(object):
def __init__(self, value_generator, *args, **kwargs): def __init__(self, value_generator, *args, **kwargs):
@ -200,7 +212,7 @@ class Daemon(AuthJSONRPCServer):
'is_running', 'is_first_run', 'get_time_behind_blockchain', 'daemon_status', 'is_running', 'is_first_run', 'get_time_behind_blockchain', 'daemon_status',
'get_start_notice', 'get_start_notice',
] ]
last_version = {'last_version': {'lbrynet': lbrynet_version, 'lbryum': lbryum_version}} last_version = {'last_version': {'lbrynet': LBRYNET_VERSION, 'lbryum': LBRYUM_VERSION}}
conf.settings.update(last_version) conf.settings.update(last_version)
self.db_dir = conf.settings['data_dir'] self.db_dir = conf.settings['data_dir']
self.download_directory = conf.settings['download_directory'] self.download_directory = conf.settings['download_directory']
@ -235,8 +247,6 @@ class Daemon(AuthJSONRPCServer):
self.startup_status = STARTUP_STAGES[0] self.startup_status = STARTUP_STAGES[0]
self.connected_to_internet = True self.connected_to_internet = True
self.connection_status_code = None self.connection_status_code = None
self.git_lbrynet_version = None
self.git_lbryum_version = None
self.platform = None self.platform = None
self.first_run = None self.first_run = None
self.log_file = conf.settings.get_log_filename() self.log_file = conf.settings.get_log_filename()
@ -261,16 +271,16 @@ class Daemon(AuthJSONRPCServer):
self.pending_claims = {} self.pending_claims = {}
self.name_cache = {} self.name_cache = {}
self.exchange_rate_manager = ExchangeRateManager() self.exchange_rate_manager = ExchangeRateManager()
self._remote_version = CheckRemoteVersion()
calls = { calls = {
Checker.INTERNET_CONNECTION: LoopingCall(CheckInternetConnection(self)), Checker.INTERNET_CONNECTION: LoopingCall(CheckInternetConnection(self)),
Checker.VERSION: LoopingCall(CheckRemoteVersions(self)), Checker.VERSION: LoopingCall(self._remote_version),
Checker.CONNECTION_STATUS: LoopingCall(self._update_connection_status), Checker.CONNECTION_STATUS: LoopingCall(self._update_connection_status),
Checker.PENDING_CLAIM: LoopingCall(self._check_pending_claims), Checker.PENDING_CLAIM: LoopingCall(self._check_pending_claims),
} }
self.looping_call_manager = LoopingCallManager(calls) self.looping_call_manager = LoopingCallManager(calls)
self.sd_identifier = StreamDescriptorIdentifier() self.sd_identifier = StreamDescriptorIdentifier()
self.stream_info_manager = DBEncryptedFileMetadataManager(self.db_dir) self.stream_info_manager = DBEncryptedFileMetadataManager(self.db_dir)
self.lbry_ui_manager = UIManager(root)
self.lbry_file_manager = None self.lbry_file_manager = None
@defer.inlineCallbacks @defer.inlineCallbacks
@ -308,11 +318,6 @@ class Daemon(AuthJSONRPCServer):
self.looping_call_manager.start(Checker.CONNECTION_STATUS, 30) self.looping_call_manager.start(Checker.CONNECTION_STATUS, 30)
self.exchange_rate_manager.start() self.exchange_rate_manager.start()
if conf.settings['host_ui']:
self.lbry_ui_manager.update_checker.start(1800, now=False)
yield self.lbry_ui_manager.setup()
if launch_ui:
self.lbry_ui_manager.launch()
yield self._initial_setup() yield self._initial_setup()
yield threads.deferToThread(self._setup_data_directory) yield threads.deferToThread(self._setup_data_directory)
yield self._check_db_migration() yield self._check_db_migration()
@ -330,7 +335,6 @@ class Daemon(AuthJSONRPCServer):
def _get_platform(self): def _get_platform(self):
if self.platform is None: if self.platform is None:
self.platform = system_info.get_platform() self.platform = system_info.get_platform()
self.platform["ui_version"] = self.lbry_ui_manager.loaded_git_version
return self.platform return self.platform
def _initial_setup(self): def _initial_setup(self):
@ -367,9 +371,6 @@ class Daemon(AuthJSONRPCServer):
def _update_connection_status(self): def _update_connection_status(self):
self.connection_status_code = CONNECTION_STATUS_CONNECTED self.connection_status_code = CONNECTION_STATUS_CONNECTED
if not self.git_lbrynet_version or not self.git_lbryum_version:
self.connection_status_code = CONNECTION_STATUS_VERSION_CHECK
if not self.connected_to_internet: if not self.connected_to_internet:
self.connection_status_code = CONNECTION_STATUS_NETWORK self.connection_status_code = CONNECTION_STATUS_NETWORK
@ -532,8 +533,6 @@ class Daemon(AuthJSONRPCServer):
self.looping_call_manager.shutdown() self.looping_call_manager.shutdown()
if self.analytics_manager: if self.analytics_manager:
self.analytics_manager.shutdown() self.analytics_manager.shutdown()
if self.lbry_ui_manager.update_checker.running:
self.lbry_ui_manager.update_checker.stop()
self._clean_up_temp_files() self._clean_up_temp_files()
@ -1254,27 +1253,15 @@ class Daemon(AuthJSONRPCServer):
""" """
platform_info = self._get_platform() platform_info = self._get_platform()
try:
lbrynet_update_available = utils.version_is_greater_than(
self.git_lbrynet_version, lbrynet_version)
except TypeError:
lbrynet_update_available = False
try:
lbryum_update_available = utils.version_is_greater_than(
self.git_lbryum_version, lbryum_version)
except TypeError:
lbryum_update_available = False
msg = { msg = {
'platform': platform_info['platform'], 'platform': platform_info['platform'],
'os_release': platform_info['os_release'], 'os_release': platform_info['os_release'],
'os_system': platform_info['os_system'], 'os_system': platform_info['os_system'],
'lbrynet_version': lbrynet_version, 'lbrynet_version': LBRYNET_VERSION,
'lbryum_version': lbryum_version, 'lbryum_version': LBRYUM_VERSION,
'ui_version': platform_info['ui_version'], 'ui_version': platform_info['ui_version'],
'remote_lbrynet': self.git_lbrynet_version, 'remote_lbrynet': self._remote_version.version,
'remote_lbryum': self.git_lbryum_version, 'lbrynet_update_available': self._remote_version.is_update_available(),
'lbrynet_update_available': lbrynet_update_available,
'lbryum_update_available': lbryum_update_available
} }
log.info("Get version info: " + json.dumps(msg)) log.info("Get version info: " + json.dumps(msg))
@ -1295,7 +1282,7 @@ class Daemon(AuthJSONRPCServer):
message, message,
conf.settings.installation_id, conf.settings.installation_id,
platform_name, platform_name,
lbrynet_version LBRYNET_VERSION
) )
return self._render_response(True) return self._render_response(True)
@ -2249,28 +2236,6 @@ class Daemon(AuthJSONRPCServer):
d.addCallback(lambda _: self._render_response(True)) d.addCallback(lambda _: self._render_response(True))
return d return d
@AuthJSONRPCServer.auth_required
def jsonrpc_configure_ui(self, branch=None, path=None, check_requirements=True):
"""
Configure the UI being hosted
Args, optional:
'branch': a branch name on lbryio/lbry-web-ui
'path': path to a ui folder
"""
if path is not None:
d = self.lbry_ui_manager.setup(
user_specified=path, check_requirements=check_requirements)
elif branch is not None:
d = self.lbry_ui_manager.setup(branch=branch, check_requirements=check_requirements)
else:
d = self.lbry_ui_manager.setup(check_requirements=check_requirements)
d.addCallback(lambda r: self._render_response(r))
return d
@AuthJSONRPCServer.auth_required @AuthJSONRPCServer.auth_required
@defer.inlineCallbacks @defer.inlineCallbacks
def jsonrpc_open(self, sd_hash): def jsonrpc_open(self, sd_hash):
@ -2548,33 +2513,6 @@ class Daemon(AuthJSONRPCServer):
return d return d
def get_lbryum_version_from_github():
return get_version_from_github('https://api.github.com/repos/lbryio/lbryum/releases/latest')
def get_lbrynet_version_from_github():
return get_version_from_github('https://api.github.com/repos/lbryio/lbry/releases/latest')
def get_version_from_github(url):
"""Return the latest released version from github."""
response = requests.get(url, timeout=20)
release = response.json()
tag = release['tag_name']
# githubs documentation claims this should never happen, but we'll check just in case
if release['prerelease']:
raise Exception('Release {} is a pre-release'.format(tag))
return get_version_from_tag(tag)
def get_version_from_tag(tag):
match = re.match('v([\d.]+)', tag)
if match:
return match.group(1)
else:
raise Exception('Failed to parse version from tag {}'.format(tag))
def get_sd_hash(stream_info): def get_sd_hash(stream_info):
if not stream_info: if not stream_info:
return None return None
@ -2911,3 +2849,11 @@ def get_blob_payment_rate_manager(session, payment_rate_manager=None):
payment_rate_manager = rate_managers[payment_rate_manager] payment_rate_manager = rate_managers[payment_rate_manager]
log.info("Downloading blob with rate manager: %s", payment_rate_manager) log.info("Downloading blob with rate manager: %s", payment_rate_manager)
return payment_rate_manager or session.payment_rate_manager return payment_rate_manager or session.payment_rate_manager
def get_version_from_tag(tag):
match = re.match('v([\d.]+)', tag)
if match:
return match.group(1)
else:
raise Exception('Failed to parse version from tag {}'.format(tag))

View file

@ -31,7 +31,6 @@ def stop():
def start(): def start():
utils.setup_certs_for_windows()
conf.initialize_settings() conf.initialize_settings()
parser = argparse.ArgumentParser(description="Launch lbrynet-daemon") parser = argparse.ArgumentParser(description="Launch lbrynet-daemon")

View file

@ -1,348 +0,0 @@
import os
import logging
import shutil
import json
import webbrowser
from urllib2 import urlopen
from StringIO import StringIO
from zipfile import ZipFile
import pkg_resources
from twisted.internet import defer
from twisted.internet.task import LoopingCall
from lbrynet import conf
from lbrynet.lbrynet_daemon.Resources import NoCacheStaticFile
from lbrynet import __version__ as lbrynet_version
from lbryum.version import LBRYUM_VERSION as lbryum_version
log = logging.getLogger(__name__)
class UIManager(object):
def __init__(self, root):
self.ui_root = os.path.join(conf.settings['data_dir'], "lbry-ui")
self.active_dir = os.path.join(self.ui_root, "active")
self.update_dir = os.path.join(self.ui_root, "update")
if not os.path.isdir(self.ui_root):
os.mkdir(self.ui_root)
if not os.path.isdir(self.active_dir):
os.mkdir(self.active_dir)
if not os.path.isdir(self.update_dir):
os.mkdir(self.update_dir)
self.config = os.path.join(self.ui_root, "active.json")
self.update_requires = os.path.join(self.update_dir, "requirements.txt")
self.requirements = {}
self.check_requirements = True
self.ui_dir = self.active_dir
self.git_version = None
self.root = root
self.branch = None
self.update_checker = LoopingCall(self.setup)
if not os.path.isfile(os.path.join(self.config)):
self.loaded_git_version = None
self.loaded_branch = None
self.loaded_requirements = None
else:
try:
f = open(self.config, "r")
loaded_ui = json.loads(f.read())
f.close()
self.loaded_git_version = loaded_ui['commit']
self.loaded_branch = loaded_ui['branch']
self.loaded_requirements = loaded_ui['requirements']
except:
self.loaded_git_version = None
self.loaded_branch = None
self.loaded_requirements = None
def setup(self, branch=None, check_requirements=None, user_specified=None):
local_ui_path = user_specified or conf.settings['local_ui_path']
self.branch = branch or conf.settings['ui_branch']
self.check_requirements = (check_requirements if check_requirements is not None
else conf.settings['check_ui_requirements'])
# Note that this currently overrides any manual setting of UI.
# It might be worth considering changing that behavior but the expectation
# is generally that any manual setting of the UI will happen during development
# and not for folks checking out the QA / RC builds that bundle the UI.
if self._check_for_bundled_ui():
return defer.succeed(True)
if local_ui_path:
if os.path.isdir(local_ui_path):
log.info("Checking user specified UI directory: " + str(local_ui_path))
self.branch = "user-specified"
self.loaded_git_version = "user-specified"
d = self.migrate_ui(source=local_ui_path)
d.addCallback(lambda _: self._load_ui())
return d
else:
log.info("User specified UI directory doesn't exist, using " + self.branch)
elif self.loaded_branch == "user-specified":
log.info("Loading user provided UI")
d = defer.maybeDeferred(self._load_ui)
return d
else:
log.info("Checking for updates for UI branch: " + self.branch)
self._git_url = "https://s3.amazonaws.com/lbry-ui/{}/data.json".format(self.branch)
self._dist_url = "https://s3.amazonaws.com/lbry-ui/{}/dist.zip".format(self.branch)
d = self._up_to_date()
d.addCallback(lambda r: self._download_ui() if not r else self._load_ui())
return d
def _check_for_bundled_ui(self):
"""Try to load a bundled UI and return True if successful, False otherwise"""
try:
bundled_path = get_bundled_ui_path()
except Exception:
log.warning('Failed to get path for bundled UI', exc_info=True)
return False
else:
bundle_manager = BundledUIManager(self.root, self.active_dir, bundled_path)
loaded = bundle_manager.setup()
if loaded:
self.loaded_git_version = bundle_manager.version()
return loaded
def _up_to_date(self):
def _get_git_info():
try:
# TODO: should this be switched to the non-blocking getPage?
response = urlopen(self._git_url)
return defer.succeed(read_sha(response))
except Exception:
return defer.fail()
def _set_git(version):
self.git_version = version.replace('\n', '')
if self.git_version == self.loaded_git_version:
log.info("UI is up to date")
return defer.succeed(True)
else:
log.info("UI updates available, checking if installation meets requirements")
return defer.succeed(False)
def _use_existing():
log.info("Failed to check for new ui version, trying to use cached ui")
return defer.succeed(True)
d = _get_git_info()
d.addCallbacks(_set_git, lambda _: _use_existing)
return d
def migrate_ui(self, source=None):
if not source:
requires_file = self.update_requires
source_dir = self.update_dir
delete_source = True
else:
requires_file = os.path.join(source, "requirements.txt")
source_dir = source
delete_source = False
def _skip_requirements():
log.info("Skipping ui requirement check")
return defer.succeed(True)
def _check_requirements():
if not os.path.isfile(requires_file):
log.info("No requirements.txt file, rejecting request to migrate this UI")
return defer.succeed(False)
requirements = Requirements(requires_file)
passed_requirements = requirements.check(lbrynet_version, lbryum_version)
return defer.succeed(passed_requirements)
def _disp_failure():
log.info("Failed to satisfy requirements for branch '%s', update was not loaded",
self.branch)
return defer.succeed(False)
def _do_migrate():
replace_dir(self.active_dir, source_dir)
if delete_source:
shutil.rmtree(source_dir)
log.info("Loaded UI update")
f = open(self.config, "w")
loaded_ui = {
'commit': self.git_version,
'branch': self.branch,
'requirements': self.requirements
}
f.write(json.dumps(loaded_ui))
f.close()
self.loaded_git_version = loaded_ui['commit']
self.loaded_branch = loaded_ui['branch']
self.loaded_requirements = loaded_ui['requirements']
return defer.succeed(True)
d = _check_requirements() if self.check_requirements else _skip_requirements()
d.addCallback(lambda r: _do_migrate() if r else _disp_failure())
return d
def _download_ui(self):
def _delete_update_dir():
if os.path.isdir(self.update_dir):
shutil.rmtree(self.update_dir)
return defer.succeed(None)
def _dl_ui():
url = urlopen(self._dist_url)
z = ZipFile(StringIO(url.read()))
names = [i for i in z.namelist() if '.DS_exStore' not in i and '__MACOSX' not in i]
z.extractall(self.update_dir, members=names)
log.info("Downloaded files for UI commit " + str(self.git_version).replace("\n", ""))
return self.branch
d = _delete_update_dir()
d.addCallback(lambda _: _dl_ui())
d.addCallback(lambda _: self.migrate_ui())
d.addCallback(lambda _: self._load_ui())
return d
def _load_ui(self):
return load_ui(self.root, self.active_dir)
def launch(self):
webbrowser.open(conf.settings.get_ui_address())
class BundledUIManager(object):
"""Copies the UI bundled with lbrynet, if available.
For the QA and nightly builds, we include a copy of the most
recent checkout of the development UI. For production builds
nothing is bundled.
n.b: For QA and nightly builds the update check is skipped.
"""
def __init__(self, root, active_dir, bundled_ui_path):
self.root = root
self.active_dir = active_dir
self.bundled_ui_path = bundled_ui_path
self.data_path = os.path.join(bundled_ui_path, 'data.json')
self._version = None
def version(self):
if not self._version:
self._version = open_and_read_sha(self.data_path)
return self._version
def bundle_is_available(self):
return os.path.exists(self.data_path)
def setup(self):
"""Load the bundled UI if possible and necessary
Returns True if there is a bundled UI, False otherwise
"""
if not self.bundle_is_available():
log.debug('No bundled UI is available')
return False
if not self.is_active_already_bundled_ui():
replace_dir(self.active_dir, self.bundled_ui_path)
log.info('Loading the bundled UI')
load_ui(self.root, self.active_dir)
return True
def is_active_already_bundled_ui(self):
target_data_path = os.path.join(self.active_dir, 'data.json')
if os.path.exists(target_data_path):
target_version = open_and_read_sha(target_data_path)
if self.version() == target_version:
return True
return False
def get_bundled_ui_path():
return pkg_resources.resource_filename('lbrynet', 'resources/ui')
def are_same_version(data_a, data_b):
"""Compare two data files and return True if they are the same version"""
with open(data_a) as a:
with open(data_b) as b:
return read_sha(a) == read_sha(b)
def open_and_read_sha(filename):
with open(filename) as f:
return read_sha(f)
def read_sha(filelike):
data = json.load(filelike)
return data['sha']
def replace_dir(active_dir, source_dir):
if os.path.isdir(active_dir):
shutil.rmtree(active_dir)
shutil.copytree(source_dir, active_dir)
def load_ui(root, active_dir):
for name in os.listdir(active_dir):
entry = os.path.join(active_dir, name)
if os.path.isdir(entry):
root.putChild(os.path.basename(entry), NoCacheStaticFile(entry))
class Requirements(object):
def __init__(self, requires_file):
self.requires_file = requires_file
def check(self, lbrynet_version, lbryum_version):
requirements = self._read()
expected = {'lbrynet': lbrynet_version, 'lbryum': lbryum_version}
return check_requirements(requirements, expected)
def _read(self):
requirements = {}
with open(self.requires_file, "r") as f:
for requirement in [line for line in f.read().split('\n') if line]:
t = requirement.split('=')
if len(t) == 3:
requirements[t[0]] = {'version': t[1], 'operator': '=='}
elif t[0][-1] == ">":
requirements[t[0][:-1]] = {'version': t[1], 'operator': '>='}
elif t[0][-1] == "<":
requirements[t[0][:-1]] = {'version': t[1], 'operator': '<='}
return requirements
def check_requirements(expected, actual):
passed_requirements = True
for name in expected:
if name in actual:
version = actual[name]
else:
continue
log_msg = "Local version %s of %s does not meet UI requirement for version %s"
if expected[name]['operator'] == '==':
if not expected[name]['version'] == version:
passed_requirements = False
log.info(log_msg, version, name, expected[name]['version'])
else:
log.info("Local version of %s meets ui requirement" % name)
if expected[name]['operator'] == '>=':
if not expected[name]['version'] <= version:
passed_requirements = False
log.info(log_msg, version, name, expected[name]['version'])
else:
log.info("Local version of %s meets ui requirement" % name)
if expected[name]['operator'] == '<=':
if not expected[name]['version'] >= version:
passed_requirements = False
log.info(log_msg, version, name, expected[name]['version'])
else:
log.info("Local version of %s meets ui requirement" % name)
return passed_requirements

View file

@ -10,7 +10,7 @@ from twisted.internet.error import ConnectionDone, ConnectionLost
from txjsonrpc import jsonrpclib from txjsonrpc import jsonrpclib
from lbrynet import conf from lbrynet import conf
from lbrynet.core.Error import InvalidAuthenticationToken, InvalidHeaderError from lbrynet.core.Error import InvalidAuthenticationToken
from lbrynet.core import utils from lbrynet.core import utils
from lbrynet.lbrynet_daemon.auth.util import APIKey, get_auth_message, jsonrpc_dumps_pretty from lbrynet.lbrynet_daemon.auth.util import APIKey, get_auth_message, jsonrpc_dumps_pretty
from lbrynet.lbrynet_daemon.auth.client import LBRY_SECRET from lbrynet.lbrynet_daemon.auth.client import LBRY_SECRET
@ -145,7 +145,7 @@ class AuthJSONRPCServer(AuthorizedBase):
def render(self, request): def render(self, request):
time_in = utils.now() time_in = utils.now()
assert self._check_headers(request), InvalidHeaderError # assert self._check_headers(request), InvalidHeaderError
session = request.getSession() session = request.getSession()
session_id = session.uid session_id = session.uid
finished_deferred = request.notifyFinish() finished_deferred = request.notifyFinish()

View file

@ -1,29 +0,0 @@
import argparse
import re
import sys
def main(args=None):
parser = argparse.ArgumentParser()
parser.add_argument('filename')
parser.add_argument('commit')
args = parser.parse_args(args)
with open(args.filename) as f:
contents = f.read()
commit = args.commit[:7]
new_contents = re.sub(
r'^__version__ = [\'"](.*)[\'"]$',
r'__version__ = "\1-{}"'.format(commit),
contents,
flags=re.MULTILINE,
)
with open(args.filename, 'w') as f:
f.write(new_contents)
if __name__ == '__main__':
sys.exit(main())

View file

@ -1,25 +0,0 @@
#!/bin/sh
# http://stackoverflow.com/a/246128
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# adapted from https://www.objc.io/issues/6-build-tools/travis-ci/#add-scripts
KEYCHAIN_PASSWORD=travis
# Create a custom keychain
security create-keychain -p ${KEYCHAIN_PASSWORD} osx-build.keychain
# Make the custom keychain default, so xcodebuild will use it for signing
security default-keychain -s osx-build.keychain
# Unlock the keychain
security unlock-keychain -p ${KEYCHAIN_PASSWORD} osx-build.keychain
# Set keychain timeout to 1 hour for long builds
# see http://www.egeek.me/2013/02/23/jenkins-and-xcode-user-interaction-is-not-allowed/
security set-keychain-settings -t 3600 -l ~/Library/Keychains/osx-build.keychain
# Add certificates to keychain and allow codesign to access them
security import ${DIR}/certs/dist.cer -k ~/Library/Keychains/osx-build.keychain -T /usr/bin/codesign
security import ${DIR}/certs/dist.p12 -k ~/Library/Keychains/osx-build.keychain -P $KEY_PASSWORD -T /usr/bin/codesign

View file

@ -1,2 +0,0 @@
dist.cer
dist.p12

View file

@ -1,30 +0,0 @@
U2FsdGVkX184Qhj+Znx23me5PxRw3d8AgHu/h2uingV6T0lAb9/xDlxOU7E0HEsE
NIVvS0r5kqK6FXhUODny567FR+OGihl/XiKMjMoJSxNIAjYcuo91hVZ2mN+AbIDl
OaaSRSXdwg948eNYhLsjfjyxU4fpZ5P+fSvcMZ4y4xSm7gwOCPrTFhRXmiCxFVsY
x8td9OtmnGwRMnkTz7les3ZW7lHFbsmiHwct+L3QCWcLZ+xklbsLLVkXOuYpws7J
pWKc8YgmyySH9uXnzuxWuRrqvw4coq1pO51WB/6ZaSbiE5FzIq32usnQocl8hjY2
0rveOAR5nLSNA4YQY6O2gbnN6Fq0TDGOIJ1Lvl8XkHKrMqSu9ifFXAmebHH5xfFS
HFZ9mije0lNSxg5a6b2EJkCmbIE5GHzqzzWccAlmgCrOtd6ZpytpW1oTJZEvboo5
G4TdZ3te31ltn+d/2Jr7Z3q2ByueTOVj01fx/mJcDCK+q5ytWOTvqkoGzrHIDbxK
eV/XfhcQ1+dCFIYu89++/bt19NZ7KrxBQ5D2W6G3+71BGIxXYlyGfyTy7dbyl/EY
f9ddk+BxDQgGpj+fRLAOIboKp94bUcneG79H5Fw+w+aTHQM5T/Ilmjq60sUft+2u
gcs0H8Slb3Gnf/QTwSLoxd/GJofAIhIcTD/HSWD8NH9YsK7lvLuLTamnLkprtdvB
NfhsLHENg0Ha/s/eEtU2GAG/RBFT0XwZKR0O19YNSWjEvop7w/cSlwv+be7gT09O
0/vO6xouqG16bSWEg7nxTYs/jMPPfrdn6fhNWEUo2p7FYDbq5BerN/1Eh1xjHwq3
a1pcnFkRumpjMH32aBMS79Ute1ij5xPfFKT/Bh+J4wCTlnKp0EsyhTY9DHtVaw9G
+IfLiFTkN2MQSCGGTcGx6KDAWkjXui/8WLM/adtcLPUBrAHd4S4DoJ8v9sxACRDb
iX950xj0IRqdzb8xF6EPCvb8t02ldzKjQw69FvFFlW4P+La+qvTSgIPo1SJ/uPGm
Asutx5EL51b1zCQk/YrH93pAK2RIqMn40I7sB9t5kcN/rhzcVcgW3ENb4wLynK5C
+gyr65cBgwHIZK7Lpq4rUaWh9TliDpkJqspDJb81IaQjvEKKD3weAg28H4969mju
7Q+Cg1X4ciHZo9aydD0le3PC//lOZ6huPEW51azFKII2QQEG4JKFT6Q57F1tXNqw
sXi0HaW9MW3doHh589NNFFU3/7zrZfMHsh5l9cA/TY7oUZFj+lWSPhZsuoy+J7e2
7r5NfmuV35Z9v1suuEbGZ4Un0ZvVWWhW4/fVhFjEr9hjVb20kd1//EJKQoK5WMFC
MkFNpi5hIaCXiLEh7B3e95XFXddZKf/IBgeCeYSnUOHwq6TFezifah9J9polovB2
bwf+2HUh8buPUN+Zo2mxh3J/eJjvoY75dSuqk6wPRvGSkTmk8w2zToqUwFXBEoi0
on3rxJB/dpFrC/zYz8c6IuIM3Zi5FAAgOrBD4gr9M9NEnt13rwsx+YxpSgPsB/LK
3j6XMrClj1faFLEpqsrSUUMRT27m9tro353JQJhTITg9oQywi9nKixNbCM72n262
FSucD8L07p+Q+tiw+ShwjJ8CW/t97lk5b9gfbQgvVThfQrarBYml8Fj4/lK+uO9q
wjnOHzjEAN6MAxy8Nbfp3xz7LB18aShMuLLwWayKBGlECkbaGj0eH1+ZfvF6QPOq
CsUnzFFR4TyeITNJyj8S1LrMUxMzPyHgTVHShECDrjILJJnSt4yzGZXMweoWV62n
AwHqiP+sEEOu7ihOySsoW/3kqpxKhAoNxbW4Kh1Lk2KgebLjcdfDIQQLK0N0VXu5
wHO80TEZVEqyfOeJTST/jA==

View file

@ -1,67 +0,0 @@
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
EjIMJeXgdGFW7PEdY/kROQ==

View file

@ -1,20 +0,0 @@
*.pyc
*.pyo
*.so
*.xml
*.iml
id.conf
lbrycrd-cli
lbrycrd-osx.zip
lbrycrd-tx
lbrycrdd
lbrynet.*.dmg
LBRY.app

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

View file

@ -1,11 +0,0 @@
badge_icon = 'app.icns'
icon_locations = {
'LBRY.app': (115, 164),
'Applications': (387, 164)
}
background='dmg_background.png'
default_view='icon-view'
symlinks = { 'Applications': '/Applications' }
window_rect=((200, 200), (500, 320))
files = [ 'LBRY.app' ]
icon_size=128

View file

@ -1,60 +0,0 @@
import os
import json
import webbrowser
import subprocess
import sys
from time import sleep
from jsonrpc.proxy import JSONRPCProxy
API_CONNECTION_STRING = "http://localhost:5279/lbryapi"
UI_ADDRESS = "http://localhost:5279"
class LBRYURIHandler(object):
def __init__(self):
self.started_daemon = False
self.daemon = JSONRPCProxy.from_url(API_CONNECTION_STRING)
def handle_osx(self, lbry_name):
try:
status = self.daemon.is_running()
except:
os.system("open /Applications/LBRY.app")
sleep(3)
if lbry_name == "lbry" or lbry_name == "":
webbrowser.open(UI_ADDRESS)
else:
webbrowser.open(UI_ADDRESS + "/?show=" + lbry_name)
def handle_linux(self, lbry_name):
try:
status = self.daemon.is_running()
except:
cmd = r'DIR = "$( cd "$(dirname "${BASH_SOURCE[0]}" )" && pwd )"' \
r'if [-z "$(pgrep lbrynet-daemon)"]; then' \
r'echo "running lbrynet-daemon"' \
r'$DIR / lbrynet - daemon &' \
r'sleep 3 # let the daemon load before connecting' \
r'fi'
subprocess.Popen(cmd, shell=True)
if lbry_name == "lbry" or lbry_name == "":
webbrowser.open(UI_ADDRESS)
else:
webbrowser.open(UI_ADDRESS + "/?show=" + lbry_name)
def main(args):
if len(args) != 1:
args = ['lbry://lbry']
name = args[0][7:]
if sys.platform == "darwin":
LBRYURIHandler().handle_osx(lbry_name=name)
else:
LBRYURIHandler().handle_linux(lbry_name=name)
if __name__ == "__main__":
main(sys.argv[1:])

View file

@ -1,71 +0,0 @@
import AppKit
import webbrowser
import sys
import logging
import platform
from twisted.internet import reactor
from lbrynet.lbrynet_daemon import DaemonControl
from lbrynet import analytics
from lbrynet import conf
from lbrynet.core import utils
if platform.mac_ver()[0] >= "10.10":
from LBRYNotify import LBRYNotify
log = logging.getLogger(__name__)
def test_internet_connection():
return utils.check_connection()
class LBRYDaemonApp(AppKit.NSApplication):
def finishLaunching(self):
self.connection = False
statusbar = AppKit.NSStatusBar.systemStatusBar()
self.statusitem = statusbar.statusItemWithLength_(AppKit.NSVariableStatusItemLength)
self.icon = AppKit.NSImage.alloc().initByReferencingFile_(conf.settings['ICON_PATH'])
self.icon.setScalesWhenResized_(True)
self.icon.setSize_((20, 20))
self.statusitem.setImage_(self.icon)
self.menubarMenu = AppKit.NSMenu.alloc().init()
self.open = AppKit.NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(
"Open", "openui:", "")
self.menubarMenu.addItem_(self.open)
self.quit = AppKit.NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(
"Quit", "applicationShouldTerminate:", "")
self.menubarMenu.addItem_(self.quit)
self.statusitem.setMenu_(self.menubarMenu)
self.statusitem.setToolTip_(conf.settings['APP_NAME'])
if test_internet_connection():
notify("Starting LBRY")
else:
notify("LBRY needs an internet connection to start, try again when one is available")
sys.exit(0)
DaemonControl.start_server_and_listen(
launchui=True, use_auth=False,
analytics_manager=analytics.Manager.new_instance()
)
def openui_(self, sender):
webbrowser.open(conf.settings.get_ui_address())
# this code is from the example
# https://pythonhosted.org/pyobjc/examples/Cocoa/Twisted/WebServicesTool/index.html
def applicationShouldTerminate_(self, sender):
if reactor.running:
log.info('Stopping twisted event loop')
notify("Goodbye!")
reactor.stop()
return False
return True
def notify(msg):
if platform.mac_ver()[0] >= "10.10":
LBRYNotify(msg)

View file

@ -1,31 +0,0 @@
import Foundation
import objc
NSUserNotification = objc.lookUpClass('NSUserNotification')
NSUserNotificationCenter = objc.lookUpClass('NSUserNotificationCenter')
def LBRYNotify(message):
notification = NSUserNotification.alloc().init()
notification.setTitle_("LBRY")
notification.setSubtitle_("")
notification.setInformativeText_(message)
notification.setUserInfo_({})
notification.setSoundName_("NSUserNotificationDefaultSoundName")
notification.setDeliveryDate_(
Foundation.NSDate.dateWithTimeInterval_sinceDate_(0, Foundation.NSDate.date()))
NSUserNotificationCenter.defaultUserNotificationCenter().scheduleNotification_(notification)
def notify(title, subtitle, info_text, delay=0, sound=False, userInfo=None):
userInfo = userInfo or {}
notification = NSUserNotification.alloc().init()
notification.setTitle_(title)
notification.setSubtitle_(subtitle)
notification.setInformativeText_(info_text)
notification.setUserInfo_(userInfo)
if sound:
notification.setSoundName_("NSUserNotificationDefaultSoundName")
notification.setDeliveryDate_(
Foundation.NSDate.dateWithTimeInterval_sinceDate_(delay, Foundation.NSDate.date()))
NSUserNotificationCenter.defaultUserNotificationCenter().scheduleNotification_(notification)

View file

@ -1,31 +0,0 @@
from PyObjCTools import AppHelper
from twisted.internet.cfreactor import install
install(runner=AppHelper.runEventLoop)
from twisted.internet import reactor
import logging
from lbrynet import conf
from lbrynet.core import log_support
from LBRYApp import LBRYDaemonApp
log = logging.getLogger()
def main():
conf.initialize_settings()
log_file = conf.settings.get_log_filename()
log_support.configure_logging(log_file, console=True)
app = LBRYDaemonApp.sharedApplication()
reactor.addSystemEventTrigger("after", "shutdown", shutdown)
reactor.run()
def shutdown():
log.info('Stopping event loop')
AppHelper.stopEventLoop()
if __name__ == "__main__":
main()

View file

@ -1,29 +0,0 @@
#!/usr/bin/env python
import os
from setuptools import setup
from lbrynet import conf
APP = [os.path.join('lbrygui', 'main.py')]
DATA_FILES = []
DATA_FILES.append('app.icns')
OPTIONS = {
'iconfile': conf.ICON_PATH,
'plist': {
'CFBundleIdentifier': 'io.lbry.LBRY',
'LSUIElement': True,
},
'packages': [
'lbrynet', 'lbryum', 'requests', 'certifi',
'pkg_resources', 'json', 'jsonrpc', 'seccure',
],
}
setup(
name=conf.APP_NAME,
app=APP,
options={'py2app': OPTIONS},
data_files=DATA_FILES,
)

View file

@ -1,128 +0,0 @@
#!/bin/bash
set -o errexit
set -o xtrace
DEST=`pwd`
tmp="${DEST}/build"
ON_TRAVIS=false
rm -rf build dist LBRY.app
echo "Updating lbrynet"
if [ -z ${TRAVIS_BUILD_DIR+x} ]; then
# building locally
mkdir -p $tmp
cd $tmp
git clone --depth 1 http://github.com/lbryio/lbry.git
cd lbry
LBRY="${tmp}/lbry"
else
# building on travis
ON_TRAVIS=true
cd ${TRAVIS_BUILD_DIR}
LBRY=${TRAVIS_BUILD_DIR}
fi
pip install wheel
MODULES="pyobjc-core==3.1.1 pyobjc-framework-Cocoa==3.1.1 pyobjc-framework-CFNetwork==3.1.1 pyobjc-framework-Quartz==3.1.1"
if [ ${ON_TRAVIS} = true ]; then
WHEEL_DIR="${TRAVIS_BUILD_DIR}/cache/wheel"
mkdir -p "${WHEEL_DIR}"
# mapping from the package name to the
# actual built wheel file is surprisingly
# hard so instead of checking for the existance
# of each wheel, we mark with a file when they've all been
# built and skip when that file exists
for MODULE in ${MODULES}; do
if [ ! -f "${WHEEL_DIR}"/${MODULE}.finished ]; then
pip wheel -w "${WHEEL_DIR}" ${MODULE}
touch "${WHEEL_DIR}"/${MODULE}.finished
pip install ${MODULE}
fi
done
fi
pip install $MODULES
pip install dmgbuild==1.1.0
export PATH=${PATH}:/Library/Frameworks/Python.framework/Versions/2.7/bin
# pyopenssl is needed because OSX ships an old version of openssl by default
# and python will use it without pyopenssl
pip install PyOpenSSL jsonrpc certifi
NAME=`python setup.py --name`
VERSION=`python setup.py -V`
pip install -r requirements.txt
if [ -z ${SKIP_PYLINT+x} ]; then
pip install pylint
./run_pylint.sh packaging/osx/lbry-osx-app/lbrygui/
fi
python setup.py install
echo "Building URI Handler"
cd "${DEST}"
if [ ! -d "py2app" ]; then
hg clone https://bitbucket.org/ronaldoussoren/py2app
cd py2app
hg checkout py2app-0.10
# this commit fixes a bug that should have been fixed as part of 0.10
hg graft 149c25c413420120d3f383a9e854a17bc10d96fd
pip install .
cd ..
rm -rf py2app
fi
rm -rf build dist
python setup_uri_handler.py py2app
echo "Signing URI Handler"
codesign -s "${LBRY_DEVELOPER_ID}" -f "${DEST}/dist/LBRYURIHandler.app/Contents/Frameworks/Python.framework/Versions/2.7"
codesign -s "${LBRY_DEVELOPER_ID}" -f "${DEST}/dist/LBRYURIHandler.app/Contents/MacOS/python"
# not sure if --deep is appropriate here, but need to get LBRYURIHandler.app/Contents/Frameworks/libcrypto.1.0.0.dylib signed
codesign --deep -s "${LBRY_DEVELOPER_ID}" -f "${DEST}/dist/LBRYURIHandler.app/Contents/MacOS/LBRYURIHandler"
codesign -vvvv "${DEST}/dist/LBRYURIHandler.app"
# py2app will skip _cffi_backend without explicitly including it
# and without this, we will get SSL handshake errors when connecting
# to bittrex
python setup_app.py py2app -i _cffi_backend
echo "Removing i386 libraries"
remove_arch () {
if [[ `lipo "$2" -verify_arch "$1"` ]]; then
lipo -output build/lipo.tmp -remove "$1" "$2" && mv build/lipo.tmp "$2"
fi
}
for i in `find dist/LBRY.app/Contents/Resources/lib/python2.7/lib-dynload/ -name "*.so"`; do
remove_arch i386 $i
done
echo "Moving LBRYURIHandler.app into LBRY.app"
mv "${DEST}/dist/LBRYURIHandler.app" "${DEST}/dist/LBRY.app/Contents/Resources"
echo "Signing LBRY.app"
codesign -s "${LBRY_DEVELOPER_ID}" -f "${DEST}/dist/LBRY.app/Contents/Frameworks/Python.framework/Versions/2.7"
codesign -s "${LBRY_DEVELOPER_ID}" -f "${DEST}/dist/LBRY.app/Contents/Frameworks/libgmp.10.dylib"
codesign -s "${LBRY_DEVELOPER_ID}" -f "${DEST}/dist/LBRY.app/Contents/MacOS/python"
# adding deep here as well because of subcomponent issues
codesign --deep -s "${LBRY_DEVELOPER_ID}" -f "${DEST}/dist/LBRY.app/Contents/MacOS/LBRY"
codesign -vvvv "${DEST}/dist/LBRY.app"
rm -rf $tmp
mv dist/LBRY.app LBRY.app
if [ -z ${SKIP_DMG+x} ]; then
rm -rf dist "${NAME}.${VERSION}.dmg"
dmgbuild -s dmg_settings.py "LBRY" "${NAME}.${VERSION}.dmg"
fi

View file

@ -1,26 +0,0 @@
from setuptools import setup
import os
from lbrynet import conf
APP = [os.path.join('lbry_uri_handler', 'LBRYURIHandler.py')]
DATA_FILES = []
OPTIONS = {'argv_emulation': True,
'packages': ['jsonrpc'],
'plist': {
'LSUIElement': True,
'CFBundleIdentifier': 'io.lbry.LBRYURIHandler',
'CFBundleURLTypes': [
{
'CFBundleURLTypes': 'LBRYURIHandler',
'CFBundleURLSchemes': [conf.PROTOCOL_PREFIX]
}
]
}
}
setup(
app=APP,
data_files=DATA_FILES,
options={'py2app': OPTIONS},
setup_requires=['py2app'],
)

View file

@ -1,48 +0,0 @@
#!/bin/bash
#
# This script is used by travis to install lbry from source
#
set -euo pipefail
set -o xtrace
SUDO=''
if (( $EUID != 0 )); then
SUDO='sudo'
fi
if [ -z ${TRAVIS+x} ]; then
# if not on travis, its nice to see progress
QUIET=""
else
QUIET="-qq"
fi
# get the required OS packages
$SUDO apt-get ${QUIET} update
$SUDO apt-get ${QUIET} install -y --no-install-recommends \
build-essential python-dev libffi-dev libssl-dev git \
libgmp3-dev wget ca-certificates python-virtualenv
# create a virtualenv so we don't muck with anything on the system
virtualenv venv
# need to unset these or else we can't activate
set +eu
source venv/bin/activate
set -eu
# need a modern version of pip (more modern than ubuntu default)
wget https://bootstrap.pypa.io/get-pip.py
python get-pip.py
rm get-pip.py
pip install -r requirements.txt
pip install cython
pip install unqlite
pip install mock pylint coveralls
# have to do `which trial` instead of simply trial because coverage needs the full path
coverage run --source=lbrynet `which trial` tests
coveralls
./run_pylint.sh

View file

@ -1,35 +0,0 @@
#!/bin/bash
#
# Configure build-specific things
#
set -euo pipefail
set -o xtrace
# changes to this script also need to be added to build.ps1 for windows
add_ui() {
wget https://s3.amazonaws.com/lbry-ui/development/dist.zip -O dist.zip
unzip -oq dist.zip -d lbrynet/resources/ui
wget https://s3.amazonaws.com/lbry-ui/development/data.json -O lbrynet/resources/ui/data.json
}
set_build() {
local file="lbrynet/build_type.py"
# cannot use 'sed -i' because BSD sed and GNU sed are incompatible
sed 's/^\(BUILD = "\)[^"]\+\(".*\)$/\1'"${1}"'\2/' "$file" > tmpbuildfile
mv -- tmpbuildfile "$file"
}
IS_RC_REGEX="v[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+rc[[:digit:]]+"
if [[ -z "$TRAVIS_TAG" ]]; then
python packaging/append_sha_to_version.py lbrynet/__init__.py "${TRAVIS_COMMIT}"
add_ui
set_build "qa"
elif [[ "$TRAVIS_TAG" =~ $IS_RC_REGEX ]]; then
# If the tag looks like v0.7.6rc0 then this is a tagged release candidate.
add_ui
set_build "rc"
else
set_build "release"
fi

View file

@ -1,25 +0,0 @@
#!/bin/sh
set -euo pipefail
set -o xtrace
wget https://www.python.org/ftp/python/2.7.11/python-2.7.11-macosx10.6.pkg
sudo installer -pkg python-2.7.11-macosx10.6.pkg -target /
pip install -U pip
brew update
# follow this pattern to avoid failing if its already
# installed by brew:
# http://stackoverflow.com/a/20802425
if brew ls --versions gmp > /dev/null; then
echo 'gmp is already installed by brew'
else
brew install gmp
fi
if brew ls --versions openssl > /dev/null; then
echo 'openssl is already installed by brew'
else
brew install openssl
brew link --force openssl
fi

View file

@ -1,5 +0,0 @@
# package scripts
How to build LBRY packages.
For best results, run on a fresh image.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

View file

@ -1,48 +0,0 @@
#!/bin/bash
set -euo pipefail
urlencode() {
local LANG=C
local length="${#1}"
for (( i = 0; i < length; i++ )); do
local c="${1:i:1}"
case $c in
[a-zA-Z0-9.~_-]) printf "$c" ;;
*) printf '%%%02X' "'$c" ;;
esac
done
}
# find true dir of executable
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
SOURCE="$(readlink "$SOURCE")"
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
if [ -z "$(pgrep lbrynet-daemon)" ]; then
echo "running lbrynet-daemon"
$DIR/lbrynet-daemon &
sleep 3 # let the daemon load before connecting
fi
ARG=${1:-}
if [ -z "$ARG" ]; then
URL=""
else
NAME=$(echo "$ARG" | cut -c 8-)
if [ -z "$NAME" -o "$NAME" == "lbry" ]; then
URL=""
else
URL="/?show=$(urlencode "$NAME")"
fi
fi
/usr/bin/xdg-open "http://localhost:5279$URL"

View file

@ -1,11 +0,0 @@
description "LBRY Daemon"
#start on (local-filesystems and net-device-up IFACE=eth0)
stop on runlevel [016]
#expect fork
respawn
respawn limit 5 20
exec /opt/venvs/lbrynet/bin/lbrynet-daemon

View file

@ -1,19 +0,0 @@
[Desktop Entry]
Version=0.8.7
Name=LBRY
Comment=The world's first user-owned content marketplace
Icon=lbry
GenericName=Content Marketplace
Categories=Network;Internet;Filesharing
Terminal=false
Type=Application
MimeType=x-scheme-handler/lbry;
Exec=/usr/bin/lbry %U
Actions=StopDaemon;
[Desktop Action StopDaemon]
Name=Stop Daemon
Exec=/opt/venvs/lbrynet/bin/stop-lbrynet-daemon

View file

@ -1,15 +0,0 @@
(
if hash zenity 2>/dev/null; then
sleep 3
zenity --info --icon-name="system-software-install" \
--text="\
<span size=\"xx-large\">LBRY Installed</span>\n\nLBRY has been installed.\n\n\
Please start LBRY by running <b><tt>lbry</tt></b> from the command line or selecting <b>LBRY</b> from the application menu.\n\n\
If you need help or have any questions, join us on Slack (<tt>https://slack.lbry.io</tt>) or email <tt>hello@lbry.io</tt>.\
"
fi
) &

View file

@ -1,204 +0,0 @@
#!/bin/bash
set -euo pipefail
function HELP {
echo "Build a debian package for lbry"
echo "-----"
echo "When run without any arguments, this script expects the current directory"
echo "to be the main lbry repo and it builds what is in that directory"
echo
echo "Optional arguments:"
echo
echo "-c: clone a fresh copy of the repo"
echo "-b <branch>: use the specified branch of the lbry repo"
echo "-w <web-ui-branch>: set the webui branch"
echo "-d <build-dir>: specifiy the build directory"
echo "-h: show help"
echo "-t: turn trace on"
exit 1
}
CLONE=false
BUILD_DIR=""
BRANCH=""
WEB_UI_BRANCH="master"
while getopts :hctb:w:d: FLAG; do
case $FLAG in
c)
CLONE=true
;;
b)
BRANCH=${OPTARG}
;;
w)
WEB_UI_BRANCH=${OPTARG}
;;
d)
BUILD_DIR=${OPTARG}
;;
t)
set -o xtrace
;;
h)
HELP
;;
\?) #unrecognized option - show help
echo "Option -$OPTARG not allowed."
HELP
;;
:)
echo "Option -$OPTARG requires an argument."
HELP
;;
esac
done
shift $((OPTIND-1))
SUDO=''
if (( $EUID != 0 )); then
SUDO='sudo'
fi
if [ "$CLONE" = false ]; then
if [ `basename $PWD` != "lbry" ]; then
echo "Not currently in the lbry directory. Cowardly refusing to go forward"
exit 1
fi
SOURCE_DIR=$PWD
fi
if [ -z "${BUILD_DIR}" ]; then
if [ "$CLONE" = true ]; then
# build in the current directory
BUILD_DIR="lbry-build-$(date +%Y%m%d-%H%M%S)"
else
BUILD_DIR="../lbry-build-$(date +%Y%m%d-%H%M%S)"
fi
fi
mkdir -p "$BUILD_DIR"
cd "$BUILD_DIR"
if [ -z ${TRAVIS+x} ]; then
# if not on travis, its nice to see progress
QUIET=""
else
QUIET="-qq"
fi
# get the required OS packages
$SUDO apt-get ${QUIET} update
$SUDO apt-get ${QUIET} install -y --no-install-recommends software-properties-common
$SUDO add-apt-repository -y ppa:spotify-jyrki/dh-virtualenv
$SUDO apt-get ${QUIET} update
$SUDO apt-get ${QUIET} install -y --no-install-recommends \
build-essential git python-dev libffi-dev libssl-dev \
libgmp3-dev dh-virtualenv debhelper wget python-pip fakeroot
# need a modern version of pip (more modern than ubuntu default)
$SUDO pip install --upgrade pip
$SUDO pip install git+https://github.com/jobevers/make-deb
# build packages
#
# dpkg-buildpackage outputs its results into '..' so
# we need to move/clone lbry into the build directory
if [ "$CLONE" == true ]; then
git clone https://github.com/lbryio/lbry.git
else
cp -a $SOURCE_DIR lbry
fi
(
cd lbry
if [ -n "${BRANCH}" ]; then
git checkout "${BRANCH}"
fi
make-deb
dpkg-buildpackage -us -uc
)
### insert our extra files
# extract .deb
PACKAGE="$(ls | grep '.deb')"
ar vx "$PACKAGE"
mkdir control data
tar -xzf control.tar.gz --directory control
# The output of the travis build is a
# tar.gz and the output locally is tar.xz.
# Instead of having tar detect the compression used, we
# could update the config to output the same in either spot.
# Unfortunately, doing so requires editting some auto-generated
# files: http://linux.spiney.org/forcing_gzip_compression_when_building_debian_packages
tar -xf data.tar.?z --directory data
PACKAGING_DIR='lbry/packaging/ubuntu'
# set web ui branch
sed -i "s/^WEB_UI_BRANCH='[^']\+'/WEB_UI_BRANCH='$WEB_UI_BRANCH'/" "$PACKAGING_DIR/lbry"
# add files
function addfile() {
FILE="$1"
TARGET="$2"
mkdir -p "$(dirname "data/$TARGET")"
cp -d "$FILE" "data/$TARGET"
echo "$(md5sum "data/$TARGET" | cut -d' ' -f1) $TARGET" >> control/md5sums
}
function addlink() {
SRC="$1"
TARGET="$2"
TMP="$PACKAGING_DIR/lbry-temp-symlink"
ln -s "$SRC" "$TMP"
addfile "$TMP" "$TARGET"
rm "$TMP"
}
# add icons
addfile "$PACKAGING_DIR/icons/lbry32.png" usr/share/icons/hicolor/32x32/apps/lbry.png
addfile "$PACKAGING_DIR/icons/lbry48.png" usr/share/icons/hicolor/48x48/apps/lbry.png
addfile "$PACKAGING_DIR/icons/lbry96.png" usr/share/icons/hicolor/96x96/apps/lbry.png
addfile "$PACKAGING_DIR/icons/lbry128.png" usr/share/icons/hicolor/128x128/apps/lbry.png
addfile "$PACKAGING_DIR/icons/lbry256.png" usr/share/icons/hicolor/256x256/apps/lbry.png
addfile "$PACKAGING_DIR/lbry.desktop" usr/share/applications/lbry.desktop
# add lbry executable script
BINPATH=opt/venvs/lbrynet/bin
addfile "$PACKAGING_DIR/lbry" "$BINPATH/lbry"
# symlink scripts into /usr/bin
for script in "lbry" "lbrynet-daemon" "lbrynet-cli" "stop-lbrynet-daemon"; do
addlink "/$BINPATH/$script" "usr/bin/$script"
done
# add postinstall script
cat "$PACKAGING_DIR/postinst_append" >> control/postinst
# change package name from lbrynet to lbry
sed -i 's/^Package: lbrynet/Package: lbry/' control/control
echo "Conflicts: lbrynet (<< 0.3.5)" >> control/control
echo "Replaces: lbrynet (<< 0.3.5)" >> control/control
# repackage .deb
$SUDO chown -R root:root control data
tar -czf control.tar.gz -C control .
tar -cJf data.tar.xz -C data .
$SUDO chown root:root debian-binary control.tar.gz data.tar.xz
ar r "$PACKAGE" debian-binary control.tar.gz data.tar.xz
# TODO: we can append to data.tar instead of extracting it all and recompressing
if [[ ! -z "${TRAVIS_BUILD_DIR+x}" ]]; then
# move it to a consistent place so that later it can be uploaded
# to the github releases page
mv "${PACKAGE}" "${TRAVIS_BUILD_DIR}/${PACKAGE}"
# want to be able to check the size of the result in the log
ls -l "${TRAVIS_BUILD_DIR}/${PACKAGE}"
fi

View file

@ -1,38 +0,0 @@
# this is a port of setup_build.sh used for the unix platforms
function AddUi {
wget https://s3.amazonaws.com/lbry-ui/development/dist.zip -OutFile dist.zip
if ($LastExitCode -ne 0) { $host.SetShouldExit($LastExitCode) }
Expand-Archive dist.zip -dest lbrynet\resources\ui
if ($LastExitCode -ne 0) { $host.SetShouldExit($LastExitCode) }
wget https://s3.amazonaws.com/lbry-ui/development/data.json -OutFile lbrynet\resources\ui\data.json
if ($LastExitCode -ne 0) { $host.SetShouldExit($LastExitCode) }
}
function SetBuild([string]$build) {
(Get-Content lbrynet\build_type.py).replace('dev', $build) | Set-Content lbrynet\build_type.py
if ($LastExitCode -ne 0) { $host.SetShouldExit($LastExitCode) }
}
If (${Env:APPVEYOR_REPO_TAG} -NotMatch "true") {
C:\Python27\python.exe packaging\append_sha_to_version.py lbrynet\__init__.py ${Env:APPVEYOR_REPO_COMMIT}
if ($LastExitCode -ne 0) { $host.SetShouldExit($LastExitCode) }
AddUi
SetBuild "qa"
}
ElseIf (${Env:APPVEYOR_REPO_TAG_NAME} -Match "v\d+\.\d+\.\d+rc\d+") {
# If the tag looks like v0.7.6rc0 then this is a tagged release candidate.
AddUi
SetBuild "rc"
}
Else {
SetBuild "release"
}
C:\Python27\python.exe setup.py build bdist_msi
if ($LastExitCode -ne 0) { $host.SetShouldExit($LastExitCode) }
signtool.exe sign /f packaging\windows\certs\lbry2.pfx /p %key_pass% /tr http://tsa.starfieldtech.com /td SHA256 /fd SHA256 dist\*.msi

View file

@ -1,100 +0,0 @@
$env:Path += ";C:\MinGW\bin\"
$env:Path += ";C:\Program Files (x86)\Windows Kits\10\bin\x86\"
gcc --version
mingw32-make --version
mkdir C:\temp
Invoke-WebRequest "https://pypi.python.org/packages/55/90/e987e28ed29b571f315afea7d317b6bf4a551e37386b344190cffec60e72/miniupnpc-1.9.tar.gz" -OutFile "C:\temp\miniupnpc-1.9.tar.gz"
cd C:\temp
7z e miniupnpc-1.9.tar.gz
7z x miniupnpc-1.9.tar
cd C:\temp\miniupnpc-1.9
mingw32-make.exe -f Makefile.mingw
C:\Python27\python.exe C:\temp\miniupnpc-1.9\setupmingw32.py build --compiler=mingw32
C:\Python27\python.exe C:\temp\miniupnpc-1.9\setupmingw32.py install
Invoke-WebRequest "https://github.com/lbryio/lbry/raw/master/packaging/windows/libs/gmpy-1.17-cp27-none-win32.whl" -OutFile "C:\temp\gmpy-1.17-cp27-none-win32.whl"
C:\Python27\Scripts\pip.exe install "C:\temp\gmpy-1.17-cp27-none-win32.whl"
C:\Python27\Scripts\pip.exe install pypiwin32==219
C:\Python27\Scripts\pip.exe install six==1.9.0
C:\Python27\Scripts\pip.exe install requests==2.9.1
C:\Python27\Scripts\pip.exe install zope.interface==4.1.3
# this is a patched to allow version numbers with non-integer values
# and it is branched off of 4.3.3
C:\Python27\Scripts\pip.exe install https://bitbucket.org/jobevers/cx_freeze/get/handle-version.tar.gz
C:\Python27\Scripts\pip.exe install cython==0.24.1
C:\Python27\Scripts\pip.exe install Twisted==16.0.0
C:\Python27\Scripts\pip.exe install Yapsy==1.11.223
C:\Python27\Scripts\pip.exe install appdirs==1.4.0
C:\Python27\Scripts\pip.exe install argparse==1.2.1
C:\Python27\Scripts\pip.exe install colorama==0.3.7
C:\Python27\Scripts\pip.exe install dnspython==1.12.0
C:\Python27\Scripts\pip.exe install ecdsa==0.13
C:\Python27\Scripts\pip.exe install envparse==0.2.0
C:\Python27\Scripts\pip.exe install jsonrpc==1.2
C:\Python27\Scripts\pip.exe install jsonrpclib==0.1.7
C:\Python27\Scripts\pip.exe install loggly-python-handler==1.0.0
C:\Python27\Scripts\pip.exe install pbkdf2==1.3
C:\Python27\Scripts\pip.exe install protobuf==3.0.0
C:\Python27\Scripts\pip.exe install pycrypto==2.6.1
C:\Python27\Scripts\pip.exe install python-bitcoinrpc==0.1
C:\Python27\Scripts\pip.exe install pyyaml==3.12
C:\Python27\Scripts\pip.exe install qrcode==5.2.2
C:\Python27\Scripts\pip.exe install requests_futures==0.9.7
C:\Python27\Scripts\pip.exe install seccure==0.3.1.3
C:\Python27\Scripts\pip.exe install simplejson==3.8.2
C:\Python27\Scripts\pip.exe install slowaes==0.1a1
C:\Python27\Scripts\pip.exe install txJSON-RPC==0.5
C:\Python27\Scripts\pip.exe install unqlite==0.5.3
C:\Python27\Scripts\pip.exe install wsgiref==0.1.2
C:\Python27\Scripts\pip.exe install base58==0.2.2
C:\Python27\Scripts\pip.exe install googlefinance==0.7
C:\Python27\Scripts\pip.exe install jsonschema==2.5.1
C:\Python27\Scripts\pip.exe install git+https://github.com/lbryio/lbryum.git
cd C:\projects\lbry

View file

@ -1,15 +0,0 @@
C:\Python27\python.exe setup.py install
# If this is a build because of a tag, make sure that
# its either a testing tag or a tag that matches the version
# specified in the source code.
If (${Env:APPVEYOR_REPO_TAG} -Match "true") {
If (${Env:APPVEYOR_REPO_TAG_NAME} -Like "test*") {
exit 0
}
# non-testing tags should be in the form v1.2.3
If ("v$(C:\Python27\python.exe setup.py -V)" -Match ${Env:APPVEYOR_REPO_TAG_NAME}) {
exit 0
}
exit 1
}

View file

@ -1,15 +0,0 @@
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\lbry]
@="URL:LBRY Protocol"
"URL Protocol"=""
[HKEY_CLASSES_ROOT\lbry\DefaultIcon]
@="\"LBRY.exe,1\""
[HKEY_CLASSES_ROOT\lbry\shell]
[HKEY_CLASSES_ROOT\lbry\shell\open]
[HKEY_CLASSES_ROOT\lbry\shell\open\command]
@="\"C:\\Program Files (x86)\\LBRY\\LBRY.exe\" \"%1\""

View file

@ -1,302 +0,0 @@
import logging
import os
import sys
import threading
import webbrowser
import win32api
import win32con
import win32gui_struct
from jsonrpc.proxy import JSONRPCProxy
from twisted.internet import reactor, error
try:
import winxpgui as win32gui
except ImportError:
import win32gui
from lbrynet import conf, analytics
from lbrynet.core import log_support
from lbrynet.core import utils
from lbrynet.lbrynet_daemon import DaemonControl
from lbrynet import conf
from uri_handler.LBRYURIHandler import LBRYURIHandler
log = logging.getLogger(__name__)
def test_internet_connection():
return utils.check_connection()
def non_string_iterable(obj):
try:
iter(obj)
except TypeError:
return False
else:
return not isinstance(obj, basestring)
class SysTrayIcon(object):
"""TODO"""
QUIT = 'QUIT'
SPECIAL_ACTIONS = [QUIT]
FIRST_ID = 1023
def __init__(self,
icon,
hover_text,
menu_options,
on_quit=None,
default_menu_index=None,
window_class_name=None, ):
self.icon = icon
self.hover_text = hover_text
self.on_quit = on_quit
menu_options = menu_options + (('Quit', None, self.QUIT),)
self._next_action_id = self.FIRST_ID
self.menu_actions_by_id = set()
self.menu_options = self._add_ids_to_menu_options(list(menu_options))
self.menu_actions_by_id = dict(self.menu_actions_by_id)
del self._next_action_id
self.default_menu_index = (default_menu_index or 0)
self.window_class_name = window_class_name or "SysTrayIconPy"
message_map = {win32gui.RegisterWindowMessage("TaskbarCreated"): self.restart,
win32con.WM_DESTROY: self.destroy,
win32con.WM_COMMAND: self.command,
win32con.WM_USER + 20: self.notify,}
# Register the Window class.
window_class = win32gui.WNDCLASS()
hinst = window_class.hInstance = win32gui.GetModuleHandle(None)
window_class.lpszClassName = self.window_class_name
window_class.style = win32con.CS_VREDRAW | win32con.CS_HREDRAW;
window_class.hCursor = win32gui.LoadCursor(0, win32con.IDC_ARROW)
window_class.hbrBackground = win32con.COLOR_WINDOW
window_class.lpfnWndProc = message_map # could also specify a wndproc.
classAtom = win32gui.RegisterClass(window_class)
# Create the Window.
style = win32con.WS_OVERLAPPED | win32con.WS_SYSMENU
self.hwnd = win32gui.CreateWindow(classAtom,
self.window_class_name,
style,
0,
0,
win32con.CW_USEDEFAULT,
win32con.CW_USEDEFAULT,
0,
0,
hinst,
None)
win32gui.UpdateWindow(self.hwnd)
self.notify_id = None
self.refresh_icon()
win32gui.PumpMessages()
def _add_ids_to_menu_options(self, menu_options):
result = []
for menu_option in menu_options:
option_text, option_icon, option_action = menu_option
if callable(option_action) or option_action in self.SPECIAL_ACTIONS:
self.menu_actions_by_id.add((self._next_action_id, option_action))
result.append(menu_option + (self._next_action_id,))
elif non_string_iterable(option_action):
result.append((option_text,
option_icon,
self._add_ids_to_menu_options(option_action),
self._next_action_id))
else:
print 'Unknown item', option_text, option_icon, option_action
self._next_action_id += 1
return result
def refresh_icon(self):
# Try and find a custom icon
hinst = win32gui.GetModuleHandle(None)
if os.path.isfile(self.icon):
icon_flags = win32con.LR_LOADFROMFILE | win32con.LR_DEFAULTSIZE
hicon = win32gui.LoadImage(hinst,
self.icon,
win32con.IMAGE_ICON,
0,
0,
icon_flags)
else:
print "Can't find icon file - using default."
hicon = win32gui.LoadIcon(0, win32con.IDI_APPLICATION)
if self.notify_id:
message = win32gui.NIM_MODIFY
else:
message = win32gui.NIM_ADD
self.notify_id = (self.hwnd,
0,
win32gui.NIF_ICON | win32gui.NIF_MESSAGE | win32gui.NIF_TIP,
win32con.WM_USER + 20,
hicon,
self.hover_text)
win32gui.Shell_NotifyIcon(message, self.notify_id)
def restart(self, hwnd, msg, wparam, lparam):
self.refresh_icon()
def destroy(self, hwnd, msg, wparam, lparam):
if self.on_quit: self.on_quit(self)
nid = (self.hwnd, 0)
win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, nid)
win32gui.PostQuitMessage(0) # Terminate the app.
def notify(self, hwnd, msg, wparam, lparam):
if lparam == win32con.WM_LBUTTONDBLCLK:
self.execute_menu_option(self.default_menu_index + self.FIRST_ID)
elif lparam == win32con.WM_RBUTTONUP:
self.show_menu()
elif lparam == win32con.WM_LBUTTONUP:
pass
return True
def show_menu(self):
menu = win32gui.CreatePopupMenu()
self.create_menu(menu, self.menu_options)
pos = win32gui.GetCursorPos()
# See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/menus_0hdi.asp
win32gui.SetForegroundWindow(self.hwnd)
win32gui.TrackPopupMenu(menu,
win32con.TPM_LEFTALIGN,
pos[0],
pos[1],
0,
self.hwnd,
None)
win32gui.PostMessage(self.hwnd, win32con.WM_NULL, 0, 0)
def create_menu(self, menu, menu_options):
for option_text, option_icon, option_action, option_id in menu_options[::-1]:
if option_icon:
option_icon = self.prep_menu_icon(option_icon)
if option_id in self.menu_actions_by_id:
item, extras = win32gui_struct.PackMENUITEMINFO(text=option_text,
hbmpItem=option_icon,
wID=option_id)
win32gui.InsertMenuItem(menu, 0, 1, item)
else:
submenu = win32gui.CreatePopupMenu()
self.create_menu(submenu, option_action)
item, extras = win32gui_struct.PackMENUITEMINFO(text=option_text,
hbmpItem=option_icon,
hSubMenu=submenu)
win32gui.InsertMenuItem(menu, 0, 1, item)
def prep_menu_icon(self, icon):
# First load the icon.
ico_x = win32api.GetSystemMetrics(win32con.SM_CXSMICON)
ico_y = win32api.GetSystemMetrics(win32con.SM_CYSMICON)
hicon = win32gui.LoadImage(
0, icon, win32con.IMAGE_ICON, ico_x, ico_y, win32con.LR_LOADFROMFILE)
hdcBitmap = win32gui.CreateCompatibleDC(0)
hdcScreen = win32gui.GetDC(0)
hbm = win32gui.CreateCompatibleBitmap(hdcScreen, ico_x, ico_y)
hbmOld = win32gui.SelectObject(hdcBitmap, hbm)
# Fill the background.
brush = win32gui.GetSysColorBrush(win32con.COLOR_MENU)
win32gui.FillRect(hdcBitmap, (0, 0, 16, 16), brush)
# unclear if brush needs to be feed. Best clue I can find is:
# "GetSysColorBrush returns a cached brush instead of allocating a new
# one." - implies no DeleteObject
# draw the icon
win32gui.DrawIconEx(hdcBitmap, 0, 0, hicon, ico_x, ico_y, 0, 0, win32con.DI_NORMAL)
win32gui.SelectObject(hdcBitmap, hbmOld)
win32gui.DeleteDC(hdcBitmap)
return hbm
def command(self, hwnd, msg, wparam, lparam):
id = win32gui.LOWORD(wparam)
self.execute_menu_option(id)
def execute_menu_option(self, id):
menu_action = self.menu_actions_by_id[id]
if menu_action == self.QUIT:
self.exit_app()
else:
menu_action(self)
def exit_app(self):
win32gui.DestroyWindow(self.hwnd)
def main(lbry_name=None):
def LBRYApp():
return SysTrayIcon(icon, hover_text, menu_options, on_quit=stop)
def openui_(sender):
webbrowser.open(conf.settings.get_ui_address())
def replyToApplicationShouldTerminate_():
try:
reactor.stop()
except error.ReactorNotRunning:
log.debug('Reactor already stopped')
def stop(sysTrayIcon):
replyToApplicationShouldTerminate_()
if getattr(sys, 'frozen', False) and os.name == "nt":
icon = os.path.join(
os.path.dirname(sys.executable), conf.settings['ICON_PATH'], 'lbry16.ico'
)
else:
icon = os.path.join(conf.settings['ICON_PATH'], 'lbry16.ico')
hover_text = conf.settings['APP_NAME']
menu_options = (('Open', icon, openui_),)
if not test_internet_connection():
log.warn('No Internet Connection')
sys.exit(1)
systray_thread = threading.Thread(target=LBRYApp)
systray_thread.daemon = True
systray_thread.start()
DaemonControl.start_server_and_listen(
launchui=True, use_auth=False,
analytics_manager=analytics.Manager.new_instance()
)
reactor.run()
if __name__ == '__main__':
utils.setup_certs_for_windows()
conf.initialize_settings()
log_file = conf.settings.get_log_filename()
log_support.configure_logging(log_file, console=True)
lbry_daemon = JSONRPCProxy.from_url(conf.settings.get_api_connection_string())
try:
daemon_running = lbry_daemon.is_running()
start_daemon = False
except:
start_daemon = True
try:
lbry_name = LBRYURIHandler.parse_name(sys.argv[1])
except IndexError:
lbry_name = None
start_daemon = True
if start_daemon:
main(lbry_name)
else:
LBRYURIHandler.open_address(lbry_name)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 361 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

View file

@ -1,6 +0,0 @@
C:\Python27\Scripts\pip.exe install mock
C:\Python27\Scripts\pip.exe install pylint
C:\Python27\python.exe C:\Python27\Scripts\trial.py C:\projects\lbry\tests\unit
if ($LastExitCode -ne 0) { $host.SetShouldExit($LastExitCode) }
C:\Python27\Scripts\pylint.exe -E --disable=inherit-non-class --disable=no-member --ignored-modules=distutils --enable=unused-import --enable=bad-whitespace --enable=line-too-long lbrynet packaging/windows/lbry-win32-app/LBRYWin32App.py
if ($LastExitCode -ne 0) { $host.SetShouldExit($LastExitCode) }

View file

@ -1,5 +1,4 @@
Twisted==16.0.0 Twisted==16.6.0
Yapsy==1.11.223
appdirs==1.4.0 appdirs==1.4.0
argparse==1.2.1 argparse==1.2.1
colorama==0.3.7 colorama==0.3.7
@ -10,7 +9,6 @@ gmpy==1.17
jsonrpc==1.2 jsonrpc==1.2
jsonrpclib==0.1.7 jsonrpclib==0.1.7
jsonschema==2.5.1 jsonschema==2.5.1
https://github.com/lbryio/lbryum/tarball/master/#egg=lbryum
loggly-python-handler==1.0.0 loggly-python-handler==1.0.0
miniupnpc==1.9 miniupnpc==1.9
pbkdf2==1.3 pbkdf2==1.3
@ -25,7 +23,7 @@ six>=1.9.0
slowaes==0.1a1 slowaes==0.1a1
txJSON-RPC==0.5 txJSON-RPC==0.5
wsgiref==0.1.2 wsgiref==0.1.2
zope.interface==4.1.3 zope.interface==4.3.3
base58==0.2.2 base58==0.2.2
googlefinance==0.7 googlefinance==0.7
pyyaml==3.12 pyyaml==3.12

View file

@ -1,5 +1,6 @@
#! /bin/bash #! /bin/bash
set -eu
# Ignoring distutils because: https://github.com/PyCQA/pylint/issues/73 # Ignoring distutils because: https://github.com/PyCQA/pylint/issues/73
# TODO: as code quality improves, make pylint be more strict # TODO: as code quality improves, make pylint be more strict

362
setup.py
View file

@ -5,18 +5,6 @@ import os
import site import site
from lbrynet import __version__ from lbrynet import __version__
LINUX = 1
DARWIN = 2
WINDOWS = 3
if sys.platform.startswith("linux"):
platform = LINUX
elif sys.platform.startswith("darwin"):
platform = DARWIN
elif sys.platform.startswith("win"):
platform = WINDOWS
else:
raise Exception("Unknown os: %s" % sys.platform)
base_dir = os.path.abspath(os.path.dirname(__file__)) base_dir = os.path.abspath(os.path.dirname(__file__))
package_name = "lbrynet" package_name = "lbrynet"
@ -31,39 +19,38 @@ keywords = "LBRY"
# TODO: find a way to keep this in sync with requirements.txt # TODO: find a way to keep this in sync with requirements.txt
requires = [ requires = [
'Twisted==16.0.0', 'Twisted',
'Yapsy==1.11.223', 'appdirs',
'appdirs==1.4.0', 'argparse',
'argparse==1.2.1', 'colorama',
'colorama==0.3.7', 'dnspython',
'dnspython==1.12.0', 'ecdsa',
'ecdsa==0.13', 'envparse',
'envparse==0.2.0', 'gmpy',
'gmpy==1.17', 'jsonrpc',
'jsonrpc==1.2', 'jsonrpclib',
'jsonrpclib==0.1.7', 'jsonschema',
'jsonschema==2.5.1', 'lbryum',
'lbryum>=2.7.5', 'loggly-python-handler',
'loggly-python-handler==1.0.0', 'miniupnpc',
'miniupnpc==1.9', 'pbkdf2',
'pbkdf2==1.3', 'protobuf',
'protobuf==3.0.0', 'pycrypto',
'pycrypto==2.6.1', 'qrcode',
'qrcode==5.2.2', 'requests',
'requests==2.9.1', 'requests_futures',
'requests_futures==0.9.7', 'seccure',
'seccure==0.3.1.3', 'simplejson',
'simplejson==3.8.2', 'six',
'six>=1.9.0', 'slowaes',
'slowaes==0.1a1', 'txJSON-RPC',
'txJSON-RPC==0.5', 'wsgiref',
'wsgiref==0.1.2', 'zope.interface',
'zope.interface==4.1.3', 'base58',
'base58==0.2.2', 'googlefinance',
'googlefinance==0.7', 'pyyaml',
'pyyaml==3.12', 'service_identity',
'service_identity==16.0.0', 'ndg-httpsclient',
'ndg-httpsclient==0.4.2',
] ]
@ -80,273 +67,22 @@ def package_files(directory):
yield os.path.join('..', path, filename) yield os.path.join('..', path, filename)
if platform == LINUX: from setuptools import setup, find_packages
import ez_setup
ez_setup.use_setuptools()
from setuptools import setup, find_packages
requires.append('service-identity')
setup(name=package_name, setup(name=package_name,
description=description, description=description,
version=__version__, version=__version__,
maintainer=maintainer, maintainer=maintainer,
maintainer_email=maintainer_email, maintainer_email=maintainer_email,
url=url, url=url,
author=author, author=author,
keywords=keywords, keywords=keywords,
packages=find_packages(base_dir), packages=find_packages(base_dir),
install_requires=requires, install_requires=requires,
entry_points={'console_scripts': console_scripts}, entry_points={'console_scripts': console_scripts},
package_data={ package_data={
package_name: list(package_files('lbrynet/resources/ui')) package_name: list(package_files('lbrynet/resources/ui'))
} },
) zip_safe=False,
)
elif platform == DARWIN:
import ez_setup
ez_setup.use_setuptools()
from setuptools import setup, find_packages
setup(name=package_name,
description=description,
version=__version__,
maintainer=maintainer,
maintainer_email=maintainer_email,
url=url,
author=author,
keywords=keywords,
packages=find_packages(base_dir),
install_requires=requires,
entry_points={'console_scripts': console_scripts},
package_data={
package_name: list(package_files('lbrynet/resources/ui'))
},
# If this is True, setuptools tries to build an egg
# and py2app / modulegraph / imp.find_module
# doesn't like that.
zip_safe=False,
)
elif platform == WINDOWS:
import opcode
import pkg_resources
from cx_Freeze import setup, Executable
import requests.certs
app_dir = os.path.join('packaging', 'windows', 'lbry-win32-app')
daemon_dir = os.path.join('lbrynet', 'lbrynet_daemon')
win_icon = os.path.join(app_dir, 'icons', 'lbry256.ico')
wordlist_path = pkg_resources.resource_filename('lbryum', 'wordlist')
# Allow virtualenv to find distutils of base python installation
distutils_path = os.path.join(os.path.dirname(opcode.__file__), 'distutils')
schemas = os.path.join(site.getsitepackages()[1], "jsonschema", "schemas")
onlyfiles = [f for f in os.listdir(schemas) if os.path.isfile(os.path.join(schemas, f))]
zipincludes = [(os.path.join(schemas, f), os.path.join("jsonschema", "schemas", f)) for f in onlyfiles]
def find_data_file(filename):
if getattr(sys, 'frozen', False):
# The application is frozen
data_dir = os.path.dirname(sys.executable)
else:
# The application is not frozen
# Change this bit to match where you store your data files:
data_dir = os.path.dirname(__file__)
return os.path.join(data_dir, filename)
shortcut_table = [
('LBRYShortcut', # Shortcut
'DesktopFolder', # Directory
'LBRY', # Name
'TARGETDIR', # Component
'[TARGETDIR]\{0}.exe'.format(dist_name), # Target
None, # Arguments
description, # Description
None, # Hotkey
None, # Icon
None, # IconIndex
None, # ShowCmd
'TARGETDIR', # WkDir
),
# ('DaemonShortcut', # Shortcut
# 'DesktopFolder', # Directory
# 'lbrynet-daemon', # Name
# 'TARGETDIR', # Component
# '[TARGETDIR]\lbrynet-daemon.exe', # Target
# '--log-to-console', # Arguments
# description, # Description
# None, # Hotkey
# None, # Icon
# None, # IconIndex
# None, # ShowCmd
# 'TARGETDIR', # WkDir
# ),
# ('DaemonCLIShortcut', # Shortcut
# 'DesktopFolder', # Directory
# 'lbrynet-cli', # Name
# 'TARGETDIR', # Component
# '[TARGETDIR]\lbrynet-cli.exe', # Target
# None, # Arguments
# description, # Description
# None, # Hotkey
# None, # Icon
# None, # IconIndex
# None, # ShowCmd
# 'TARGETDIR', # WkDir
# ),
('ProgramMenuLBRYShortcut', # Shortcut
'ProgramMenuFolder', # Directory
# r'[ProgramMenuFolder]\lbrynet', # Directory
'LBRY', # Name
'TARGETDIR', # Component
'[TARGETDIR]\{0}.exe'.format(dist_name), # Target
None, # Arguments
description, # Description
None, # Hotkey
None, # Icon
None, # IconIndex
None, # ShowCmd
'TARGETDIR', # WkDir
),
('ProgramMenuDaemonShortcut', # Shortcut
'ProgramMenuFolder', # Directory
# r'[ProgramMenuFolder]\lbrynet', # Directory
'lbrynet-daemon', # Name
'TARGETDIR', # Component
'[TARGETDIR]\lbrynet-daemon.exe', # Target
'--log-to-console', # Arguments
description, # Description
None, # Hotkey
None, # Icon
None, # IconIndex
None, # ShowCmd
'TARGETDIR', # WkDir
),
('ProgramMenuDaemonCLIShortcut', # Shortcut
'ProgramMenuFolder', # Directory
# r'[ProgramMenuFolder]\lbrynet', # Directory
'lbrynet-cli', # Name
'TARGETDIR', # Component
'[TARGETDIR]\lbrynet-cli.exe', # Target
None, # Arguments
description, # Description
None, # Hotkey
None, # Icon
None, # IconIndex
None, # ShowCmd
'TARGETDIR', # WkDir
),
]
msi_data = {"Shortcut": shortcut_table}
bdist_msi_options = {
'upgrade_code': '{18c0e933-ad08-44e8-a413-1d0ed624c100}',
'add_to_path': True,
# Default install path is 'C:\Program Files\' for 32-bit or 'C:\Program Files (x86)\' for 64-bit
# 'initial_target_dir': r'[LocalAppDataFolder]\{0}'.format(name),
'data': msi_data
}
build_exe_options = {
'include_msvcr': True,
'includes': [],
'packages': ['cython',
'twisted',
'yapsy',
'appdirs',
'argparse',
'base58',
'colorama',
'cx_Freeze',
'dns',
'ecdsa',
'envparse',
'gmpy',
'googlefinance',
'jsonrpc',
'jsonrpclib',
'lbryum',
'loggly',
'miniupnpc',
'pbkdf2',
'google.protobuf',
'Crypto',
'bitcoinrpc',
'win32api',
'qrcode',
'requests',
'requests_futures',
'seccure',
'simplejson',
'jsonschema',
'six',
'aes',
'txjsonrpc',
'wsgiref',
'zope.interface',
'os',
'pkg_resources',
'yaml'
],
'excludes': ['distutils', 'collections.sys', 'collections._weakref', 'collections.abc',
'Tkinter', 'tk', 'tcl', 'PyQt4', 'nose', 'mock'
'zope.interface._zope_interface_coptimizations', 'leveldb'],
'include_files': [(distutils_path, 'distutils'), (requests.certs.where(), 'cacert.pem'),
(os.path.join(app_dir, 'icons', 'lbry16.ico'), os.path.join('icons', 'lbry16.ico')),
(os.path.join(app_dir, 'icons', 'lbry256.ico'), os.path.join('icons', 'lbry256.ico')),
(os.path.join(wordlist_path, 'chinese_simplified.txt'),
os.path.join('wordlist', 'chinese_simplified.txt')),
(os.path.join(wordlist_path, 'english.txt'), os.path.join('wordlist', 'english.txt')),
(os.path.join(wordlist_path, 'japanese.txt'), os.path.join('wordlist', 'japanese.txt')),
(os.path.join(wordlist_path, 'portuguese.txt'), os.path.join('wordlist', 'portuguese.txt')),
(os.path.join(wordlist_path, 'spanish.txt'), os.path.join('wordlist', 'spanish.txt'))
],
'namespace_packages': ['zope', 'google'],
"zip_includes": zipincludes}
tray_app = Executable(
script=os.path.join(app_dir, 'LBRYWin32App.py'),
base='Win32GUI',
icon=win_icon,
targetName='{0}.exe'.format(dist_name)
)
daemon_exe = Executable(
script=os.path.join(daemon_dir, 'DaemonControl.py'),
icon=win_icon,
targetName='lbrynet-daemon.exe'
)
cli_exe = Executable(
script=os.path.join(daemon_dir, 'DaemonCLI.py'),
icon=win_icon,
targetName='lbrynet-cli.exe'
)
setup(
name=package_name,
description=description,
version=__version__,
maintainer=maintainer,
maintainer_email=maintainer_email,
url=url,
author=author,
keywords=keywords,
data_files=[],
options={
'build_exe': build_exe_options,
'bdist_msi': bdist_msi_options
},
executables=[
tray_app,
daemon_exe,
cli_exe
],
package_data={
package_name: list(package_files('lbrynet/resources/ui'))
}
)

View file

@ -14,7 +14,7 @@ from tests.mocks import mock_conf_settings, FakeNetwork
class MiscTests(unittest.TestCase): class MiscTests(unittest.TestCase):
def test_get_lbrynet_version_from_github(self): def test_get_lbry_electron_client_version_from_github(self):
response = mock.create_autospec(requests.Response) response = mock.create_autospec(requests.Response)
# don't need to mock out the entire response from the api # don't need to mock out the entire response from the api
# but at least need 'tag_name' # but at least need 'tag_name'
@ -28,7 +28,9 @@ class MiscTests(unittest.TestCase):
} }
with mock.patch('lbrynet.lbrynet_daemon.Daemon.requests') as req: with mock.patch('lbrynet.lbrynet_daemon.Daemon.requests') as req:
req.get.return_value = response req.get.return_value = response
self.assertEqual('0.3.8', Daemon.get_lbrynet_version_from_github()) rv = Daemon.CheckRemoteVersion()
rv._get_lbry_electron_client_version()
self.assertEqual('0.3.8', rv.version)
def test_error_is_thrown_if_prerelease(self): def test_error_is_thrown_if_prerelease(self):
response = mock.create_autospec(requests.Response) response = mock.create_autospec(requests.Response)
@ -38,8 +40,9 @@ class MiscTests(unittest.TestCase):
} }
with mock.patch('lbrynet.lbrynet_daemon.Daemon.requests') as req: with mock.patch('lbrynet.lbrynet_daemon.Daemon.requests') as req:
req.get.return_value = response req.get.return_value = response
rv = Daemon.CheckRemoteVersion()
with self.assertRaises(Exception): with self.assertRaises(Exception):
Daemon.get_lbrynet_version_from_github() rv._get_lbry_electron_client_version()
def test_error_is_thrown_when_version_cant_be_parsed(self): def test_error_is_thrown_when_version_cant_be_parsed(self):
with self.assertRaises(Exception): with self.assertRaises(Exception):

View file

@ -1,54 +0,0 @@
import json
import os
import shutil
import tempfile
from twisted.trial import unittest
import mock
from lbrynet.lbrynet_daemon import UIManager
class BundledUIManagerTest(unittest.TestCase):
def setUp(self):
self.active_dir = tempfile.mkdtemp()
self.bundled_dir = tempfile.mkdtemp()
self.manager = UIManager.BundledUIManager(mock.Mock(), self.active_dir, self.bundled_dir)
def tearDown(self):
shutil.rmtree(self.active_dir)
shutil.rmtree(self.bundled_dir)
def test_when_bundle_is_not_available(self):
result = self.manager.setup()
self.assertFalse(result)
expected = []
self.assertEqual(os.listdir(self.active_dir), expected)
def test_when_already_bundled(self):
make_data_file(self.active_dir)
make_data_file(self.bundled_dir)
result = self.manager.setup()
self.assertTrue(result)
expected = ['data.json']
self.assertEqual(os.listdir(self.active_dir), expected)
def test_bundled_files_are_copied(self):
make_data_file(self.active_dir)
make_data_file(self.bundled_dir, 'BARFOO')
touch(os.path.join(self.bundled_dir, 'test.html'))
result = self.manager.setup()
self.assertTrue(result)
self.assertEqual('BARFOO', self.manager.version())
expected = ['data.json', 'test.html']
self.assertItemsEqual(os.listdir(self.active_dir), expected)
def make_data_file(directory, sha='FOOBAR'):
with open(os.path.join(directory, 'data.json'), 'w') as f:
json.dump({'sha': sha}, f)
def touch(filename):
with open(filename, 'a') as f:
pass

View file

@ -1,90 +0,0 @@
import os
import webbrowser
import subprocess
import sys
from time import sleep
from lbrynet.lbrynet_daemon.auth.client import LBRYAPIClient
from lbrynet import conf
class LBRYURIHandler(object):
def __init__(self):
self.started_daemon = False
self.daemon = LBRYAPIClient.get_client()
def handle_osx(self, lbry_name):
self.check_daemon()
if not self.started_daemon:
os.system("open /Applications/LBRY.app")
sleep(3)
lbry_name = self.parse_name(lbry_name)
self.open_address(lbry_name)
def handle_linux(self, lbry_name):
self.check_daemon()
if not self.started_daemon:
cmd = r'DIR = "$( cd "$(dirname "${BASH_SOURCE[0]}" )" && pwd )"' \
r'if [-z "$(pgrep lbrynet-daemon)"]; then' \
r'echo "running lbrynet-daemon"' \
r'$DIR / lbrynet - daemon &' \
r'sleep 3 # let the daemon load before connecting' \
r'fi'
subprocess.Popen(cmd, shell=True)
lbry_name = self.parse_name(lbry_name)
self.open_address(lbry_name)
def handle_win32(self, lbry_name):
# Opening LBRY.exe with lbry_name as arg prevents the need to
# make a separate call to open_address()
self.check_daemon()
lbry_name = self.parse_name(lbry_name)
if self.started_daemon:
self.open_address(lbry_name)
else:
lbry_path = os.path.join(os.environ["PROGRAMFILES"], "LBRY", "LBRY.exe ")
subprocess.call(lbry_path + lbry_name)
def check_daemon(self):
try:
status = self.daemon.call('status')
self.started_daemon = status['is_running']
except:
self.started_daemon = False
@staticmethod
def parse_name(lbry_name):
if lbry_name[:7].lower() == "lbry://":
if lbry_name[-1] == "/":
return lbry_name[7:-1]
else:
return lbry_name[7:]
else:
if lbry_name[-1] == "/":
return lbry_name[:-1]
else:
return lbry_name[:]
@staticmethod
def open_address(lbry_name):
if lbry_name == "lbry" or lbry_name == "" or lbry_name is None:
webbrowser.open(conf.settings.get_ui_address())
else:
webbrowser.open(conf.settings.get_ui_address() + "/?show=" + lbry_name)
def main(args):
if len(args) != 1:
args = ["lbry://lbry"]
name = args[0][7:]
if sys.platform == "darwin":
LBRYURIHandler().handle_osx(lbry_name=name)
elif os.name == "nt":
LBRYURIHandler().handle_win32(lbry_name=name)
else:
LBRYURIHandler().handle_linux(lbry_name=name)
if __name__ == "__main__":
main(sys.argv[1:])

View file

@ -1,54 +0,0 @@
import _winreg as winreg
import os
import sys
import win32con
import win32gui
def main():
try:
install = 'remove' not in sys.argv[1]
except:
install = True
lbry_path = os.path.join(os.environ["ProgramFiles"], "LBRY", "LBRY.exe")
key_url = 'lbry'
try:
key = winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, key_url, 0, winreg.KEY_ALL_ACCESS)
except:
key = winreg.CreateKey(winreg.HKEY_CLASSES_ROOT, key_url)
if install:
winreg.SetValueEx(key, None, 0, winreg.REG_SZ, "URL:LBRY Protocol")
winreg.SetValueEx(key, "URL Protocol", 0, winreg.REG_SZ, "")
else:
winreg.DeleteKey(winreg.HKEY_CLASSES_ROOT, key_url)
winreg.CloseKey(key)
key_icon = os.path.join('lbry', 'DefaultIcon')
try:
key = winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, key_icon, 0, winreg.KEY_ALL_ACCESS)
except:
key = winreg.CreateKey(winreg.HKEY_CLASSES_ROOT, key_icon)
if install:
winreg.SetValueEx(key, None, 0, winreg.REG_SZ, "\"LBRY.exe,1\"")
else:
winreg.DeleteKey(winreg.HKEY_CLASSES_ROOT, key_icon)
winreg.CloseKey(key)
key_command = os.path.join('lbry', 'shell', 'open', 'command')
try:
key = winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, key_command, 0, winreg.KEY_ALL_ACCESS)
except:
key = winreg.CreateKey(winreg.HKEY_CLASSES_ROOT, key_command)
if install:
winreg.SetValueEx(key, None, 0, winreg.REG_SZ, "\"{0}\" \"%1\"".format(lbry_path))
else:
winreg.DeleteKey(winreg.HKEY_CLASSES_ROOT, key_command)
winreg.CloseKey(key)
win32gui.SendMessage(win32con.HWND_BROADCAST, win32con.WM_SETTINGCHANGE, 0, 'Environment')
if __name__ == "__main__":
main()