Skip to content

Commit

Permalink
Better clean.py script for preparing releases, #fixes quantmind#106. …
Browse files Browse the repository at this point in the history
…Removed Server and Date from HopHeaders, #fixes 108.
  • Loading branch information
lsbardel committed Mar 31, 2014
1 parent b82f342 commit e187075
Show file tree
Hide file tree
Showing 17 changed files with 105 additions and 115 deletions.
12 changes: 7 additions & 5 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
Ver. 0.8.1 - Development
Ver. 0.8.1 - 2014-Mar-31
===========================
* Added :mod:`pulsar.apps.greenio` application for writing asynchronous code
using the greenlet library.
using the greenlet library
* Moved :class:`.PulsarDS` server into its own :mod:`pulsar.apps.ds`
module.
module
* The task application can run on redis.
* Added support for :ref:`couchdb datastore <store_couchdb>` (alpha).
* Added :ref:`twisted integration <tutorials-twisted>` (alpha).
* Added support for :ref:`couchdb datastore <store_couchdb>` (alpha)
* Added :ref:`twisted integration <tutorials-twisted>` (alpha)
* Removed ``Server`` and ``Date`` from Hop headers
* Fixed installation problem with extensions
* More documentation for data stores.

Ver. 0.8.0 - 2014-Mar-06
Expand Down
5 changes: 1 addition & 4 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
include .gitignore
include MANIFEST.in
include LICENSE
include README.rst
Expand All @@ -7,6 +6,4 @@ include docs/Makefile
recursive-include examples *.py *.js *.css *.html
recursive-include pulsar/apps/test/plugins/htmlfiles *
recursive-include docs/source *
recursive-include extensions *.py *.pxd *.pyx *.h
include extensions/lua/src/*.c
include extensions/lua/ext/*.c
recursive-include extensions *.py *.pxd *.pyx *.h
4 changes: 2 additions & 2 deletions buildrelease.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
from datetime import datetime, date

import setup
from clean import rmfiles
import clean

rmfiles()
clean.run()
script = os.path.abspath(setup.__file__)

assert setup.mod.VERSION[3] == 'final'
Expand Down
38 changes: 23 additions & 15 deletions clean.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
import shutil

remove_dirs = ('dist', 'build', 'pulsar.egg-info')

def rmgeneric(path, __func__):
try:
Expand All @@ -12,33 +13,40 @@ def rmgeneric(path, __func__):
return 0


def rmfiles(path=None, ext='pyc', rmcache=True):
def rmfiles(path=None, *extensions):
path = path or os.curdir
if not os.path.isdir(path):
return 0
assert ext
assert extensions
for ext in extensions:
assert ext
trem = 0
tall = 0
files = os.listdir(path)
for f in files:
fullpath = os.path.join(path, f)
for name in files:
fullpath = os.path.join(path, name)
if os.path.isfile(fullpath):
sf = f.split('.')
if len(sf) == 2:
if ext is None or sf[1] == ext:
tall += 1
trem += rmgeneric(fullpath, os.remove)
elif f == '__pycache__' and rmcache:
sf = name.split('.')
if len(sf) == 2 and sf[1] in extensions:
tall += 1
trem += rmgeneric(fullpath, os.remove)
elif name == '__pycache__':
shutil.rmtree(fullpath)
tall += 1
elif os.path.isdir(fullpath):
r, ra = rmfiles(fullpath, ext)
elif os.path.isdir(fullpath) and not name.startswith('.'):
r, ra = rmfiles(fullpath, *extensions)
trem += r
tall += ra
return trem, tall


if __name__ == '__main__':
path = os.curdir
removed, allfiles = rmfiles(path, 'pyc')
def run():
for path in remove_dirs:
if os.path.isdir(path):
shutil.rmtree(path)
removed, allfiles = rmfiles(os.curdir, 'pyc', 'DS_Store')
print('removed {0} pyc files out of {1}'.format(removed, allfiles))


if __name__ == '__main__':
run()
16 changes: 7 additions & 9 deletions extensions/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

include_dirs = []
ext_errors = (CCompilerError, DistutilsExecError, DistutilsPlatformError)
if sys.platform == 'win32' and sys.version_info > (2, 6):
if sys.platform == 'win32':
# 2.6's distutils.msvc9compiler can raise an IOError when failing to
# find the compiler
ext_errors += (IOError,)
Expand Down Expand Up @@ -46,7 +46,7 @@ def build_extension(self, ext):
raise BuildFailed
raise

lib_path = os.path.dirname(__file__)
lib_path = 'extensions'


def lib_extension():
Expand All @@ -57,10 +57,8 @@ def lib_extension():
include_dirs=include_dirs)


extensions = [lib_extension()]

libparams = {
'ext_modules': cythonize(extensions),
'cmdclass': {'build_ext' : tolerant_build_ext},
'include_dirs': include_dirs
}
def libparams():
extensions = [lib_extension()]
return {'ext_modules': cythonize(extensions),
'cmdclass': {'build_ext' : tolerant_build_ext},
'include_dirs': include_dirs}
2 changes: 1 addition & 1 deletion pulsar/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -
'''Event driven concurrent framework for Python'''
VERSION = (0, 8, 1, 'beta', 1)
VERSION = (0, 8, 1, 'final', 0)

import os

Expand Down
51 changes: 25 additions & 26 deletions pulsar/apps/wsgi/content.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@
from pulsar import multi_async, Future, async, coroutine_return, chain_future
from pulsar.utils.pep import iteritems, is_string, to_string, ispy3k
from pulsar.utils.html import (slugify, INLINE_TAGS, tag_attributes, attr_iter,
csslink, dump_data_value, child_tag)
dump_data_value, child_tag)
from pulsar.utils.httpurl import remove_double_slash
from pulsar.utils.system import json

Expand Down Expand Up @@ -806,7 +806,7 @@ def absolute_path(self, path, with_media_ending=True):
if urlparams:
path = '%s?%s' % (path, urlparams)
if self.is_relative(path):
return remove_double_slash('/%s/%s' % (self.media_path, path))
return remove_double_slash('%s/%s' % (self.media_path, path))
else:
return path

Expand All @@ -832,32 +832,38 @@ def append(self, value):
{'all': [path1, ...],
'print': [path2, ...]}
'''
if value:
if isinstance(value, str):
if value is not None:
if isinstance(value, Html):
value = {'all': [value]}
elif isinstance(value, str):
value = {'all': [value]}
for media, values in value.items():
if isinstance(values, str):
values = (values,)
m = self.children.get(media, [])
for value in values:
if not isinstance(value, (tuple, list)):
value = (value, None)
path, condition = value
value = csslink(self.absolute_path(path), condition)
if value not in m:
m.append(value)
if not isinstance(value, Html):
if not isinstance(value, (tuple, list)):
value = (value, None)
path, condition = value
path = self.absolute_path(path)
value = Html('link', href=path, type='text/css',
rel='stylesheet')
if condition:
value = Html(None, '<!--[if %s]>', value,
'<![endif]-->')
m.append(value)
self.children[media] = m

def do_stream(self, request):
children = self.children
for medium in sorted(children):
paths = children[medium]
medium = '' if medium == 'all' else " media='%s'" % medium
medium = '' if medium == 'all' else medium
for path in paths:
link = ("<link href='%s' type='text/css'%s "
"rel='stylesheet'/>\n" % (path.link, medium))
if path.condition:
link = '<!--[if %s]>%s<![endif]-->' % (path.condition,
link)
yield link
if medium:
path.attr('media', medium)
yield path


class Scripts(Media):
Expand Down Expand Up @@ -1070,18 +1076,11 @@ def __init__(self, title=None, media_path='/media/', charset=None,
scripts_dependencies=scripts_dependencies,
charset=charset)
self.body = Html('body')

def __call__(self, title=None, body=None, media_path=None):
if title:
self.head.title = title
if media_path:
self.head.scripts.media_path = media_path
self.head.links.media_path = media_path
self.body.append(body)
return self
self.end = Html(None)

def do_stream(self, request):
# stream the body
self.body.append(self.end)
body = multi_async(self.body.stream(request))
# the body has asynchronous components
# delay the header untl later
Expand Down
10 changes: 5 additions & 5 deletions pulsar/apps/wsgi/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
with the standard `WSGI 1.0.1`_ specification with the following two
exceptions:
* It can return a :class:`.Future`.
* If it returns a :class:`.Future`, it must result in an
* It can return a :class:`~asyncio.Future`.
* If it returns a :class:`~asyncio.Future`, it must results in an
:ref:`asynchronous iterable <wsgi-async-iter>`.
Pulsar is shipped with two WSGI application handlers documented below.
Expand All @@ -44,13 +44,13 @@
========================
An asynchronous iterable is an iterable over a combination of ``bytes`` or
:class:`.Future` which result in ``bytes``.
:class:`~asyncio.Future` which result in ``bytes``.
For example this could be an asynchronous iterable::
def simple_async():
yield b'hello'
c = pulsar.Future()
c.callback(b' ')
c = Future()
c.set_result(b' ')
yield c
yield b'World!'
Expand Down
4 changes: 1 addition & 3 deletions pulsar/apps/wsgi/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,7 @@
'te',
'trailers',
'transfer-encoding',
'upgrade',
'server',
'date')
'upgrade')
)

logger = logging.getLogger('pulsar.wsgi')
Expand Down
4 changes: 2 additions & 2 deletions pulsar/apps/wsgi/wrappers.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ def __str__(self):

@cached_property
def content_types(self):
'''List of content types this client supports as
'''List of content types this client supports as a
:class:`.ContentAccept` object.
Obtained form the ``Accept`` request header.
Expand All @@ -392,7 +392,7 @@ def content_types(self):

@cached_property
def charsets(self):
'''List of charsets this client supports as
'''List of charsets this client supports as a
:class:`.CharsetAccept` object.
Obtained form the ``Accept-Charset`` request header.
Expand Down
14 changes: 11 additions & 3 deletions pulsar/utils/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,10 @@ class Config(object):
def __init__(self, description=None, epilog=None,
version=None, apps=None, include=None,
exclude=None, settings=None, prefix=None,
name=None, **params):
name=None, log_name=None, **params):
self.settings = {} if settings is None else settings
self.name = name
self.log_name = log_name
self.prefix = prefix
self.include = set(include or ())
self.exclude = set(exclude or ())
Expand Down Expand Up @@ -213,7 +214,9 @@ def set(self, name, value, default=False):
If ``default`` is ``True``, the :attr:`Setting.default` is also set.
'''
if name not in self.settings:
if name in self.__dict__:
self.__dict__[name] = value
elif name not in self.settings:
# not in settings, check if this is a prefixed name
if self.prefix:
prefix_name = '%s_%s' % (self.prefix, name)
Expand Down Expand Up @@ -347,7 +350,10 @@ def configured_logger(self, name=None):
'''
loggers = {}
loghandlers = self.loghandlers
name = 'pulsar.%s' % (name or self.name)
if not name and self.log_name:
name = self.log_name
else:
name = 'pulsar.%s' % (name or self.name)
default_loglevel = None
for loglevel in self.loglevel or ():
bits = loglevel.split('.')
Expand Down Expand Up @@ -857,6 +863,7 @@ class Loglevel(Global):
name = "loglevel"
flags = ["--log-level"]
nargs = '+'
default = ['info']
validator = validate_list
desc = '''
The granularity of log outputs.
Expand All @@ -877,6 +884,7 @@ class Loglevel(Global):
class LogHandlers(Global):
name = "loghandlers"
flags = ["--log-handlers"]
nargs = '+'
default = ['console']
validator = validate_list
desc = '''Log handlers for pulsar server'''
Expand Down
7 changes: 3 additions & 4 deletions pulsar/utils/html.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@
'''
import re
from unicodedata import normalize
from collections import namedtuple

from .system import json
from .pep import (ispy3k, native_str, to_string, iteritems, is_string,
string_type)

NOTHING = ('', b'', None)
'''Tuple of elements considered as null.'''
INLINE_TAGS = set(('input', 'meta', 'hr'))
INLINE_TAGS = set(('input', 'link', 'meta', 'hr'))
# The global attributes below can be used on any HTML element
# class and style are misssing here since they are treated separately
GLOBAL_HTML_ATTRIBUTES = ('accesskey', 'contenteditable', 'contextmenu', 'dir',
Expand Down Expand Up @@ -47,6 +46,8 @@
HTML_ATTRIBUTES['input[type="radio"]'] = input_attr('checked')
HTML_ATTRIBUTES['input[type="submit"]'] = input_attr(
'formaction', 'formenctype', 'formmethod', 'formtarget')
HTML_ATTRIBUTES['link'] = e('href', 'hreflang', 'media', 'rel',
'sizes', 'type')
HTML_ATTRIBUTES['meta'] = e('name', 'charset', 'content')
HTML_ATTRIBUTES['option'] = e('disabled', 'label', 'selected', 'value')
HTML_ATTRIBUTES['script'] = e('async', 'charset', 'defer', 'src', 'type')
Expand Down Expand Up @@ -80,8 +81,6 @@
HTML_EMDASH = '&mdash;'
'''HTML -- symbol.'''

csslink = namedtuple('cssentry', 'link condition')


def tag_attributes(tag, type=None):
'''Return a tuple of valid attributes for the HTML ``tag`` and optional
Expand Down
Loading

0 comments on commit e187075

Please sign in to comment.