Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 639 prints in cdxj #640

Merged
merged 26 commits into from
Jul 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
f478ece
Merge pull request #2 from oduwsdl/master
anatoly-scherbakov Apr 27, 2020
15abc94
Replace print() with a logging call
anatoly-scherbakov Apr 27, 2020
2f2be09
Little cleanup, closes #639
anatoly-scherbakov Apr 27, 2020
5f47023
check_for_update.py and better test coverage
anatoly-scherbakov Apr 27, 2020
9c39bf2
Removed the PyPI version check
anatoly-scherbakov Apr 27, 2020
501e381
Remove logError()
anatoly-scherbakov Apr 27, 2020
6ae17f2
A few reformatted imports
anatoly-scherbakov Apr 27, 2020
b38909b
Merge branch 'issue-639-prints-in-cdxj' into issue-639-rebase
machawk1 Jun 29, 2020
422ed3f
Merge pull request #1 from oduwsdl/issue-639-rebase
machawk1 Jun 29, 2020
b6a6ef4
Merge pull request #3 from oduwsdl/master
machawk1 Jul 1, 2020
abfff15
Add missing json dependency
machawk1 Jul 1, 2020
2088f74
Merge pull request #3 from machawk1/issue-639-prints-in-cdxj
anatoly-scherbakov Jul 2, 2020
1ca49d7
introduce error_handler() decorator
anatoly-scherbakov Jul 5, 2020
6184276
Merge pull request #4 from oduwsdl/master
anatoly-scherbakov Jul 5, 2020
9780d0c
Fixed conflicts
anatoly-scherbakov Jul 5, 2020
76d6063
Fixed issues after merging conflicts
anatoly-scherbakov Jul 5, 2020
9bfac3a
Linter error fixed, docstring improved
anatoly-scherbakov Jul 5, 2020
a544698
tests for check_daemon_is_alive()
anatoly-scherbakov Jul 5, 2020
436e257
ipfs_client() is now caching the instance of IPFS client
anatoly-scherbakov Jul 5, 2020
04aa90c
Fix tests
anatoly-scherbakov Jul 5, 2020
f460e8b
More tests to improve coverage
anatoly-scherbakov Jul 5, 2020
e71715a
try-except clauses
anatoly-scherbakov Jul 5, 2020
e5ad8ef
Tests for error_handler.exception_logger()
anatoly-scherbakov Jul 5, 2020
144d897
Make linter a bit happier
anatoly-scherbakov Jul 5, 2020
df09869
Update ipwb/util.py
anatoly-scherbakov Jul 6, 2020
16bbb8f
Update ipwb/__main__.py
anatoly-scherbakov Jul 6, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 12 additions & 15 deletions ipwb/__main__.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
import sys
import os
import argparse
import tempfile
import string # For generating a temp file for stdin
import random # For generating a temp file for stdin
from .__init__ import __version__ as ipwbVersion
import string # For generating a temp file for stdin
import sys
import tempfile

# ipwb modules
from . import replay
from . import indexer
from . import util as ipwbUtil

from .util import IPWBREPLAY_HOST, IPWBREPLAY_PORT
from ipwb import settings, replay, indexer, util
from ipwb.error_handler import exception_logger
from .__init__ import __version__ as ipwb_version


@exception_logger(catch=not settings.DEBUG)
def main():
checkArgs(sys.argv)


def checkArgs_index(args):
if not ipwbUtil.isDaemonAlive():
sys.exit()
util.check_daemon_is_alive()

encKey = None
compressionLevel = None
if args.e:
Expand Down Expand Up @@ -139,17 +136,17 @@ def checkArgs(argsIn):
'-d', '--daemon',
help=("Multi-address of IPFS daemon "
"(default /dns/localhost/tcp/5001/http)"),
default=ipwbUtil.IPFSAPI_MUTLIADDRESS,
default=util.IPFSAPI_MUTLIADDRESS,
dest='daemon_address')
parser.add_argument(
'-v', '--version', help='Report the version of ipwb', action='version',
version='InterPlanetary Wayback ' + ipwbVersion)
version=f'InterPlanetary Wayback {ipwb_version}')
parser.add_argument(
'-u', '--update-check',
action='store_true',
help='Check whether an updated version of ipwb is available'
)
parser.set_defaults(func=ipwbUtil.checkForUpdate)
parser.set_defaults(func=util.checkForUpdate)

argCount = len(argsIn)
cmdList = ['index', 'replay']
Expand Down
42 changes: 42 additions & 0 deletions ipwb/error_handler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import functools
import logging
from typing import Callable

logger = logging.getLogger('ipwb')


def exception_logger(catch=True, exception_class=Exception):
"""
Decorator which catches exceptions in the function and logs them.

Usage:

```python
@exception_logger()
def decorated_function(foo, bar):
do_something
```

`exception_logger()` will catch any exception which happens in
`decorated_function()` while it is being executed, and log an error using
Python built in `logging` library.

Unless `catch` argument is `False` - in which case the exception will be
reraised.
"""
def decorator(f: Callable):
@functools.wraps(f)
def wrapper(*args, **kwargs):
try:
return f(*args, **kwargs)

except exception_class as err:
if catch:
logger.critical(str(err))

else:
raise

return wrapper

return decorator
2 changes: 2 additions & 0 deletions ipwb/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class IPFSDaemonNotAvailable(Exception):
"""IPFS Daemon is for some reason not available."""
19 changes: 3 additions & 16 deletions ipwb/indexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import os
import json
import ipfshttpclient as ipfsapi
import argparse
import zlib
import surt
import ntpath
Expand All @@ -33,14 +32,10 @@
from six import PY2
from six import PY3

from .util import iso8601ToDigits14
from . import util as ipwbUtils

# from warcio.archiveiterator import ArchiveIterator
from ipwb.util import iso8601ToDigits14, ipfs_client

import requests
import datetime
import shutil

from bs4 import BeautifulSoup

Expand All @@ -52,11 +47,6 @@

DEBUG = False

IPFS_API = ipwbUtils.createIPFSClient()
if IPFS_API is None:
print("Error initializing IPFS API client")
sys.exit()


def s2b(s): # Convert str to bytes, cross-py
return bytes(s) if PY2 else bytes(s, 'utf-8')
Expand Down Expand Up @@ -367,20 +357,17 @@ def logError(errIn, end='\n'):


def pullFromIPFS(hash):
global IPFS_API
return IPFS_API.cat(hash)
return ipfs_client().cat(hash)


def pushBytesToIPFS(bytes):
"""
Call the IPFS API to add the byte string to IPFS.
When IPFS returns a hash, return this to the caller
"""
global IPFS_API

# Returns unicode in py2.7, str in py3.7
try:
res = IPFS_API.add_bytes(bytes) # bytes)
res = ipfs_client().add_bytes(bytes) # bytes)
except TypeError as err:
print('fail')
logError('IPFS_API had an issue pushing the item to IPFS')
Expand Down
48 changes: 27 additions & 21 deletions ipwb/replay.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@

from . import util as ipwbUtils
from .backends import get_web_archive_index
from .util import unsurt
from .exceptions import IPFSDaemonNotAvailable
from .util import unsurt, ipfs_client
from .util import IPWBREPLAY_HOST, IPWBREPLAY_PORT
from .util import INDEX_FILE

Expand All @@ -56,6 +57,10 @@
from flask import send_from_directory
from flask import make_response

import logging

logger = logging.getLogger(__name__)

UPLOAD_FOLDER = tempfile.gettempdir()
ALLOWED_EXTENSIONS = ('.warc', '.warc.gz')

Expand All @@ -64,12 +69,6 @@
app.debug = False


IPFS_API = ipwbUtils.createIPFSClient()
if IPFS_API is None:
print("Error initializing IPFS API client")
sys.exit()


@app.context_processor
def formatters():
return {'pluralize': lambda x, s, p: "{} {}".format(x, s if x == 1 else p)}
Expand Down Expand Up @@ -134,7 +133,6 @@ class UnsupportedIPFSVersions(Exception):

@app.route('/ipfsdaemon/<cmd>')
def commandDaemon(cmd):
global IPFS_API
if cmd == 'status':
return generateDaemonStatusButton()
elif cmd == 'start':
Expand All @@ -143,10 +141,10 @@ def commandDaemon(cmd):

elif cmd == 'stop':
try:
installedIPFSVersion = IPFS_API.version()['Version']
installedIPFSVersion = ipfs_client().version()['Version']
if ipwbUtils.compareVersions(installedIPFSVersion, '0.4.10') < 0:
raise UnsupportedIPFSVersions()
IPFS_API.shutdown()
ipfs_client().shutdown()
except (subprocess.CalledProcessError, UnsupportedIPFSVersions) as e:
if os.name != 'nt': # Big hammer
subprocess.call(['killall', 'ipfs'])
Expand Down Expand Up @@ -593,13 +591,15 @@ def showLandingPage():


def show_uri(path, datetime=None):
global IPFS_API
try:
ipwbUtils.check_daemon_is_alive(ipwbUtils.IPFSAPI_MUTLIADDRESS)

if not ipwbUtils.isDaemonAlive(ipwbUtils.IPFSAPI_MUTLIADDRESS):
except IPFSDaemonNotAvailable:
errStr = ('IPFS daemon not running. '
'Start it using $ ipfs daemon on the command-line '
' or from the <a href="/">'
'IPWB replay homepage</a>.')

return Response(errStr, status=503)

cdxjLine = ''
Expand Down Expand Up @@ -642,8 +642,8 @@ def handler(signum, frame):
# signal.signal(signal.SIGALRM, handler)
# signal.alarm(10)

payload = IPFS_API.cat(digests[-1])
header = IPFS_API.cat(digests[-2])
payload = ipfs_client().cat(digests[-1])
header = ipfs_client().cat(digests[-2])

# if os.name != 'nt': # Bug #310
# signal.alarm(0)
Expand Down Expand Up @@ -846,7 +846,14 @@ def extractResponseFromChunkedData(data):
def generateDaemonStatusButton():
text = 'Not Running'
buttonText = 'Start'
if ipwbUtils.isDaemonAlive():

try:
ipwbUtils.check_daemon_is_alive()

except IPFSDaemonNotAvailable:
pass

else:
text = 'Running'
buttonText = 'Stop'

Expand Down Expand Up @@ -1034,12 +1041,11 @@ def start(cdxjFilePath, proxy=None):
if not hostPort:
ipwbUtils.setIPWBReplayConfig(IPWBREPLAY_HOST, IPWBREPLAY_PORT)

if ipwbUtils.isDaemonAlive():
ipwbUtils.setIPWBReplayIndexPath(cdxjFilePath)
app.cdxjFilePath = cdxjFilePath
else:
print('Sample data not pulled from IPFS.')
print('Check that the IPFS daemon is running.')
# This will throw an exception if daemon is not available.
ipwbUtils.check_daemon_is_alive()

ipwbUtils.setIPWBReplayIndexPath(cdxjFilePath)
app.cdxjFilePath = cdxjFilePath

try:
print((f'IPWB replay started on '
Expand Down
35 changes: 35 additions & 0 deletions ipwb/settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"""Settings and configuration parameters of ipwb."""

import os
from logging import config as logging_config

# Running in debug mode or not?
DEBUG = os.environ.get('DEBUG', False)


LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'standard': {
'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
}
},
'handlers': {
'console': {
'level': 'DEBUG' if DEBUG else 'INFO',
'formatter': 'standard',
'class': 'logging.StreamHandler',
},
},
'loggers': {
'': {
'handlers': ['console'],
'level': 'INFO',
'propagate': False
},
}
}


logging_config.dictConfig(LOGGING)
Loading