Skip to content

Commit

Permalink
Next Minor (Release 10/21) (#449)
Browse files Browse the repository at this point in the history
* Added Redis Cache Driver

* Finalized Redis Cache Driver

* Merge 2.0 into master (#443)

* bumped version

* fixed connection credentials

* bumped version

* fixed amqp driver to pickup connection when lost (#442)

* bumped version

* updated test

* Added ability to add jinja extensions (#458)

* started to add ability to use other file extensions

* fixed search path and pugjs

* fixed pypug dependency

* Add custom exception handlers (#459)

* added ability to add custom exception handlers

* added more

* added debug exception

* added debug exception to tests

* added dd and templates

* fixed manifest file

* removed print statement
  • Loading branch information
josephmancuso committed Nov 1, 2018
1 parent e2e22ce commit ae29340
Show file tree
Hide file tree
Showing 23 changed files with 530 additions and 132 deletions.
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
include masonite/snippets/exceptions/css/*
include masonite/snippets/exceptions/*
include masonite/snippets/*
include masonite/snippets/auth/controllers/*
include masonite/snippets/auth/templates/auth/*
1 change: 1 addition & 0 deletions app/http/controllers/TestController.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from cleo import Command
from masonite.exceptions import DebugException

class TestController:

Expand Down
7 changes: 7 additions & 0 deletions config/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,17 @@
Cache configuration
"""

import os

DRIVER = 'disk'

DRIVERS = {
'disk': {
'location': 'bootstrap/cache'
},
'redis': {
'host': os.getenv('REDIS_HOST', 'localhost'),
'port': os.getenv('REDIS_PORT', '6379'),
'password': os.getenv('REDIS_PASSWORD', '')
}
}
27 changes: 14 additions & 13 deletions masonite/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,19 +144,20 @@ def collect(self, search):
# 'Sentry*'
# 'Sentry*Hook'
for key, value in self.providers.items():
if search.startswith('*'):
if key.endswith(search.split('*')[1]):
provider_list.update({key: value})
elif search.endswith('*'):
if key.startswith(search.split('*')[0]):
provider_list.update({key: value})
elif '*' in search:
split_search = search.split('*')
if key.startswith(split_search[0]) and key.endswith(split_search[1]):
provider_list.update({key: value})
else:
raise AttributeError(
"There is no '*' in your collection search")
if isinstance(key, str):
if search.startswith('*'):
if key.endswith(search.split('*')[1]):
provider_list.update({key: value})
elif search.endswith('*'):
if key.startswith(search.split('*')[0]):
provider_list.update({key: value})
elif '*' in search:
split_search = search.split('*')
if key.startswith(split_search[0]) and key.endswith(split_search[1]):
provider_list.update({key: value})
else:
raise AttributeError(
"There is no '*' in your collection search")
else:
for provider_key, provider_class in self.providers.items():
if inspect.isclass(provider_class) and issubclass(provider_class, search):
Expand Down
37 changes: 37 additions & 0 deletions masonite/drivers/BaseCacheDriver.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
"""Base cache driver module.
"""

from masonite.drivers.BaseDriver import BaseDriver


class BaseCacheDriver(BaseDriver):
"""Base class that all cache drivers inherit from.
"""

def calculate_time(self, cache_type, cache_time):
"""Convert time to required unit
Returns:
self
"""

cache_type = cache_type.lower()
calc = 0

if cache_type in ("second", "seconds"):
# Set time now for
calc = 1
elif cache_type in ("minute", "minutes"):
calc = 60
elif cache_type in ("hour", "hours"):
calc = 60 * 60
elif cache_type in ("day", "days"):
calc = 60 * 60 * 60
elif cache_type in ("month", "months"):
calc = 60 * 60 * 60 * 60
elif cache_type in ("year", "years"):
calc = 60 * 60 * 60 * 60 * 60
else:
raise ValueError(
'{0} is not a valid caching type.'.format(cache_type))

return cache_time * calc
25 changes: 3 additions & 22 deletions masonite/drivers/CacheDiskDriver.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
import time

from masonite.contracts.CacheContract import CacheContract
from masonite.drivers.BaseDriver import BaseDriver
from masonite.drivers.BaseCacheDriver import BaseCacheDriver


class CacheDiskDriver(CacheContract, BaseDriver):
class CacheDiskDriver(CacheContract, BaseCacheDriver):
"""Class for the cache disk driver.
"""

Expand Down Expand Up @@ -74,27 +74,8 @@ def store_for(self, key, value, cache_time, cache_type, extension=".txt", locati
"""

self.cache_forever = False
cache_type = cache_type.lower()
calc = 0

if cache_type in ("second", "seconds"):
# Set time now for
calc = 1
elif cache_type in ("minute", "minutes"):
calc = 60
elif cache_type in ("hour", "hours"):
calc = 60 * 60
elif cache_type in ("day", "days"):
calc = 60 * 60 * 60
elif cache_type in ("month", "months"):
calc = 60 * 60 * 60 * 60
elif cache_type in ("year", "years"):
calc = 60 * 60 * 60 * 60 * 60
else:
raise ValueError(
'{0} is not a valid caching type.'.format(cache_type))

cache_for_time = cache_time * calc
cache_for_time = self.calculate_time(cache_type, cache_time)

cache_for_time = cache_for_time + time.time()

Expand Down
131 changes: 131 additions & 0 deletions masonite/drivers/CacheRedisDriver.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
"""Module for the ache disk driver.
"""

import os

from masonite.contracts.CacheContract import CacheContract
from masonite.drivers.BaseCacheDriver import BaseCacheDriver

from masonite.exceptions import DriverLibraryNotFound


class CacheRedisDriver(CacheContract, BaseCacheDriver):
"""Class for the cache redis driver.
"""

def __init__(self, CacheConfig, Application):
"""Cache redis driver constructor
Arguments:
CacheConfig {config.cache} -- Cache configuration module.
Application {config.application} -- Application configuration module.
"""

self.appconfig = Application
self.cache_forever = None
self.app_name = os.getenv('APP_NAME', 'masonite')

config = CacheConfig.DRIVERS['redis']

try:
import redis
self.redis = redis
except ImportError:
raise DriverLibraryNotFound(
"Could not find the 'redis' library. Run pip install redis to fix this.")

self.connection = redis.StrictRedis(
host=config['host'],
port=config['port'],
password=config['password'],
decode_responses=True)

def store(self, key, value):
"""Stores content in cache file.
Arguments:
key {string} -- The key to store the cache file into
value {string} -- The value you want to store in the cache
Keyword Arguments:
extension {string} -- the extension you want to append to the file (default: {".txt"})
location {string} -- The path you want to store the cache into. (default: {None})
Returns:
string -- Returns the key
"""

self.cache_forever = True

self.connection.set('{0}_cache_{1}'.format(self.app_name, key), value)

return key

def store_for(self, key, value, cache_time, cache_type):
"""Store the cache for a specific amount of time.
Arguments:
key {string} -- The key to store the cache file into
value {string} -- The value you want to store in the cache
cache_time {int|string} -- The time as a string or an integer (1, 2, 5, 100, etc)
cache_type {string} -- The type of time to store for (minute, minutes, hours, seconds, etc)
Keyword Arguments:
extension {string} -- the extension you want to append to the file (default: {".txt"})
location {string} -- The path you want to store the cache into. (default: {None})
Raises:
ValueError -- Thrown if an invalid cache type was caught (like houes instead of hours).
Returns:
string -- Returns the key
"""

self.cache_forever = False
cache_for_time = self.calculate_time(cache_type, cache_time)

self.connection.set('{0}_cache_{1}'.format(self.app_name, key), value, ex=cache_for_time)

return key

def get(self, key):
"""
Get the data from a key in the cache
"""

return self.connection.get('{0}_cache_{1}'.format(self.app_name, key))

def delete(self, key):
"""
Delete file cache
"""

self.connection.delete('{0}_cache_{1}'.format(self.app_name, key))

def update(self, key, value):
"""
Updates a specific cache by key
"""

time_to_expire = self.connection.ttl('{0}_cache_{1}'.format(self.app_name, key))

if time_to_expire > 0:
self.connection.set('{0}_cache_{1}'.format(self.app_name, key), value, ex=time_to_expire)
else:
self.connection.set('{0}_cache_{1}'.format(self.app_name, key), value)

return key

def cache_exists(self, key):
"""
Check if the cache exists
"""

return self.connection.exists('{0}_cache_{1}'.format(self.app_name, key))

def is_valid(self, key):
"""
Check if a valid cache
"""

return self.cache_exists(key)
2 changes: 2 additions & 0 deletions masonite/drivers/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from .BaseDriver import BaseDriver
from .BaseMailDriver import BaseMailDriver
from .BaseUploadDriver import BaseUploadDriver
from .BaseCacheDriver import BaseCacheDriver
from .BroadcastAblyDriver import BroadcastAblyDriver
from .BroadcastPusherDriver import BroadcastPusherDriver
from .CacheDiskDriver import CacheDiskDriver
from .CacheRedisDriver import CacheRedisDriver
from .MailMailgunDriver import MailMailgunDriver
from .MailSmtpDriver import MailSmtpDriver
from .MailLogDriver import MailLogDriver
Expand Down
53 changes: 51 additions & 2 deletions masonite/exception_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,17 @@
code in a Masonite application. These errors could are thrown during runtime.
"""

import inspect
import os
import platform
import sys
import traceback

from masonite.app import App
from masonite.exceptions import DumpException
from masonite.request import Request
from masonite.view import View

package_directory = os.path.dirname(os.path.realpath(__file__))


Expand Down Expand Up @@ -45,9 +51,13 @@ def load_exception(self, exception):

self._exception = exception

self._render()
if self._app.has('Exception{}Handler'.format(exception.__class__.__name__)):

return self._app.resolve(self._app.make('Exception{}Handler'.format(exception.__class__.__name__))).handle(exception)

self.handle(exception)

def _render(self):
def handle(self, exception):
"""Render an exception view if the DEBUG configuration is True. Else this should not return anything.
Returns:
Expand Down Expand Up @@ -76,3 +86,42 @@ def _render(self):
}
).rendered_template
self._app.bind('Response', rendered_view)


class DD:

def __init__(self, container):
self.app = container

def dump(self, obj):
self.app.bind('ObjDump', obj)
raise DumpException


class DumpHandler:

def __init__(self, view: View, request: Request, app: App):
self.view = view
self.request = request
self.app = app

def handle(self, handle):
from config.database import Model
self.app.make('HookHandler').fire('*ExceptionHook')

template = self.view.render(
'/masonite/snippets/exceptions/dump', {
'obj': self.app.make('ObjDump'),
'type': type,
'list': list,
'inspect': inspect,
'members': inspect.getmembers(self.app.make('ObjDump'), predicate=inspect.ismethod),
'properties': inspect.getmembers(self.app.make('ObjDump')),
'hasattr': hasattr,
'getattr': getattr,
'Model': Model,
'isinstance': isinstance,
'show_methods': (bool, str, list, dict),
'len': len,
}).rendered_template
self.app.bind('Response', template)
8 changes: 8 additions & 0 deletions masonite/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,11 @@ class StrictContainerException(Exception):

class InvalidRouteCompileException(Exception):
pass


class DebugException(Exception):
pass


class DumpException(Exception):
pass
3 changes: 2 additions & 1 deletion masonite/info.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Module for specifying the Masonite version in a central location.
"""

VERSION = '2.0.31'

VERSION = '2.0.32'
Loading

0 comments on commit ae29340

Please sign in to comment.