Skip to content

Commit

Permalink
Removed the selective import in common for one that might work better
Browse files Browse the repository at this point in the history
Included error checking when trying to connect online to
    prevent crashes when unable to connect.
  • Loading branch information
MosesofEgypt committed Jun 20, 2017
1 parent e8da1d7 commit a0798c9
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 26 deletions.
15 changes: 9 additions & 6 deletions src/common.py
Expand Up @@ -7,6 +7,15 @@
from PyQt5.QtWidgets import QApplication
from util import get_platform

try:
# common needs to import config, and config needs to import common.
# whichever one successfully imports the other will give the other
# a reference to itself.
import config
config.common = sys.modules[__name__]
except ImportError:
config = None

ICON_SIZES = (16, 32, 48, 64, 256)

GLOBAL_CONTEXT = {
Expand Down Expand Up @@ -38,12 +47,6 @@ def get_loop():


def set_app_icon():
# config relies on common, and this function in common relies on config.
# gotta break the import loop somewhere, so this seems like a good place.
# might be more preferrable to make a dummy config attribute and have the
# launcher's __init__.py set up a circular link between both modules.
# that might not work well when running tests though...
import config
g = globals()

if g.get('app') is None:
Expand Down
31 changes: 23 additions & 8 deletions src/config.py
Expand Up @@ -6,15 +6,23 @@
import requests
import logging
from logging.handlers import RotatingFileHandler
from requests.exceptions import HTTPError, Timeout
from common import inject_variables, GLOBAL_CONTEXT, sanitize_url
from requests.exceptions import HTTPError, Timeout, ConnectionError
from util import namedtuple_from_mapping, get_platform
from collections import OrderedDict

try:
# common needs to import config, and config needs to import common.
# whichever one successfully imports the other will give the other
# a reference to itself.
import common
common.config = sys.modules[__name__]
except ImportError:
common = None

__all__ = (
"TRANSLATION_DIR", "TRANSLATION_DIRNAME", "TRANSLATIONS",
"CONFIG_DIR", "CONFIG_DIRNAME", "CONFIG_NAME", "CONFIG",
"BASE_DIR", "RESOURCE_DIR", "GLOBAL_CONTEXT", "ROOT_LOGGER"
"BASE_DIR", "RESOURCE_DIR", "ROOT_LOGGER"
)


Expand Down Expand Up @@ -76,9 +84,10 @@ def reload_config():
config_json = json.load(config_file, object_pairs_hook=OrderedDict)

old_url = None
GLOBAL_CONTEXT['project'] = sanitize_url(config_json['project'])
common.GLOBAL_CONTEXT['project'] = common.sanitize_url(
config_json['project'])
if 'config_endpoint' in config_json:
url = inject_variables(config_json['config_endpoint'])
url = common.inject_variables(config_json['config_endpoint'])
while old_url != url:
if _LOGGER_SETUP:
logging.info('Loading remote config from %s' % url)
Expand All @@ -102,13 +111,19 @@ def reload_config():
if _LOGGER_SETUP:
logging.error(timeout)
break
except ConnectionError as connection_error:
if _LOGGER_SETUP:
logging.error(connection_error)
break
old_url = url
GLOBAL_CONTEXT['project'] = sanitize_url(
common.GLOBAL_CONTEXT['project'] = common.sanitize_url(
config_json['project'])
if 'config_endpoint' in config_json:
url = inject_variables(config_json['config_endpoint'])
url = common.inject_variables(
config_json['config_endpoint'])
g['CONFIG'] = namedtuple_from_mapping(config_json)
GLOBAL_CONTEXT['project'] = sanitize_url(config_json['project'])
common.GLOBAL_CONTEXT['project'] = common.sanitize_url(
config_json['project'])

return g['CONFIG']

Expand Down
83 changes: 72 additions & 11 deletions src/ui.py
Expand Up @@ -17,6 +17,7 @@
from util import get_platform, sha256_hash, list_files
from download import DownloadTracker
from quamash import QThreadExecutor
from requests.exceptions import HTTPError, Timeout, ConnectionError
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QPixmap
from PyQt5.QtCore import *
Expand Down Expand Up @@ -103,6 +104,7 @@ def fetch_remote_index(self, context, download_tracker):
url = inject_variables(self.config.index_endpoint, branch_context)
logging.info('Fetching remote index from %s...' % url)
response = requests.get(url)

# TODO(james7132): Do proper error checking
remote_index = response.json()
logging.info('Fetched remote index from %s...' % url)
Expand Down Expand Up @@ -141,6 +143,7 @@ class ClientState(Enum):


class MainWindow(QWidget):
news_row_count = 0

def __init__(self, cfg):
super().__init__()
Expand Down Expand Up @@ -173,6 +176,7 @@ async def main_loop(self):
asyncio.ensure_future(self.fetch_news())
while True:
if self.client_state in state_mapping:
state = self.client_state
await state_mapping[self.client_state]()
else:
await asyncio.sleep(0.1)
Expand All @@ -184,12 +188,30 @@ async def fetch_news(self):
return
feed_url = self.build_path(self.config.news_rss_feed)
# TODO(james7132): Do proper error checking
rss_response = requests.get(feed_url,
headers={
'User-Agent': 'HouraiLauncher 0.1.0'
})
try:
rss_response = requests.get(
feed_url, headers={
'User-Agent': 'HouraiLauncher 0.1.0'
})
error_occurred = False
except HTTPError as http_error:
logging.error(http_error)
error_occurred = True
except Timeout as timeout:
logging.error(timeout)
error_occurred = True
except ConnectionError as connection_error:
logging.error(connection_error)
error_occurred = True

if error_occurred:
if self.news_row_count < 10:
self.news_row_count += 1
self.news_view.addRow(QLabel(
"Could not fetch news. Check the log for details."))
return

rss_data = feedparser.parse(rss_response.text)
count = 0
for entry in rss_data.entries:
entry_time = datetime.fromtimestamp(mktime(entry.updated_parsed))
entry_date = entry_time.date()
Expand All @@ -199,8 +221,8 @@ async def fetch_news(self):
self.news_view.addRow(QLabel(format_date(entry_date)), label)
logging.info('News Item: %s (%s)' %
(format_date(entry_date), entry.title))
count += 1
if count >= 10:
self.news_row_count += 1
if self.news_row_count >= 10:
break
logging.info('News fetched!')

Expand Down Expand Up @@ -230,9 +252,29 @@ async def launcher_update_check(self):
hash_url = url + '.hash'
logging.info('Fetching remote hash from: %s' % hash_url)
# TODO(james7132): Do proper error checking
response = await get_loop().run_in_executor(self.executor,
requests.get,
hash_url)
try:
response = await get_loop().run_in_executor(self.executor,
requests.get,
hash_url)
error_occurred = False
except HTTPError as http_error:
logging.error(http_error)
error_occurred = True
except Timeout as timeout:
logging.error(timeout)
error_occurred = True
except ConnectionError as connection_error:
logging.error(connection_error)
error_occurred = True

if error_occurred:
if self.news_row_count < 10:
self.news_row_count += 1
self.news_view.addRow(QLabel(
"Could not check for launcher updates. "
"Check the log for details."))
return

remote_launcher_hash = response.text
logging.info('Remote launcher hash: %s' % remote_launcher_hash)
if remote_launcher_hash == launcher_hash:
Expand Down Expand Up @@ -283,7 +325,26 @@ async def game_update_check(self):
self.executor, branch.fetch_remote_index,
self.context, self.download_tracker)
for branch in self.branches.values()]
await asyncio.gather(*downloads)
try:
await asyncio.gather(*downloads)
error_occurred = False
except HTTPError as http_error:
logging.error(http_error)
error_occurred = True
except Timeout as timeout:
logging.error(timeout)
error_occurred = True
except ConnectionError as connection_error:
logging.error(connection_error)
error_occurred = True

if error_occurred:
if self.news_row_count < 10:
self.news_row_count += 1
self.news_view.addRow(QLabel(
"Could not check for game updates. "
"Check the log for details."))

logging.info('Remote game update check completed.')
self.client_state = ClientState.READY

Expand Down
1 change: 0 additions & 1 deletion test/test_config.py
Expand Up @@ -164,7 +164,6 @@ def test_config_contains_proper_attributes(self):
assert hasattr(config, "CONFIG")
assert hasattr(config, "BASE_DIR")
assert hasattr(config, "RESOURCE_DIR")
assert hasattr(config, "GLOBAL_CONTEXT")

assert hasattr(cfg, "branches")
assert hasattr(cfg, "config_endpoint")
Expand Down

0 comments on commit a0798c9

Please sign in to comment.