Skip to content
This repository has been archived by the owner on Sep 1, 2021. It is now read-only.

Commit

Permalink
Notifies user when roll processed, fixes #57
Browse files Browse the repository at this point in the history
Adds a background service for pulling rolls and notify user when roll
was processed.
There's currently a bug where the service may die for a unknown reason.
Also the notification is not clickable and doesn't bring back to the
app.
This commit also brings a bunch of other things such as:

  - fixes missing `libffi-dev`
  - adds missing `libgmp3-dev` required by coincurve
  - upgrades Docker base image to latest Ubuntu Bionic LTS
  - refactors some file locations (shared with service/)
  • Loading branch information
AndreMiras committed Sep 6, 2018
1 parent 8b8d9ab commit 21130ce
Show file tree
Hide file tree
Showing 13 changed files with 283 additions and 85 deletions.
4 changes: 3 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
venv/
.git/
.buildozer/
.pytest_cache/
**/.pytest_cache/
.tox/
bin/
*.pyc
**/__pycache__
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ GARDEN=`. $(ACTIVATE_PATH); which garden`
PYTHON="$(VENV_NAME)/bin/python"
SYSTEM_DEPENDENCIES=python3-dev virtualenv build-essential libssl-dev \
libsdl2-dev libsdl2-image-dev libsdl2-mixer-dev libsdl2-ttf-dev \
xclip xsel
libffi-dev libgmp3-dev xclip xsel
OS=$(shell lsb_release -si)


Expand Down
6 changes: 4 additions & 2 deletions buildozer.spec
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ package.name = etheroll
package.domain = com.github.andremiras

# (str) Source code where the main.py live
source.dir = src/
source.dir = src

# (list) Source files to include (let empty to include all the files)
source.include_exts = py,png,jpg,kv,atlas,md,json
Expand Down Expand Up @@ -41,7 +41,8 @@ requirements =
hostpython3crystax==3.6,
python3crystax==3.6,
setuptools,
kivy,
kivy==d8ef8c2,
plyer==1.3.0,
android,
gevent,
cffi,
Expand Down Expand Up @@ -121,6 +122,7 @@ orientation = portrait
# (list) List of service to declare
#services = NAME:ENTRYPOINT_TO_PY,NAME2:ENTRYPOINT2_TO_PY
services = service:service/main.py
#
# OSX Specific
Expand Down
5 changes: 3 additions & 2 deletions dockerfiles/Dockerfile-linux
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
# TODO:
# - delete archives to keep small the container small
# - setup caching (for apt, and pip)
FROM ubuntu:16.04
FROM ubuntu:18.04

# configure locale
RUN apt update -qq > /dev/null && apt install --yes --no-install-recommends \
Expand All @@ -23,7 +23,7 @@ ENV LANG="en_US.UTF-8" \
# install system dependencies
RUN apt update -qq > /dev/null && apt install --yes --no-install-recommends \
python3 python3-dev virtualenv make lsb-release pkg-config git build-essential \
libssl-dev tox
sudo libssl-dev tox

# install kivy system dependencies
# https://kivy.org/docs/installation/installation-linux.html#dependencies-with-sdl2
Expand All @@ -32,4 +32,5 @@ RUN apt install --yes --no-install-recommends \

WORKDIR /app
COPY . /app
RUN make system_dependencies
ENTRYPOINT ["./dockerfiles/start.sh"]
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ isort
# is fixed by installing kivy master
# https://github.com/kivy/kivy/archive/27e3b90eae2a0155b22a435f1b6f65c913519db6.zip#egg=kivy
# on Ubuntu 18.04 Bionic, the compile error related to `MIX_INIT_MOD` is fixed by installing:
https://github.com/kivy/kivy/archive/d8ef8c2834293098bc404c0432049b2761f9b721.zip#egg=kivy
https://github.com/kivy/kivy/archive/d8ef8c2.zip#egg=kivy
# Kivy==1.10.0
https://gitlab.com/kivymd/KivyMD/repository/archive.zip?ref=19e587e6#egg=kivymd
ethereum==2.1.1
Expand All @@ -24,3 +24,4 @@ rlp==0.6.0
# https://github.com/golemfactory/golem-messages/pull/112/files
https://github.com/mfranciszkiewicz/pyelliptic/archive/1.5.10.tar.gz#egg=pyelliptic
https://github.com/AndreMiras/garden.layoutmargin/archive/20180517.zip#egg=layoutmargin
plyer==1.3.0
26 changes: 21 additions & 5 deletions src/etheroll/controller.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#!/usr/bin/env python
import os
from os.path import expanduser

from kivy.app import App
from kivy.clock import Clock, mainthread
Expand All @@ -15,11 +14,10 @@
from raven.handlers.logging import SentryHandler

from etheroll.constants import KEYSTORE_DIR_SUFFIX
from etheroll.patches import patch_find_library_android, patch_typing_python351
from etheroll.settings import SettingsScreen
from etheroll.switchaccount import SwitchAccountScreen
from etheroll.utils import (Dialog, load_kv_from_py,
patch_find_library_android, patch_typing_python351,
run_in_thread)
from etheroll.utils import Dialog, load_kv_from_py, run_in_thread
from version import __version__

patch_find_library_android()
Expand Down Expand Up @@ -121,7 +119,7 @@ def get_default_keystore_path():
Returns the keystore path, which is the same as the default pyethapp
one.
"""
KEYSTORE_DIR_PREFIX = expanduser("~")
KEYSTORE_DIR_PREFIX = os.path.expanduser("~")
# uses kivy user_data_dir (/sdcard/<app_name>)
if platform == "android":
KEYSTORE_DIR_PREFIX = App.get_running_app().user_data_dir
Expand Down Expand Up @@ -478,12 +476,30 @@ def build(self):
self.icon = "docs/images/icon.png"
self.theme_cls.theme_style = 'Dark'
self.theme_cls.primary_palette = 'Indigo'
self.start_service()
return Controller()

def start_service(self):
"""
Starts the roll pulling service.
"""
if platform == 'android':
from jnius import autoclass
package_name = 'etheroll'
package_domain = 'com.github.andremiras'
service_name = 'service'
service_class = '{}.{}.Service{}'.format(
package_domain, package_name, service_name.title())
service = autoclass(service_class)
mActivity = autoclass('org.kivy.android.PythonActivity').mActivity
argument = ''
service.start(mActivity, argument)


def main():
# only send Android errors to Sentry
in_debug = platform != "android"
in_debug = True
client = configure_sentry(in_debug)
try:
EtherollApp().run()
Expand Down
52 changes: 52 additions & 0 deletions src/etheroll/patches.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import ctypes.util
import os
import typing
from ctypes.util import find_library as original_find_library

from kivy.utils import platform


def find_library(name):
"""
Looks in the right places on Android, see:
https://github.com/kivy/python-for-android/blob/0.6.0/
pythonforandroid/recipes/python2/patches/ctypes-find-library-updated.patch
"""
# Check the user app lib dir
app_root = os.path.abspath('../../').split(os.path.sep)
lib_search = os.path.sep.join(app_root) + os.path.sep + 'lib'
for filename in os.listdir(lib_search):
if filename.endswith('.so') and name in filename:
return lib_search + os.path.sep + filename
# Check the normal Android system libraries
for filename in os.listdir('/system/lib'):
if filename.endswith('.so') and name in filename:
return lib_search + os.path.sep + filename
# fallback on the original find_library()
return original_find_library(name)


def patch_find_library_android():
"""
Monkey patches find_library() to first try to find libraries on Android.
https://github.com/AndreMiras/EtherollApp/issues/30
"""
if platform == 'android':
ctypes.util.find_library = find_library


CT_co = typing.TypeVar('CT_co', covariant=True, bound=type)


class Type(typing.Generic[CT_co], extra=type):
__slots__ = ()


def patch_typing_python351():
"""
Python 3.5.1 doesn't have typing.Type, refs:
https://github.com/crystax/android-vendor-python-3-5/issues/1
"""
# TODO: check Python version and only patch if == 3.5.1
if not hasattr(typing, 'Type'):
typing.Type = Type
3 changes: 2 additions & 1 deletion src/etheroll/settings.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from etheroll.utils import Store, SubScreen, load_kv_from_py
from etheroll.store import Store
from etheroll.utils import SubScreen, load_kv_from_py
from pyetheroll.constants import DEFAULT_GAS_PRICE_GWEI, ChainID

load_kv_from_py(__file__)
Expand Down
25 changes: 25 additions & 0 deletions src/etheroll/store.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import os

from kivy.app import App
from kivy.storage.jsonstore import JsonStore


class Store:

@staticmethod
def get_store_path():
"""
Returns the full user store path.
"""
user_data_dir = App.get_running_app().user_data_dir
store_path = os.path.join(user_data_dir, 'store.json')
return store_path

@classmethod
def get_store(cls):
"""
Returns user Store object.
"""
store_path = cls.get_store_path()
store = JsonStore(store_path)
return store
72 changes: 0 additions & 72 deletions src/etheroll/utils.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
import ctypes.util
import os
import threading
import typing
from ctypes.util import find_library as original_find_library
from io import StringIO

from kivy.app import App
from kivy.clock import mainthread
from kivy.lang import Builder
from kivy.metrics import dp
from kivy.storage.jsonstore import JsonStore
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import Screen
from kivy.utils import platform
from kivymd.dialog import MDDialog
from kivymd.label import MDLabel
from kivymd.snackbar import Snackbar
Expand Down Expand Up @@ -169,52 +164,6 @@ def create_dialog(cls, title, body):
return dialog


def find_library(name):
"""
Looks in the right places on Android, see:
https://github.com/kivy/python-for-android/blob/0.6.0/
pythonforandroid/recipes/python2/patches/ctypes-find-library-updated.patch
"""
# Check the user app lib dir
app_root = os.path.abspath('../../').split(os.path.sep)
lib_search = os.path.sep.join(app_root) + os.path.sep + 'lib'
for filename in os.listdir(lib_search):
if filename.endswith('.so') and name in filename:
return lib_search + os.path.sep + filename
# Check the normal Android system libraries
for filename in os.listdir('/system/lib'):
if filename.endswith('.so') and name in filename:
return lib_search + os.path.sep + filename
# fallback on the original find_library()
return original_find_library(name)


def patch_find_library_android():
"""
Monkey patches find_library() to first try to find libraries on Android.
https://github.com/AndreMiras/EtherollApp/issues/30
"""
if platform == 'android':
ctypes.util.find_library = find_library


CT_co = typing.TypeVar('CT_co', covariant=True, bound=type)


class Type(typing.Generic[CT_co], extra=type):
__slots__ = ()


def patch_typing_python351():
"""
Python 3.5.1 doesn't have typing.Type, refs:
https://github.com/crystax/android-vendor-python-3-5/issues/1
"""
# TODO: check Python version and only patch if == 3.5.1
if not hasattr(typing, 'Type'):
typing.Type = Type


class SubScreen(Screen):
"""
Helper parent class for updating toolbar on enter/leave.
Expand All @@ -239,27 +188,6 @@ def on_leave(self):
app.root.ids.toolbar_id.load_default_buttons()


class Store:

@staticmethod
def get_store_path():
"""
Returns the full user store path.
"""
user_data_dir = App.get_running_app().user_data_dir
store_path = os.path.join(user_data_dir, 'store.json')
return store_path

@classmethod
def get_store(cls):
"""
Returns the full user Store object instance.
"""
store_path = cls.get_store_path()
store = JsonStore(store_path)
return store


class BoxLayoutMarginLayout(MarginLayout, BoxLayout):
pass

Expand Down
5 changes: 5 additions & 0 deletions src/pyetheroll/etheroll.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ def get_bets_logs(self, address, from_block, to_block='latest'):
"""
Retrieves `address` last bets from event logs and returns the list
of bets with decoded info. Does not return the actual roll result.
Least recent first (index 0), most recent last (index -1).
"""
bets = []
bet_events = self.get_log_bet_events(address, from_block, to_block)
Expand Down Expand Up @@ -371,6 +372,10 @@ def merge_logs(bet_logs, bet_results_logs):
return merged_logs

def get_merged_logs(self, address):
"""
Returns the merged logs.
Least recent first (index 0), most recent last (index -1).
"""
last_bets_blocks = self.get_last_bets_blocks(address)
if last_bets_blocks is None:
return []
Expand Down
Loading

0 comments on commit 21130ce

Please sign in to comment.