Skip to content

Commit

Permalink
Fixed pesky templating + setup.py issues
Browse files Browse the repository at this point in the history
  • Loading branch information
mtford90 committed Jun 12, 2014
1 parent b288023 commit dde75de
Show file tree
Hide file tree
Showing 102 changed files with 4,655 additions and 21 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,6 @@ dist

# Vagrant
.vagrant

# Hardlinks
django_silky/silk
5 changes: 4 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,8 @@ install:
- pip install -q Django==$DJANGO_VERSION
- pip install -r requirements.txt

script: cd django_silky/ && ./manage.py test silk
script:
- cp -r silk django_silky/silk
- cd django_silky
- ./manage.py test silk

2 changes: 1 addition & 1 deletion django_silky/silk/templates/silk/base/detail_base.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% extends 'silk/templates/silk/base/base.html' %}
{% extends 'silk/base/base.html' %}
{% load staticfiles %}
{% block style %}
<link rel="stylesheet" href="{% static 'silk/lib/highlight/foundation.css' %}"/>
Expand Down
2 changes: 1 addition & 1 deletion django_silky/silk/templates/silk/base/root_base.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% extends "silk/templates/silk/base/base.html" %}
{% extends "silk/base/base.html" %}
{% load nav %}
{% load inclusion %}
{% load staticfiles %}
Expand Down
2 changes: 1 addition & 1 deletion django_silky/silk/templates/silk/profile_detail.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% extends "silk/templates/silk/base/detail_base.html" %}
{% extends "silk/base/detail_base.html" %}
{% load filters %}
{% load nav %}
{% load inclusion %}
Expand Down
2 changes: 1 addition & 1 deletion django_silky/silk/templates/silk/profiling.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% extends 'silk/templates/silk/base/root_base.html' %}
{% extends 'silk/base/root_base.html' %}
{% load inclusion %}

{% block menu %}
Expand Down
2 changes: 1 addition & 1 deletion django_silky/silk/templates/silk/request.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% extends "silk/templates/silk/base/base.html" %}
{% extends "silk/base/base.html" %}
{% load filters %}
{% load inclusion %}
{% load staticfiles %}
Expand Down
2 changes: 1 addition & 1 deletion django_silky/silk/templates/silk/requests.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% extends 'silk/templates/silk/base/root_base.html' %}
{% extends 'silk/base/root_base.html' %}
{% load inclusion %}

{% block menu %}
Expand Down
2 changes: 1 addition & 1 deletion django_silky/silk/templates/silk/sql.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% extends 'silk/templates/silk/base/base.html' %}
{% extends 'silk/base/base.html' %}

{% load nav %}
{% load filters %}
Expand Down
2 changes: 1 addition & 1 deletion django_silky/silk/templates/silk/sql_detail.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% extends "silk/templates/silk/base/detail_base.html" %}
{% extends "silk/base/detail_base.html" %}
{% load filters %}
{% load nav %}
{% load inclusion %}
Expand Down
14 changes: 7 additions & 7 deletions django_silky/silk/templatetags/inclusion.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ def code(lines, actual_line):
return {'code': lines, 'actual_line': [x.strip() for x in actual_line]}


register.inclusion_tag('silk/templates/silk/inclusion/request_summary.html')(request_summary)
register.inclusion_tag('silk/templates/silk/inclusion/profile_summary.html')(profile_summary)
register.inclusion_tag('silk/templates/silk/inclusion/code.html')(code)
register.inclusion_tag('silk/templates/silk/inclusion/request_menu.html')(request_menu)
register.inclusion_tag('silk/templates/silk/inclusion/profile_menu.html')(profile_menu)
register.inclusion_tag('silk/templates/silk/inclusion/root_menu.html')(root_menu)
register.inclusion_tag('silk/templates/silk/inclusion/heading.html')(heading)
register.inclusion_tag('silk/inclusion/request_summary.html')(request_summary)
register.inclusion_tag('silk/inclusion/profile_summary.html')(profile_summary)
register.inclusion_tag('silk/inclusion/code.html')(code)
register.inclusion_tag('silk/inclusion/request_menu.html')(request_menu)
register.inclusion_tag('silk/inclusion/profile_menu.html')(profile_menu)
register.inclusion_tag('silk/inclusion/root_menu.html')(root_menu)
register.inclusion_tag('silk/inclusion/heading.html')(heading)


8 changes: 4 additions & 4 deletions django_silky/silk/tests/test_view_sql_detail.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@ def test_allowed_file_paths_unavailable_source(self):
"""if we request to view source that is not in the tracebackk we should get a 403"""
request = MockSuite().mock_request()
query = MockSuite().mock_sql_queries(request=request, n=1)[0]
file_path = os.path.realpath(os.path.dirname(os.path.realpath(__file__)) + '/../../django_silky/settings.py')
with open(file_path, 'r') as f:
line_num = random.randint(0, len(f.read().split('\n')))
file_path = '/tmp/blah'
with open(file_path, 'w') as f:
f.write('test')
response = self.client.get(silky_reverse('request_sql_detail',
kwargs={'sql_id': query.id, 'request_id': request.id}),
data={
'line_num': line_num,
'line_num': 0,
'file_path': file_path
})
self.assertTrue(response.status_code == 403)
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

setup(
name='django-silk',
version='0.1.1',
version='0.2-alpha',
packages=['silk'],
include_package_data=True,
license='MIT License',
Expand Down
1 change: 1 addition & 0 deletions silk/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__author__ = 'mtford'
42 changes: 42 additions & 0 deletions silk/auth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from functools import wraps

from django.contrib.auth.decorators import login_required
from django.core.exceptions import PermissionDenied
from django.utils.decorators import available_attrs

from silk.config import SilkyConfig



# noinspection PyUnresolvedReferences
from six.moves.urllib.parse import urlparse

def login_possibly_required(function=None, **kwargs):
if SilkyConfig().SILKY_AUTHENTICATION:
return login_required(function, **kwargs)
return function


def permissions_possibly_required(function=None):
if SilkyConfig().SILKY_AUTHORISATION:
actual_decorator = user_passes_test(
SilkyConfig().SILKY_PERMISSIONS
)
if function:
return actual_decorator(function)
return actual_decorator
return function


def user_passes_test(test_func):
def decorator(view_func):
@wraps(view_func, assigned=available_attrs(view_func))
def _wrapped_view(request, *args, **kwargs):
if test_func(request.user):
return view_func(request, *args, **kwargs)
else:
raise PermissionDenied

return _wrapped_view

return decorator
1 change: 1 addition & 0 deletions silk/code_generation/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__author__ = 'mtford'
65 changes: 65 additions & 0 deletions silk/code_generation/curl.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import json
# import urllib

# noinspection PyUnresolvedReferences
from six.moves.urllib.parse import urlencode

import jinja2
from silk.profiling.profiler import silk_profile


curl_template = """
curl {% if method %}-X {{ method }}{% endif %}
{% if content_type %}-H 'Content-Type: {{ content_type }}'{% endif %}
{% if modifier %}{{ modifier }} {% endif %}{% if body %}'{{ body }}'{% endif %}
{{ url }}{% if query_params %}{{ query_params }}{% endif %}
{% if extra %}{{ extra }}{% endif %}
"""


def _curl_process_params(body, content_type, query_params):
extra = None
modifier = None
if query_params:
try:
query_params = urlencode(query_params)
except TypeError:
pass
query_params = '?' + str(query_params)
if 'json' in content_type or 'javascript' in content_type:
if isinstance(body, dict):
body = json.dumps(body)
modifier = '-d'
# See http://curl.haxx.se/docs/manpage.html#-F
# for multipart vs x-www-form-urlencoded
# x-www-form-urlencoded is same way as browser, multipart is RFC 2388 which allows file uploads.
elif 'multipart' in content_type or 'x-www-form-urlencoded' in content_type:
try:
body = ' '.join(['%s=%s' % (k, v) for k, v in body.items()])
except AttributeError:
modifier = '-d'
else:
content_type = None
modifier = '-F'
elif body:
body = str(body)
modifier = '-d'
else:
modifier = None
content_type = None
# TODO: Clean up.
return modifier, body, query_params, content_type, extra

def curl_cmd(url, method=None, query_params=None, body=None, content_type=None):
if not content_type:
content_type = 'text/plain'
modifier, body, query_params, content_type, extra = _curl_process_params(body, content_type, query_params)
t = jinja2.Template(curl_template)
return ' '.join(t.render(url=url,
method=method,
query_params=query_params,
body=body,
modifier=modifier,
content_type=content_type,
extra=extra).split('\n'))

52 changes: 52 additions & 0 deletions silk/code_generation/django_test_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import urllib

import autopep8

import jinja2
# noinspection PyUnresolvedReferences
from six.moves.urllib.parse import urlencode
from silk.profiling.dynamic import is_str_typ
from silk.profiling.profiler import silk_profile

template = """
from django.test import Client
c = Client()
response = c.{{ lower_case_method }}(path='{{ path }}'{% if data or content_type %},{% else %}){% endif %}{% if data %}
data={{ data }}{% endif %}{% if data and content_type %},{% elif data %}){% endif %}{% if content_type %}
content_type='{{ content_type }}'){% endif %}
"""


def _encode_query_params(query_params):
try:
query_params = urlencode(query_params)
except TypeError:
pass
query_params = '?' + query_params
return query_params

def gen(path,
method=None,
query_params=None,
data=None,
content_type=None):
"""generates python code representing a call via django client. useful for use in testing"""
method = method.lower()
t = jinja2.Template(template)
if method == 'get':
r = t.render(path=path,
data=query_params,
lower_case_method=method,
content_type=content_type)
else:
if query_params:
query_params = _encode_query_params(query_params)
path += query_params
if is_str_typ(data):
data = "'%s'" % data
r = t.render(path=path,
data=data,
lower_case_method=method,
query_params=query_params,
content_type=content_type)
return autopep8.fix_code(r, options=autopep8.parse_args(['--aggressive', '']))
98 changes: 98 additions & 0 deletions silk/collector.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
from threading import local

from six import with_metaclass
from silk import models
from silk.models import SQLQuery

from silk.singleton import Singleton


class DataCollector(with_metaclass(Singleton, object)):
"""
Provides the ability to save all models at the end of the request. We cannot save during
the request due to the possibility of atomic blocks and hence must collect data and perform
the save at the end.
"""
def __init__(self):
super(DataCollector, self).__init__()
self.local = local()
self._configure()

@property
def request(self):
return getattr(self.local, 'request', None)

def get_identifier(self):
self.local.temp_identifier += 1
return self.local.temp_identifier

@request.setter
def request(self, value):
self.local.request = value

@property
def queries(self):
queries = getattr(self.local, 'queries', {})
return queries.values()

@queries.setter
def queries(self, value):
self.local.queries = value

@property
def profiles(self):
profiles = getattr(self.local, 'profiles', {})
return profiles.values()

def query_with_temp_id(self, ident):
return self.local.queries.get(ident, None)

def profile_with_temp_id(self, ident):
return self.local.profiles.get(ident, None)

@profiles.setter
def profiles(self, value):
self.local.profiles = value

def _configure(self):
self.queries = {}
self.profiles = {}
self.local.temp_identifier = 0

def configure(self, request=None):
self.request = request
self._configure()

def clear(self):
self.request = None
self._configure()

def register_query(self, *args):
for arg in args:
ident = self.get_identifier()
arg['temp_id'] = ident
self.local.queries[ident] = arg

def register_profile(self, *args):
for arg in args:
ident = self.get_identifier()
arg['temp_id'] = ident
self.local.profiles[ident] = arg

def finalise(self):
for query in self.queries:
del(query['temp_id'])
query_model = models.SQLQuery.objects.create(**query)
query['pk'] = query_model.pk
for profile in self.profiles:
if 'temp_id' in profile:
del profile['temp_id']
if 'queries' in profile:
pks = [x['pk'] for x in profile['queries']]
del profile['queries']
else:
pks = []
profile = models.Profile.objects.create(**profile)
queries = SQLQuery.objects.filter(pk__in=pks)
profile.queries = queries
profile.save()
Loading

0 comments on commit dde75de

Please sign in to comment.