diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 7397053..d9831c0 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,9 @@ Version 0.8.5a16 ============================================================ * Upgrade dependencies and setup for 0.8.5 +* Remove `hyde.fs` use `fswrap` package instead. +* Remove logging functions from `hyde.util`. Use `commando.util` instead. +* Remove `hyde.loader`. Use `commando.util.load_python_object` instead. * Bug fix: Use the released version of typogrify. (Issue #193) Version 0.8.5a15 diff --git a/hyde/engine.py b/hyde/engine.py index bfab25c..da5d286 100644 --- a/hyde/engine.py +++ b/hyde/engine.py @@ -2,6 +2,12 @@ """ Implements the hyde entry point commands """ +from hyde.exceptions import HydeException +from hyde.layout import Layout, HYDE_DATA +from hyde.model import Config +from hyde.site import Site +from hyde.version import __version__ + from commando import ( Application, command, @@ -10,19 +16,21 @@ from commando import ( true, version ) -from hyde.exceptions import HydeException -from hyde.fs import FS, Folder -from hyde.layout import Layout, HYDE_DATA -from hyde.model import Config -from hyde.site import Site -from hyde.version import __version__ -from hyde.util import getLoggerWithConsoleHandler +from commando.util import getLoggerWithConsoleHandler +from fswrap import FS, Folder HYDE_LAYOUTS = "HYDE_LAYOUTS" class Engine(Application): + def __init__(self, raise_exceptions=True): + logger = getLoggerWithConsoleHandler('hyde') + super(Engine, self).__init__( + raise_exceptions=raise_exceptions, + logger=logger + ) + @command(description='hyde - a python static website generator', epilog='Use %(prog)s {command} -h to get help on individual commands') @true('-v', '--verbose', help="Show detailed information in console") @@ -34,10 +42,6 @@ class Engine(Application): to provide common parameters for the subcommands and some generic stuff like version and metadata """ - if args.verbose: - import logging - self.logger.setLevel(logging.DEBUG) - sitepath = Folder(args.sitepath).fully_expanded_path return Folder(sitepath) diff --git a/hyde/ext/plugins/folders.py b/hyde/ext/plugins/folders.py index 6a25add..7769628 100644 --- a/hyde/ext/plugins/folders.py +++ b/hyde/ext/plugins/folders.py @@ -4,7 +4,8 @@ Plugins related to folders and paths """ from hyde.plugin import Plugin -from hyde.fs import Folder + +from fswrap import Folder class FlattenerPlugin(Plugin): """ diff --git a/hyde/ext/plugins/git.py b/hyde/ext/plugins/git.py index 996a865..24c0285 100644 --- a/hyde/ext/plugins/git.py +++ b/hyde/ext/plugins/git.py @@ -6,7 +6,6 @@ Contains classes and utilities to extract information from git repository from hyde.plugin import Plugin import subprocess -import traceback from dateutil.parser import parse class GitDatesPlugin(Plugin): diff --git a/hyde/ext/plugins/grouper.py b/hyde/ext/plugins/grouper.py index d07e1f5..63d4e5f 100644 --- a/hyde/ext/plugins/grouper.py +++ b/hyde/ext/plugins/grouper.py @@ -3,16 +3,12 @@ Contains classes and utilities related to grouping resources and nodes in hyde. """ -import re from hyde.model import Expando from hyde.plugin import Plugin from hyde.site import Node, Resource from hyde.util import add_method, add_property, pairwalk from collections import namedtuple -from functools import partial -from itertools import ifilter, izip, tee, product -from operator import attrgetter Grouper = namedtuple('Grouper', 'group resources') diff --git a/hyde/ext/plugins/jpegoptim.py b/hyde/ext/plugins/jpegoptim.py index 7dc005f..b623f10 100644 --- a/hyde/ext/plugins/jpegoptim.py +++ b/hyde/ext/plugins/jpegoptim.py @@ -4,7 +4,8 @@ jpegoptim plugin """ from hyde.plugin import CLTransformer -from hyde.fs import File + +from fswrap import File class JPEGOptimPlugin(CLTransformer): """ diff --git a/hyde/ext/plugins/less.py b/hyde/ext/plugins/less.py index d64d706..8b1e3f5 100644 --- a/hyde/ext/plugins/less.py +++ b/hyde/ext/plugins/less.py @@ -4,11 +4,11 @@ Less css plugin """ from hyde.plugin import CLTransformer -from hyde.fs import File import re import subprocess +from fswrap import File class LessCSSPlugin(CLTransformer): """ diff --git a/hyde/ext/plugins/optipng.py b/hyde/ext/plugins/optipng.py index 3b6dc2b..0c517c8 100644 --- a/hyde/ext/plugins/optipng.py +++ b/hyde/ext/plugins/optipng.py @@ -4,7 +4,8 @@ OPTIPNG plugin """ from hyde.plugin import CLTransformer -from hyde.fs import File + +from fswrap import File class OptiPNGPlugin(CLTransformer): """ diff --git a/hyde/ext/plugins/paginator.py b/hyde/ext/plugins/paginator.py index 1998707..ded8954 100644 --- a/hyde/ext/plugins/paginator.py +++ b/hyde/ext/plugins/paginator.py @@ -5,11 +5,12 @@ each page to a copy of the original resource. """ import os -from hyde.fs import File from hyde.plugin import Plugin from hyde.site import Resource from hyde.util import pairwalk +from fswrap import File + class Page: def __init__(self, posts, number): self.posts = posts diff --git a/hyde/ext/plugins/sorter.py b/hyde/ext/plugins/sorter.py index 894b540..b73ce9d 100644 --- a/hyde/ext/plugins/sorter.py +++ b/hyde/ext/plugins/sorter.py @@ -3,8 +3,6 @@ Contains classes and utilities related to sorting resources and nodes in hyde. """ -import re -from hyde.model import Expando from hyde.plugin import Plugin from hyde.site import Node, Resource from hyde.util import add_method, pairwalk @@ -40,7 +38,7 @@ def attributes_checker(item, attributes=None): Checks if the given list of attributes exist. """ try: - x = attrgetter(*attributes)(item) + attrgetter(*attributes)(item) return True except AttributeError: return False diff --git a/hyde/ext/plugins/sphinx.py b/hyde/ext/plugins/sphinx.py index 9f342b0..c7e0768 100644 --- a/hyde/ext/plugins/sphinx.py +++ b/hyde/ext/plugins/sphinx.py @@ -41,16 +41,16 @@ hyde templating workflow. You would end up with:: from __future__ import absolute_import import os -import sys import json -import tempfile +import tempfile from hyde.plugin import Plugin -from hyde.fs import File, Folder from hyde.model import Expando from hyde.ext.plugins.meta import MetaPlugin as _MetaPlugin -from hyde.util import getLoggerWithNullHandler +from commado.util import getLoggerWithNullHandler +from fswrap import File, Folder + logger = getLoggerWithNullHandler('hyde.ext.plugins.sphinx') try: @@ -101,7 +101,7 @@ class SphinxPlugin(Plugin): def sphinx_config(self): """Configuration options for sphinx. - This is a lazily-generated property giving the options from the + This is a lazily-generated property giving the options from the sphinx configuration file. It's generated by actualy executing the config file, so don't do anything silly in there. """ @@ -276,7 +276,7 @@ class HydeJSONHTMLBuilder(JSONHTMLBuilder): This is a Sphinx builder that serilises the generated HTML fragments into a JSON docuent, so they can be later retrieved and dealt with at will. - The only customistion we do over the standard JSONHTMLBuilder is to + The only customistion we do over the standard JSONHTMLBuilder is to reference documents with a .html suffix, so that internal link will work correctly once things have been processed by Hyde. """ diff --git a/hyde/ext/plugins/stylus.py b/hyde/ext/plugins/stylus.py index 20d7b37..b35ad2a 100644 --- a/hyde/ext/plugins/stylus.py +++ b/hyde/ext/plugins/stylus.py @@ -4,11 +4,11 @@ Less css plugin """ from hyde.plugin import CLTransformer -from hyde.fs import File import re import subprocess +from fswrap import File class StylusPlugin(CLTransformer): """ diff --git a/hyde/ext/plugins/tagger.py b/hyde/ext/plugins/tagger.py index 6608a88..ff3f28d 100644 --- a/hyde/ext/plugins/tagger.py +++ b/hyde/ext/plugins/tagger.py @@ -3,19 +3,15 @@ Contains classes and utilities related to tagging resources in hyde. """ -import re -from hyde.fs import File, Folder + from hyde.model import Expando from hyde.plugin import Plugin -from hyde.site import Node, Resource -from hyde.util import add_method, add_property, pairwalk +from hyde.site import Node +from hyde.util import add_method -from collections import namedtuple -from datetime import datetime -from functools import partial -from itertools import ifilter, izip, tee, product from operator import attrgetter +from fswrap import File, Folder class Tag(Expando): """ diff --git a/hyde/ext/plugins/uglify.py b/hyde/ext/plugins/uglify.py index e6a2664..de4f848 100644 --- a/hyde/ext/plugins/uglify.py +++ b/hyde/ext/plugins/uglify.py @@ -4,7 +4,8 @@ Uglify plugin """ from hyde.plugin import CLTransformer -from hyde.fs import File + +from fswrap import File class UglifyPlugin(CLTransformer): """ diff --git a/hyde/ext/plugins/urls.py b/hyde/ext/plugins/urls.py index a290d88..393f634 100644 --- a/hyde/ext/plugins/urls.py +++ b/hyde/ext/plugins/urls.py @@ -2,14 +2,12 @@ """ Contains classes and utilities related to hyde urls. """ -import re -from hyde.fs import File, Folder -from hyde.model import Expando from hyde.plugin import Plugin -from hyde.site import Site, Node, Resource +from hyde.site import Site from functools import wraps +from fswrap import File class UrlCleanerPlugin(Plugin): """ diff --git a/hyde/ext/publishers/dvcs.py b/hyde/ext/publishers/dvcs.py index dbbca44..ae880f7 100644 --- a/hyde/ext/publishers/dvcs.py +++ b/hyde/ext/publishers/dvcs.py @@ -3,12 +3,9 @@ Contains classes and utilities that help publishing a hyde website to distributed version control systems. """ -import sys -import abc - -from hyde.fs import File, Folder from hyde.publisher import Publisher +import abc from subprocess import Popen, PIPE class DVCS(Publisher): diff --git a/hyde/ext/publishers/pyfs.py b/hyde/ext/publishers/pyfs.py index 5a9b4ff..d8219e6 100644 --- a/hyde/ext/publishers/pyfs.py +++ b/hyde/ext/publishers/pyfs.py @@ -14,10 +14,11 @@ are valid URLs that can be used with this publisher: import getpass import hashlib -from hyde.fs import File, Folder + from hyde.publisher import Publisher -from hyde.util import getLoggerWithNullHandler +from commando.util import getLoggerWithNullHandler + logger = getLoggerWithNullHandler('hyde.ext.publishers.pyfs') diff --git a/hyde/ext/publishers/pypi.py b/hyde/ext/publishers/pypi.py index 5292da1..5980f59 100644 --- a/hyde/ext/publishers/pypi.py +++ b/hyde/ext/publishers/pypi.py @@ -13,10 +13,9 @@ import urlparse from base64 import standard_b64encode import ConfigParser -from hyde.fs import File, Folder from hyde.publisher import Publisher -from hyde.util import getLoggerWithNullHandler +from commando.util import getLoggerWithNullHandler logger = getLoggerWithNullHandler('hyde.ext.publishers.pypi') @@ -136,5 +135,5 @@ class PyPI(Publisher): con.close() finally: tf.close() - + diff --git a/hyde/ext/templates/jinja.py b/hyde/ext/templates/jinja.py index 2b62d56..7e591f6 100644 --- a/hyde/ext/templates/jinja.py +++ b/hyde/ext/templates/jinja.py @@ -11,15 +11,20 @@ from urllib import quote, unquote from hyde.model import Expando from hyde.template import HtmlWrap, Template -from hyde.util import getLoggerWithNullHandler from operator import attrgetter -from jinja2 import contextfunction, Environment -from jinja2 import FileSystemLoader, FileSystemBytecodeCache +from jinja2 import ( + contextfunction, + Environment, + FileSystemLoader, + FileSystemBytecodeCache +) from jinja2 import contextfilter, environmentfilter, Markup, Undefined, nodes from jinja2.ext import Extension from jinja2.exceptions import TemplateError +from commando.util import getLoggerWithNullHandler + logger = getLoggerWithNullHandler('hyde.engine.Jinja2') class SilentUndefined(Undefined): diff --git a/hyde/fs.py b/hyde/fs.py deleted file mode 100644 index cf4bb8e..0000000 --- a/hyde/fs.py +++ /dev/null @@ -1,618 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Unified object oriented interface for interacting with file system objects. -File system operations in python are distributed across modules: os, os.path, -fnamtch, shutil and distutils. This module attempts to make the right choices -for common operations to provide a single interface. -""" - -import codecs -from datetime import datetime -import mimetypes -import os -import shutil -from distutils import dir_util -import functools -import fnmatch - -from hyde.util import getLoggerWithNullHandler - -logger = getLoggerWithNullHandler('fs') - -# pylint: disable-msg=E0611 - - -__all__ = ['File', 'Folder'] - - -class FS(object): - """ - The base file system object - """ - - def __init__(self, path): - super(FS, self).__init__() - if path == os.sep: - self.path = path - else: - self.path = os.path.expandvars(os.path.expanduser( - unicode(path).strip().rstrip(os.sep))) - - def __str__(self): - return self.path - - def __repr__(self): - return self.path - - def __eq__(self, other): - return unicode(self) == unicode(other) - - def __ne__(self, other): - return unicode(self) != unicode(other) - - @property - def fully_expanded_path(self): - """ - Returns the absolutely absolute path. Calls os.( - normpath, normcase, expandvars and expanduser). - """ - return os.path.abspath( - os.path.normpath( - os.path.normcase( - os.path.expandvars( - os.path.expanduser(self.path))))) - - @property - def exists(self): - """ - Does the file system object exist? - """ - return os.path.exists(self.path) - - @property - def name(self): - """ - Returns the name of the FS object with its extension - """ - return os.path.basename(self.path) - - @property - def parent(self): - """ - The parent folder. Returns a `Folder` object. - """ - return Folder(os.path.dirname(self.path)) - - @property - def depth(self): - """ - Returns the number of ancestors of this directory. - """ - return len(self.path.rstrip(os.sep).split(os.sep)) - - def ancestors(self, stop=None): - """ - Generates the parents until stop or the absolute - root directory is reached. - """ - folder = self - while folder.parent != stop: - if folder.parent == folder: - return - yield folder.parent - folder = folder.parent - - def is_descendant_of(self, ancestor): - """ - Checks if this folder is inside the given ancestor. - """ - stop = Folder(ancestor) - for folder in self.ancestors(): - if folder == stop: - return True - if stop.depth > folder.depth: - return False - return False - - def get_relative_path(self, root): - """ - Gets the fragment of the current path starting at root. - """ - if self.path == root: - return '' - ancestors = self.ancestors(stop=root) - return functools.reduce(lambda f, p: Folder(p.name).child(f), - ancestors, - self.name) - - def get_mirror(self, target_root, source_root=None): - """ - Returns a File or Folder object that reperesents if the entire - fragment of this directory starting with `source_root` were copied - to `target_root`. - - >>> Folder('/usr/local/hyde/stuff').get_mirror('/usr/tmp', - source_root='/usr/local/hyde') - Folder('/usr/tmp/stuff') - """ - fragment = self.get_relative_path( - source_root if source_root else self.parent) - return Folder(target_root).child(fragment) - - @staticmethod - def file_or_folder(path): - """ - Returns a File or Folder object that would represent the given path. - """ - target = unicode(path) - return Folder(target) if os.path.isdir(target) else File(target) - - def __get_destination__(self, destination): - """ - Returns a File or Folder object that would represent this entity - if it were copied or moved to `destination`. - """ - if isinstance(destination, File) or os.path.isfile(unicode(destination)): - return destination - else: - return FS.file_or_folder(Folder(destination).child(self.name)) - - -class File(FS): - """ - The File object. - """ - - def __init__(self, path): - super(File, self).__init__(path) - - @property - def name_without_extension(self): - """ - Returns the name of the FS object without its extension - """ - return os.path.splitext(self.name)[0] - - @property - def extension(self): - """ - File extension prefixed with a dot. - """ - return os.path.splitext(self.path)[1] - - @property - def kind(self): - """ - File extension without dot prefix. - """ - return self.extension.lstrip(".") - - @property - def size(self): - """ - Size of this file. - """ - - if not self.exists: - return -1 - return os.path.getsize(self.path) - - @property - def mimetype(self): - """ - Gets the mimetype of this file. - """ - (mime, _) = mimetypes.guess_type(self.path) - return mime - - @property - def is_binary(self): - """Return true if this is a binary file.""" - with open(self.path, 'rb') as fin: - CHUNKSIZE = 1024 - while 1: - chunk = fin.read(CHUNKSIZE) - if '\0' in chunk: - return True - if len(chunk) < CHUNKSIZE: - break - return False - - @property - def is_text(self): - """Return true if this is a text file.""" - return (not self.is_binary) - - @property - def is_image(self): - """Return true if this is an image file.""" - return self.mimetype.split("/")[0] == "image" - - - @property - def last_modified(self): - """ - Returns a datetime object representing the last modified time. - Calls os.path.getmtime. - - """ - return datetime.fromtimestamp(os.path.getmtime(self.path)) - - def has_changed_since(self, basetime): - """ - Returns True if the file has been changed since the given time. - - """ - return self.last_modified > basetime - - def older_than(self, another_file): - """ - Checks if this file is older than the given file. Uses last_modified to - determine age. - - """ - return self.last_modified < File(unicode(another_file)).last_modified - - @staticmethod - def make_temp(text): - """ - Creates a temprorary file and writes the `text` into it - """ - import tempfile - (handle, path) = tempfile.mkstemp(text=True) - os.close(handle) - afile = File(path) - afile.write(text) - return afile - - def read_all(self, encoding='utf-8'): - """ - Reads from the file and returns the content as a string. - """ - logger.info("Reading everything from %s" % self) - with codecs.open(self.path, 'r', encoding) as fin: - read_text = fin.read() - return read_text - - def write(self, text, encoding="utf-8"): - """ - Writes the given text to the file using the given encoding. - """ - logger.info("Writing to %s" % self) - with codecs.open(self.path, 'w', encoding) as fout: - fout.write(text) - - def copy_to(self, destination): - """ - Copies the file to the given destination. Returns a File - object that represents the target file. `destination` must - be a File or Folder object. - """ - target = self.__get_destination__(destination) - logger.info("Copying %s to %s" % (self, target)) - shutil.copy(self.path, unicode(destination)) - return target - - def delete(self): - """ - Delete the file if it exists. - """ - if self.exists: - os.remove(self.path) - - -class FSVisitor(object): - """ - Implements syntactic sugar for walking and listing folders - """ - - def __init__(self, folder, pattern=None): - super(FSVisitor, self).__init__() - self.folder = folder - self.pattern = pattern - - def folder_visitor(self, function): - """ - Decorator for `visit_folder` protocol - """ - self.visit_folder = function - return function - - def file_visitor(self, function): - """ - Decorator for `visit_file` protocol - """ - self.visit_file = function - return function - - def finalizer(self, function): - """ - Decorator for `visit_complete` protocol - """ - self.visit_complete = function - return function - - def __enter__(self): - return self - - def __exit__(self, exc_type, exc_val, exc_tb): - pass - - -class FolderWalker(FSVisitor): - """ - Walks the entire hirearchy of this directory starting with itself. - - If a pattern is provided, only the files that match the pattern are - processed. - """ - - def walk(self, walk_folders=False, walk_files=False): - """ - A simple generator that yields a File or Folder object based on - the arguments. - """ - - if not walk_files and not walk_folders: - return - - for root, _, a_files in os.walk(self.folder.path, followlinks=True): - folder = Folder(root) - if walk_folders: - yield folder - if walk_files: - for a_file in a_files: - if (not self.pattern or - fnmatch.fnmatch(a_file, self.pattern)): - yield File(folder.child(a_file)) - - def walk_all(self): - """ - Yield both Files and Folders as the tree is walked. - """ - - return self.walk(walk_folders=True, walk_files=True) - - def walk_files(self): - """ - Yield only Files. - """ - return self.walk(walk_folders=False, walk_files=True) - - def walk_folders(self): - """ - Yield only Folders. - """ - return self.walk(walk_folders=True, walk_files=False) - - def __exit__(self, exc_type, exc_val, exc_tb): - """ - Automatically walk the folder when the context manager is exited. - - Calls self.visit_folder first and then calls self.visit_file for - any files found. After all files and folders have been exhausted - self.visit_complete is called. - - If visitor.visit_folder returns False, the files in the folder are not - processed. - """ - - def __visit_folder__(folder): - process_folder = True - if hasattr(self, 'visit_folder'): - process_folder = self.visit_folder(folder) - # If there is no return value assume true - # - if process_folder is None: - process_folder = True - return process_folder - - def __visit_file__(a_file): - if hasattr(self, 'visit_file'): - self.visit_file(a_file) - - def __visit_complete__(): - if hasattr(self, 'visit_complete'): - self.visit_complete() - - for root, dirs, a_files in os.walk(self.folder.path, followlinks=True): - folder = Folder(root) - if not __visit_folder__(folder): - dirs[:] = [] - continue - for a_file in a_files: - if not self.pattern or fnmatch.fnmatch(a_file, self.pattern): - __visit_file__(File(folder.child(a_file))) - __visit_complete__() - - -class FolderLister(FSVisitor): - """ - Lists the contents of this directory. - - If a pattern is provided, only the files that match the pattern are - processed. - """ - - def list(self, list_folders=False, list_files=False): - """ - A simple generator that yields a File or Folder object based on - the arguments. - """ - - a_files = os.listdir(self.folder.path) - for a_file in a_files: - path = self.folder.child(a_file) - if os.path.isdir(path): - if list_folders: - yield Folder(path) - elif list_files: - if not self.pattern or fnmatch.fnmatch(a_file, self.pattern): - yield File(path) - - def list_all(self): - """ - Yield both Files and Folders as the folder is listed. - """ - - return self.list(list_folders=True, list_files=True) - - def list_files(self): - """ - Yield only Files. - """ - return self.list(list_folders=False, list_files=True) - - def list_folders(self): - """ - Yield only Folders. - """ - return self.list(list_folders=True, list_files=False) - - def __exit__(self, exc_type, exc_val, exc_tb): - """ - Automatically list the folder contents when the context manager - is exited. - - Calls self.visit_folder first and then calls self.visit_file for - any files found. After all files and folders have been exhausted - self.visit_complete is called. - """ - - a_files = os.listdir(self.folder.path) - for a_file in a_files: - path = self.folder.child(a_file) - if os.path.isdir(path) and hasattr(self, 'visit_folder'): - self.visit_folder(Folder(path)) - elif hasattr(self, 'visit_file'): - if not self.pattern or fnmatch.fnmatch(a_file, self.pattern): - self.visit_file(File(path)) - if hasattr(self, 'visit_complete'): - self.visit_complete() - - -class Folder(FS): - """ - Represents a directory. - """ - - def __init__(self, path): - super(Folder, self).__init__(path) - - def child_folder(self, fragment): - """ - Returns a folder object by combining the fragment to this folder's path - """ - return Folder(os.path.join(self.path, Folder(fragment).path)) - - def child(self, fragment): - """ - Returns a path of a child item represented by `fragment`. - """ - return os.path.join(self.path, FS(fragment).path) - - def make(self): - """ - Creates this directory and any of the missing directories in the path. - Any errors that may occur are eaten. - """ - try: - if not self.exists: - logger.info("Creating %s" % self.path) - os.makedirs(self.path) - except os.error: - pass - return self - - def delete(self): - """ - Deletes the directory if it exists. - """ - if self.exists: - logger.info("Deleting %s" % self.path) - shutil.rmtree(self.path) - - def copy_to(self, destination): - """ - Copies this directory to the given destination. Returns a Folder object - that represents the moved directory. - """ - target = self.__get_destination__(destination) - logger.info("Copying %s to %s" % (self, target)) - shutil.copytree(self.path, unicode(target)) - return target - - def move_to(self, destination): - """ - Moves this directory to the given destination. Returns a Folder object - that represents the moved directory. - """ - target = self.__get_destination__(destination) - logger.info("Move %s to %s" % (self, target)) - shutil.move(self.path, unicode(target)) - return target - - def rename_to(self, destination_name): - """ - Moves this directory to the given destination. Returns a Folder object - that represents the moved directory. - """ - target = self.parent.child_folder(destination_name) - logger.info("Rename %s to %s" % (self, target)) - shutil.move(self.path, unicode(target)) - return target - - def _create_target_tree(self, target): - """ - There is a bug in dir_util that makes `copy_tree` crash if a folder in - the tree has been deleted before and readded now. To workaround the - bug, we first walk the tree and create directories that are needed. - """ - source = self - with source.walker as walker: - - @walker.folder_visitor - def visit_folder(folder): - """ - Create the mirror directory - """ - if folder != source: - Folder(folder.get_mirror(target, source)).make() - - def copy_contents_to(self, destination): - """ - Copies the contents of this directory to the given destination. - Returns a Folder object that represents the moved directory. - """ - logger.info("Copying contents of %s to %s" % (self, destination)) - target = Folder(destination) - target.make() - self._create_target_tree(target) - dir_util.copy_tree(self.path, unicode(target)) - return target - - def get_walker(self, pattern=None): - """ - Return a `FolderWalker` object with a set pattern. - """ - return FolderWalker(self, pattern) - - @property - def walker(self): - """ - Return a `FolderWalker` object - """ - return FolderWalker(self) - - def get_lister(self, pattern=None): - """ - Return a `FolderLister` object with a set pattern. - """ - return FolderLister(self, pattern) - - @property - def lister(self): - """ - Return a `FolderLister` object - """ - return FolderLister(self) \ No newline at end of file diff --git a/hyde/generator.py b/hyde/generator.py index 93036af..0b42e2b 100644 --- a/hyde/generator.py +++ b/hyde/generator.py @@ -4,17 +4,17 @@ The generator class and related utility functions. """ from hyde.exceptions import HydeException -from hyde.fs import File, Folder +from fswrap import File, Folder from hyde.model import Context, Dependents from hyde.plugin import Plugin from hyde.template import Template -from hyde.site import Node, Resource +from hyde.site import Resource from contextlib import contextmanager from datetime import datetime from shutil import copymode -from hyde.util import getLoggerWithNullHandler +from commando.util import getLoggerWithNullHandler logger = getLoggerWithNullHandler('hyde.engine') diff --git a/hyde/layout.py b/hyde/layout.py index a56c3ee..fd83a68 100644 --- a/hyde/layout.py +++ b/hyde/layout.py @@ -4,7 +4,7 @@ Classes, functions and utilties related to hyde layouts """ import os -from hyde.fs import File, Folder +from fswrap import File, Folder HYDE_DATA = "HYDE_DATA" LAYOUTS = "layouts" diff --git a/hyde/loader.py b/hyde/loader.py deleted file mode 100644 index fa8c5b8..0000000 --- a/hyde/loader.py +++ /dev/null @@ -1,49 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Generic loader of extensions (plugins & templates) -""" -import sys - -from hyde.exceptions import HydeException - -from hyde.util import getLoggerWithNullHandler -logger = getLoggerWithNullHandler('hyde.engine') - -plugins = {} -templates = {} - - -def load_python_object(name): - """ - Loads a python module from string - """ - (module_name, _, object_name) = name.rpartition(".") - if module_name == '': - (module_name, object_name) = (object_name, module_name) - try: - logger.debug('Loading module [%s]' % module_name) - module = __import__(module_name) - except ImportError: - raise HydeException("The given module name [%s] is invalid." % - module_name) - - if object_name == '': - return module - - try: - module = sys.modules[module_name] - except KeyError: - raise HydeException("Error occured when loading module [%s]" % - module_name) - - try: - logger.debug('Getting object [%s] from module [%s]' % - (object_name, module_name)) - return getattr(module, object_name) - except AttributeError: - raise HydeException("Cannot load the specified plugin [%s]. " - "The given module [%s] does not contain the " - "desired object [%s]. Please fix the " - "configuration or ensure that the module is " - "installed properly" % - (name, module_name, object_name)) diff --git a/hyde/model.py b/hyde/model.py index 4e33cc0..cd68a76 100644 --- a/hyde/model.py +++ b/hyde/model.py @@ -2,14 +2,14 @@ """ Contains data structures and utilities for hyde. """ -from hyde.fs import File, Folder - import codecs import yaml from datetime import datetime from UserDict import IterableUserDict -from hyde.util import getLoggerWithNullHandler +from commando.util import getLoggerWithNullHandler +from fswrap import File, Folder + logger = getLoggerWithNullHandler('hyde.engine') class Expando(object): diff --git a/hyde/plugin.py b/hyde/plugin.py index 90e7e9f..66904fa 100644 --- a/hyde/plugin.py +++ b/hyde/plugin.py @@ -2,23 +2,21 @@ """ Contains definition for a plugin protocol and other utiltities. """ -import abc - -from hyde import loader - from hyde.exceptions import HydeException -from hyde.fs import File -from hyde.util import getLoggerWithNullHandler, first_match, discover_executable +from hyde.util import first_match, discover_executable from hyde.model import Expando +import abc from functools import partial import fnmatch - import os import re import subprocess import traceback +from commando.util import getLoggerWithNullHandler, load_python_object +from fswrap import File + logger = getLoggerWithNullHandler('hyde.engine') class PluginProxy(object): @@ -263,7 +261,7 @@ class Plugin(object): Loads plugins based on the configuration. Assigns the plugins to 'site.plugins' """ - site.plugins = [loader.load_python_object(name)(site) + site.plugins = [load_python_object(name)(site) for name in site.config.plugins] @staticmethod diff --git a/hyde/publisher.py b/hyde/publisher.py index 8635029..10142d5 100644 --- a/hyde/publisher.py +++ b/hyde/publisher.py @@ -1,8 +1,7 @@ import abc from operator import attrgetter -from hyde.util import getLoggerWithNullHandler -from hyde.loader import load_python_object +from commando.util import getLoggerWithNullHandler, load_python_object """ Contains abstract classes and utilities that help publishing a website to a diff --git a/hyde/server.py b/hyde/server.py index 5cda149..ffa56b2 100644 --- a/hyde/server.py +++ b/hyde/server.py @@ -3,8 +3,6 @@ Contains classes and utilities for serving a site generated from hyde. """ -import os -import select import threading import urlparse import urllib @@ -12,12 +10,12 @@ import traceback from datetime import datetime from SimpleHTTPServer import SimpleHTTPRequestHandler from BaseHTTPServer import HTTPServer -from hyde.fs import File, Folder -from hyde.site import Site + from hyde.generator import Generator -from hyde.exceptions import HydeException -from hyde.util import getLoggerWithNullHandler +from fswrap import File, Folder + +from commando.util import getLoggerWithNullHandler logger = getLoggerWithNullHandler('hyde.server') class HydeRequestHandler(SimpleHTTPRequestHandler): @@ -146,44 +144,6 @@ class HydeWebServer(HTTPServer): ext = "." + extension if not extension == 'default' else '' HydeRequestHandler.extensions_map[ext] = type - -####### Code from python 2.7.1: Socket server -####### Duplicated to make sure shutdown works in Python v > 2.6 -####### - - def serve_forever(self, poll_interval=0.5): - """Handle one request at a time until shutdown. - - Polls for shutdown every poll_interval seconds. Ignores - self.timeout. If you need to do periodic tasks, do them in - another thread. - """ - self.__is_shut_down.clear() - try: - while not self.__shutdown_request: - # XXX: Consider using another file descriptor or - # connecting to the socket to wake this up instead of - # polling. Polling reduces our responsiveness to a - # shutdown request and wastes cpu at all other times. - r, w, e = select.select([self], [], [], poll_interval) - if self in r: - self._handle_request_noblock() - finally: - self.__shutdown_request = False - self.__is_shut_down.set() - - def shutdown(self): - """Stops the serve_forever loop. - - Blocks until the loop has finished. This must be called while - serve_forever() is running in another thread, or it will - deadlock. - """ - self.__shutdown_request = True - self.__is_shut_down.wait() - -############## Duplication End. - def regenerate(self): """ Regenerates the entire site. diff --git a/hyde/site.py b/hyde/site.py index 4531940..9b3d1ed 100644 --- a/hyde/site.py +++ b/hyde/site.py @@ -10,10 +10,10 @@ from functools import wraps from urllib import quote from hyde.exceptions import HydeException -from hyde.fs import FS, File, Folder from hyde.model import Config -from hyde.util import getLoggerWithNullHandler +from commando.util import getLoggerWithNullHandler +from fswrap import FS, File, Folder def path_normalized(f): @wraps(f) @@ -51,7 +51,7 @@ class Processable(object): Gets the source path of this node. """ return self.source.path - + def get_relative_deploy_path(self): """ Gets the path where the file will be created @@ -109,7 +109,7 @@ class Resource(Processable): Gets the path relative to the root folder (Content) """ return self.source_file.get_relative_path(self.node.root.source_folder) - + @property def slug(self): #TODO: Add a more sophisticated slugify method diff --git a/hyde/template.py b/hyde/template.py index 59ed271..85841b9 100644 --- a/hyde/template.py +++ b/hyde/template.py @@ -4,10 +4,12 @@ Abstract classes and utilities for template engines """ from hyde.exceptions import HydeException -from hyde.util import getLoggerWithNullHandler import abc +from commando.util import getLoggerWithNullHandler + + class HtmlWrap(object): """ A wrapper class for raw html. diff --git a/hyde/tests/ext/test_auto_extend.py b/hyde/tests/ext/test_auto_extend.py index 63a8f4a..431bf43 100644 --- a/hyde/tests/ext/test_auto_extend.py +++ b/hyde/tests/ext/test_auto_extend.py @@ -4,13 +4,13 @@ Use nose `$ pip install nose` `$ nosetests` """ -from hyde.fs import File, Folder from hyde.generator import Generator from hyde.site import Site -from pyquery import PyQuery +from fswrap import File from nose.tools import nottest +from pyquery import PyQuery TEST_SITE = File(__file__).parent.parent.child_folder('_test') diff --git a/hyde/tests/ext/test_blockdown.py b/hyde/tests/ext/test_blockdown.py index c3ecba8..7957bce 100644 --- a/hyde/tests/ext/test_blockdown.py +++ b/hyde/tests/ext/test_blockdown.py @@ -4,10 +4,10 @@ Use nose `$ pip install nose` `$ nosetests` """ -from hyde.fs import File, Folder from hyde.generator import Generator from hyde.site import Site +from fswrap import File from pyquery import PyQuery TEST_SITE = File(__file__).parent.parent.child_folder('_test') diff --git a/hyde/tests/ext/test_combine.py b/hyde/tests/ext/test_combine.py index e8003d4..2c97798 100644 --- a/hyde/tests/ext/test_combine.py +++ b/hyde/tests/ext/test_combine.py @@ -4,11 +4,11 @@ Use nose `$ pip install nose` `$ nosetests` """ -from hyde.fs import File, Folder -from hyde.model import Expando from hyde.generator import Generator from hyde.site import Site +from fswrap import File, Folder + COMBINE_SOURCE = File(__file__).parent.child_folder('combine') TEST_SITE = File(__file__).parent.parent.child_folder('_test') diff --git a/hyde/tests/ext/test_depends.py b/hyde/tests/ext/test_depends.py index b7219a4..7258648 100644 --- a/hyde/tests/ext/test_depends.py +++ b/hyde/tests/ext/test_depends.py @@ -4,13 +4,10 @@ Use nose `$ pip install nose` `$ nosetests` """ -from hyde.fs import File, Folder from hyde.generator import Generator from hyde.site import Site -from pyquery import PyQuery - -from nose.tools import nottest +from fswrap import File TEST_SITE = File(__file__).parent.parent.child_folder('_test') diff --git a/hyde/tests/ext/test_flattener.py b/hyde/tests/ext/test_flattener.py index e2af835..47b7461 100644 --- a/hyde/tests/ext/test_flattener.py +++ b/hyde/tests/ext/test_flattener.py @@ -4,11 +4,12 @@ Use nose `$ pip install nose` `$ nosetests` """ -from hyde.fs import File, Folder + from hyde.generator import Generator from hyde.site import Site -from hyde.model import Expando, Config +from hyde.model import Config +from fswrap import File TEST_SITE = File(__file__).parent.parent.child_folder('_test') @@ -60,7 +61,7 @@ class TestFlattner(object): gen = Generator(s) gen.generate_all() blog_node = s.content.node_from_relative_path('blog') - + assert blog_node assert blog_node.url == '/' diff --git a/hyde/tests/ext/test_grouper.py b/hyde/tests/ext/test_grouper.py index 5aeba0a..992c501 100644 --- a/hyde/tests/ext/test_grouper.py +++ b/hyde/tests/ext/test_grouper.py @@ -7,11 +7,11 @@ Use nose from hyde.ext.plugins.meta import MetaPlugin from hyde.ext.plugins.sorter import SorterPlugin from hyde.ext.plugins.grouper import GrouperPlugin -from hyde.fs import File, Folder from hyde.generator import Generator from hyde.site import Site from hyde.model import Config, Expando +from fswrap import File from hyde.tests.util import assert_html_equals import yaml diff --git a/hyde/tests/ext/test_images.py b/hyde/tests/ext/test_images.py index 5724f23..b735bbd 100644 --- a/hyde/tests/ext/test_images.py +++ b/hyde/tests/ext/test_images.py @@ -6,11 +6,11 @@ Use nose Requires PIL """ -from hyde.fs import File, Folder + from hyde.generator import Generator from hyde.site import Site -from pyquery import PyQuery +from fswrap import File TEST_SITE = File(__file__).parent.parent.child_folder('_test') IMAGE_SOURCE = File(__file__).parent.child_folder('optipng') @@ -87,8 +87,7 @@ class TestImageSizer(object): def test_size_image_multiline(self): text = u""" - + """ % IMAGE_NAME html = self._generic_test_image(text) assert ' width="%d"' % IMAGE_SIZE[0] in html diff --git a/hyde/tests/ext/test_less.py b/hyde/tests/ext/test_less.py index fc45b5a..ad555ba 100644 --- a/hyde/tests/ext/test_less.py +++ b/hyde/tests/ext/test_less.py @@ -4,10 +4,11 @@ Use nose `$ pip install nose` `$ nosetests` """ -from hyde.fs import File, Folder from hyde.generator import Generator from hyde.site import Site +from fswrap import File, Folder + LESS_SOURCE = File(__file__).parent.child_folder('less') TEST_SITE = File(__file__).parent.parent.child_folder('_test') diff --git a/hyde/tests/ext/test_markings.py b/hyde/tests/ext/test_markings.py index ba725f2..b9be045 100644 --- a/hyde/tests/ext/test_markings.py +++ b/hyde/tests/ext/test_markings.py @@ -4,10 +4,10 @@ Use nose `$ pip install nose` `$ nosetests` """ -from hyde.fs import File, Folder from hyde.generator import Generator from hyde.site import Site +from fswrap import File from pyquery import PyQuery TEST_SITE = File(__file__).parent.parent.child_folder('_test') diff --git a/hyde/tests/ext/test_meta.py b/hyde/tests/ext/test_meta.py index 16b98ff..29d0705 100644 --- a/hyde/tests/ext/test_meta.py +++ b/hyde/tests/ext/test_meta.py @@ -4,10 +4,10 @@ Use nose `$ pip install nose` `$ nosetests` """ -from hyde.fs import File, Folder from hyde.generator import Generator from hyde.site import Site +from fswrap import File, Folder from pyquery import PyQuery import yaml diff --git a/hyde/tests/ext/test_optipng.py b/hyde/tests/ext/test_optipng.py index 8cb54eb..dea9d73 100644 --- a/hyde/tests/ext/test_optipng.py +++ b/hyde/tests/ext/test_optipng.py @@ -4,11 +4,12 @@ Use nose `$ pip install nose` `$ nosetests` """ -from hyde.fs import File, Folder from hyde.model import Expando from hyde.generator import Generator from hyde.site import Site +from fswrap import File, Folder + OPTIPNG_SOURCE = File(__file__).parent.child_folder('optipng') TEST_SITE = File(__file__).parent.parent.child_folder('_test') diff --git a/hyde/tests/ext/test_paginator.py b/hyde/tests/ext/test_paginator.py index d66caff..e76f0e1 100644 --- a/hyde/tests/ext/test_paginator.py +++ b/hyde/tests/ext/test_paginator.py @@ -6,11 +6,11 @@ Use nose """ from textwrap import dedent -from hyde.fs import File, Folder from hyde.generator import Generator -from hyde.model import Expando from hyde.site import Site +from fswrap import File + TEST_SITE = File(__file__).parent.parent.child_folder('_test') class TestPaginator(object): diff --git a/hyde/tests/ext/test_sorter.py b/hyde/tests/ext/test_sorter.py index 9b48b27..1bfea7e 100644 --- a/hyde/tests/ext/test_sorter.py +++ b/hyde/tests/ext/test_sorter.py @@ -6,13 +6,13 @@ Use nose """ from hyde.ext.plugins.meta import MetaPlugin from hyde.ext.plugins.sorter import SorterPlugin -from hyde.fs import File, Folder from hyde.generator import Generator from hyde.site import Site from hyde.model import Config, Expando + +from fswrap import File, Folder import yaml -from operator import attrgetter TEST_SITE = File(__file__).parent.parent.child_folder('_test') diff --git a/hyde/tests/ext/test_stylus.py b/hyde/tests/ext/test_stylus.py index 9d32df3..d9ddaad 100644 --- a/hyde/tests/ext/test_stylus.py +++ b/hyde/tests/ext/test_stylus.py @@ -4,15 +4,15 @@ Use nose `$ pip install nose` `$ nosetests` """ -from hyde.fs import File, Folder from hyde.model import Expando from hyde.generator import Generator from hyde.site import Site +from fswrap import File, Folder + STYLUS_SOURCE = File(__file__).parent.child_folder('stylus') TEST_SITE = File(__file__).parent.parent.child_folder('_test') - class TestStylus(object): def setUp(self): diff --git a/hyde/tests/ext/test_syntext.py b/hyde/tests/ext/test_syntext.py index 5e8eae0..23a0d24 100644 --- a/hyde/tests/ext/test_syntext.py +++ b/hyde/tests/ext/test_syntext.py @@ -4,10 +4,10 @@ Use nose `$ pip install nose` `$ nosetests` """ -from hyde.fs import File, Folder from hyde.generator import Generator from hyde.site import Site +from fswrap import File from pyquery import PyQuery TEST_SITE = File(__file__).parent.parent.child_folder('_test') diff --git a/hyde/tests/ext/test_tagger.py b/hyde/tests/ext/test_tagger.py index bbb5d3e..e23f70b 100644 --- a/hyde/tests/ext/test_tagger.py +++ b/hyde/tests/ext/test_tagger.py @@ -4,11 +4,10 @@ Use nose `$ pip install nose` `$ nosetests` """ -from hyde.fs import File from hyde.generator import Generator from hyde.site import Site - +from fswrap import File TEST_SITE = File(__file__).parent.parent.child_folder('_test') @@ -152,7 +151,7 @@ class TestTagger(object): assert tag assert not hasattr(tag, "emotions") - def test_tagger_metadata(self): + def test_tagger_sorted(self): conf = { "tagger":{ "sorter": "time", diff --git a/hyde/tests/ext/test_textlinks.py b/hyde/tests/ext/test_textlinks.py index fd214c2..4cf16d2 100644 --- a/hyde/tests/ext/test_textlinks.py +++ b/hyde/tests/ext/test_textlinks.py @@ -4,12 +4,11 @@ Use nose `$ pip install nose` `$ nosetests` """ -from hyde.fs import File, Folder from hyde.generator import Generator from hyde.site import Site from urllib import quote -from pyquery import PyQuery +from fswrap import File TEST_SITE = File(__file__).parent.parent.child_folder('_test') diff --git a/hyde/tests/ext/test_uglify.py b/hyde/tests/ext/test_uglify.py index 7ee91ef..65dcb6b 100644 --- a/hyde/tests/ext/test_uglify.py +++ b/hyde/tests/ext/test_uglify.py @@ -4,11 +4,12 @@ Use nose `$ pip install nose` `$ nosetests` """ -from hyde.fs import File, Folder from hyde.model import Expando from hyde.generator import Generator from hyde.site import Site +from fswrap import File, Folder + UGLIFY_SOURCE = File(__file__).parent.child_folder('uglify') TEST_SITE = File(__file__).parent.parent.child_folder('_test') diff --git a/hyde/tests/ext/test_urlcleaner.py b/hyde/tests/ext/test_urlcleaner.py index 2db7686..aeb9069 100644 --- a/hyde/tests/ext/test_urlcleaner.py +++ b/hyde/tests/ext/test_urlcleaner.py @@ -4,14 +4,13 @@ Use nose `$ pip install nose` `$ nosetests` """ -from hyde.fs import File, Folder from hyde.generator import Generator +from hyde.model import Config from hyde.site import Site +from fswrap import File, Folder import yaml -from hyde.model import Config - TEST_SITE = File(__file__).parent.parent.child_folder('_test') diff --git a/hyde/tests/test_fs.py b/hyde/tests/test_fs.py deleted file mode 100644 index 5bb91e9..0000000 --- a/hyde/tests/test_fs.py +++ /dev/null @@ -1,457 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Use nose -`$ pip install nose` -`$ nosetests` -""" - -from hyde.fs import FS, File, Folder -import codecs -import os -import shutil - -from nose.tools import raises, with_setup, nottest - -def test_representation(): - f = FS(__file__) - assert f.path == __file__ - assert unicode(f) == __file__ - assert repr(f) == __file__ - -def test_name(): - f = FS(__file__) - assert f.name == os.path.basename(__file__) - -def test_equals(): - f = FS('/blog/2010/december') - g = FS('/blog/2010/december') - h = FS('/blog/2010/december/') - i = FS('/blog/2010/november') - assert f == f.path - assert f == g - assert f == h - assert f != i - -def test_name_without_extension(): - f = File(__file__) - assert f.name_without_extension == "test_fs" - -def test_extension(): - f = File(__file__) - assert f.extension == os.path.splitext(__file__)[1] - f = File("abc") - assert f.extension == '' - -def test_kind(): - f = File(__file__) - assert f.kind == os.path.splitext(__file__)[1].lstrip('.') - f = File("abc") - assert f.kind == '' - -def test_can_create_temp_file(): - text = "A for apple" - f = File.make_temp(text) - assert f.exists - assert text == f.read_all() - f.delete() - assert not f.exists - -def test_time_functions(): - f1 = File(__file__) - t1 = f1.last_modified - f2 = File.make_temp("I am new") - t2 = f2.last_modified - assert t1 < t2 - assert f2.has_changed_since(t1) - assert f1.older_than(f2) - - -def test_path_expands_user(): - f = File("~/abc/def") - assert f.path == os.path.expanduser("~/abc/def") - -def test_fully_expanded_path(): - f = File(__file__).parent - n = f.child_folder('../' + f.name) - e = Folder(n.fully_expanded_path) - assert n != e - assert f == e - -def test_parent(): - f = File(__file__) - p = f.parent - assert hasattr(p, 'child_folder') - assert unicode(p) == os.path.dirname(__file__) - -def test_child(): - p = File(__file__).parent - c = p.child('data.dat') - assert c == os.path.join(os.path.dirname(__file__), 'data.dat') - -def test_child_folder(): - p = File(__file__).parent - c = p.child_folder('data') - assert hasattr(c, 'child_folder') - assert unicode(c) == os.path.join(os.path.dirname(__file__), 'data') - -def test_exists(): - p = FS(__file__) - assert p.exists - p = FS(__file__ + "_some_junk") - assert not p.exists - f = FS(__file__).parent.parent - assert f.exists - f = FS(__file__).parent.child_folder('templates') - assert f.exists - -def test_create_folder(): - f = FS(__file__).parent - assert f.exists - f.make() - assert True # No Exceptions - c = f.child_folder('__test__') - assert not c.exists - c.make() - assert c.exists - shutil.rmtree(unicode(c)) - assert not c.exists - -def test_remove_folder(): - f = FS(__file__).parent - c = f.child_folder('__test__') - assert not c.exists - c.make() - assert c.exists - c.delete() - assert not c.exists - -def test_can_remove_file(): - f = FS(__file__).parent - c = f.child_folder('__test__') - c.make() - assert c.exists - txt = "abc" - abc = File(c.child('abc.txt')) - abc.write(txt) - assert abc.exists - abc.delete() - assert not abc.exists - abc.delete() - assert True # No Exception - c.delete() - -def test_file_or_folder(): - f = FS.file_or_folder(__file__) - assert isinstance(f, File) - f = FS.file_or_folder(File(__file__).parent) - assert isinstance(f, Folder) - -DATA_ROOT = File(__file__).parent.child_folder('data') -TEMPLATE_ROOT = File(__file__).parent.child_folder('templates') -JINJA2 = TEMPLATE_ROOT.child_folder('jinja2') -HELPERS = File(JINJA2.child('helpers.html')) -INDEX = File(JINJA2.child('index.html')) -LAYOUT = File(JINJA2.child('layout.html')) -LOGO = File(TEMPLATE_ROOT.child('../../../resources/hyde-logo.png')) -XML = File(TEMPLATE_ROOT.child('../sites/test_jinja/content/crossdomain.xml')) - -def test_ancestors(): - depth = 0 - next = JINJA2 - for folder in INDEX.ancestors(): - assert folder == next - depth += 1 - next = folder.parent - assert depth == len(JINJA2.path.split(os.sep)) - -def test_ancestors_stop(): - depth = 0 - next = JINJA2 - for folder in INDEX.ancestors(stop=TEMPLATE_ROOT.parent): - assert folder == next - depth += 1 - next = folder.parent - assert depth == 2 - -def test_is_descendant_of(): - assert INDEX.is_descendant_of(JINJA2) - assert JINJA2.is_descendant_of(TEMPLATE_ROOT) - assert INDEX.is_descendant_of(TEMPLATE_ROOT) - assert not INDEX.is_descendant_of(DATA_ROOT) - -def test_get_relative_path(): - assert INDEX.get_relative_path(TEMPLATE_ROOT) == Folder(JINJA2.name).child(INDEX.name) - assert INDEX.get_relative_path(TEMPLATE_ROOT.parent) == Folder( - TEMPLATE_ROOT.name).child_folder(JINJA2.name).child(INDEX.name) - assert JINJA2.get_relative_path(JINJA2) == "" - -def test_get_mirror(): - mirror = JINJA2.get_mirror(DATA_ROOT, source_root=TEMPLATE_ROOT) - assert mirror == DATA_ROOT.child_folder(JINJA2.name) - mirror = JINJA2.get_mirror(DATA_ROOT, source_root=TEMPLATE_ROOT.parent) - assert mirror == DATA_ROOT.child_folder(TEMPLATE_ROOT.name).child_folder(JINJA2.name) - -def test_mimetype(): - assert HELPERS.mimetype == 'text/html' - assert LOGO.mimetype == 'image/png' - -def test_is_text(): - assert HELPERS.is_text - assert not LOGO.is_text - assert XML.is_text - -def test_is_image(): - assert not HELPERS.is_image - assert LOGO.is_image - -def test_file_size(): - assert LOGO.size == 1942 - -@nottest -def setup_data(): - DATA_ROOT.make() - -@nottest -def cleanup_data(): - DATA_ROOT.delete() - -@with_setup(setup_data, cleanup_data) -def test_copy_file(): - DATA_HELPERS = File(DATA_ROOT.child(HELPERS.name)) - assert not DATA_HELPERS.exists - HELPERS.copy_to(DATA_ROOT) - assert DATA_HELPERS.exists - -@with_setup(setup_data, cleanup_data) -def test_copy_folder(): - assert DATA_ROOT.exists - DATA_JINJA2 = DATA_ROOT.child_folder(JINJA2.name) - assert not DATA_JINJA2.exists - JINJA2.copy_to(DATA_ROOT) - assert DATA_JINJA2.exists - for f in [HELPERS, INDEX, LAYOUT]: - assert File(DATA_JINJA2.child(f.name)).exists - -@with_setup(setup_data, cleanup_data) -def test_copy_folder_target_missing(): - DATA_ROOT.delete() - assert not DATA_ROOT.exists - DATA_JINJA2 = DATA_ROOT.child_folder(JINJA2.name) - assert not DATA_JINJA2.exists - JINJA2.copy_to(DATA_ROOT) - assert DATA_JINJA2.exists - for f in [HELPERS, INDEX, LAYOUT]: - assert File(DATA_JINJA2.child(f.name)).exists - -@with_setup(setup_data, cleanup_data) -def test_copy_folder_contents(): - for f in [HELPERS, INDEX, LAYOUT]: - assert not File(DATA_ROOT.child(f.name)).exists - JINJA2.copy_contents_to(DATA_ROOT) - for f in [HELPERS, INDEX, LAYOUT]: - assert File(DATA_ROOT.child(f.name)).exists - -@with_setup(setup_data, cleanup_data) -def test_move_folder(): - DATA_JUNK = DATA_ROOT.child_folder('junk') - assert not DATA_JUNK.exists - JINJA2.copy_contents_to(DATA_JUNK) - assert DATA_JUNK.exists - for f in [HELPERS, INDEX, LAYOUT]: - assert File(DATA_JUNK.child(f.name)).exists - DATA_JUNK2 = DATA_ROOT.child_folder('second_junk') - assert not DATA_JUNK2.exists - DATA_JUNK.move_to(DATA_JUNK2) - assert not DATA_JUNK.exists - assert DATA_JUNK2.exists - for f in [HELPERS, INDEX, LAYOUT]: - assert File(DATA_JUNK2.child_folder( - DATA_JUNK.name).child( - f.name)).exists - -@with_setup(setup_data, cleanup_data) -def test_rename_folder(): - DATA_JUNK = DATA_ROOT.child_folder('junk') - assert not DATA_JUNK.exists - JINJA2.copy_contents_to(DATA_JUNK) - for f in [HELPERS, INDEX, LAYOUT]: - assert File(DATA_JUNK.child(f.name)).exists - DATA_JUNK2 = DATA_ROOT.child_folder('junk2') - assert DATA_JUNK.exists - assert not DATA_JUNK2.exists - DATA_JUNK.rename_to('junk2') - assert not DATA_JUNK.exists - assert DATA_JUNK2.exists - for f in [HELPERS, INDEX, LAYOUT]: - assert File(DATA_JUNK2.child(f.name)).exists - -@with_setup(setup_data, cleanup_data) -def test_read_all(): - utxt = u'åßcdeƒ' - path = DATA_ROOT.child('unicode.txt') - with codecs.open(path, 'w', 'utf-8') as f: - f.write(utxt) - - txt = File(path).read_all() - assert txt == utxt - -@with_setup(setup_data, cleanup_data) -def test_write(): - utxt = u'åßcdeƒ' - path = DATA_ROOT.child('unicode.txt') - File(path).write(utxt) - txt = File(path).read_all() - assert txt == utxt - -def test_walker(): - folders = [] - files = [] - complete = [] - - with TEMPLATE_ROOT.walker as walker: - - @walker.folder_visitor - def visit_folder(f): - folders.append(f) - - @walker.file_visitor - def visit_file(f): - files.append(f) - - @walker.finalizer - def visit_complete(): - assert folders[0] == TEMPLATE_ROOT - assert folders[1] == JINJA2 - assert INDEX in files - assert HELPERS in files - assert LAYOUT in files - complete.append(True) - - assert len(files) == 4 - assert len(folders) == 2 - assert len(complete) == 1 - -def test_walker_walk_all(): - items = list(TEMPLATE_ROOT.walker.walk_all()) - assert len(items) == 6 - assert TEMPLATE_ROOT in items - assert JINJA2 in items - assert INDEX in items - assert HELPERS in items - assert LAYOUT in items - -def test_walker_walk_files(): - items = list(TEMPLATE_ROOT.walker.walk_files()) - assert len(items) == 4 - assert INDEX in items - assert HELPERS in items - assert LAYOUT in items - -def test_walker_walk_folders(): - items = list(TEMPLATE_ROOT.walker.walk_folders()) - assert len(items) == 2 - assert TEMPLATE_ROOT in items - assert JINJA2 in items - -def test_walker_templates_just_root(): - folders = [] - files = [] - complete = [] - - with TEMPLATE_ROOT.walker as walker: - - @walker.folder_visitor - def visit_folder(f): - assert f == TEMPLATE_ROOT - folders.append(f) - return False - - @walker.file_visitor - def visit_file(f): - files.append(f) - - @walker.finalizer - def visit_complete(): - complete.append(True) - - assert len(files) == 0 - assert len(folders) == 1 - assert len(complete) == 1 - -def test_lister_templates(): - folders = [] - files = [] - complete = [] - - with TEMPLATE_ROOT.lister as lister: - - @lister.folder_visitor - def visit_folder(f): - assert f == JINJA2 - folders.append(f) - - @lister.file_visitor - def visit_file(f): - files.append(f) - - @lister.finalizer - def visit_complete(): - complete.append(True) - - assert len(files) == 0 - assert len(folders) == 1 - assert len(complete) == 1 - - -def test_lister_list_all(): - items = list(TEMPLATE_ROOT.lister.list_all()) - assert len(items) == 1 - assert JINJA2 in items - items = list(JINJA2.lister.list_all()) - assert len(items) == 4 - assert INDEX in items - assert HELPERS in items - assert LAYOUT in items - - -def test_lister_list_files(): - items = list(TEMPLATE_ROOT.lister.list_files()) - assert len(items) == 0 - items = list(JINJA2.lister.list_files()) - assert len(items) == 4 - assert INDEX in items - assert HELPERS in items - assert LAYOUT in items - -def test_lister_list_folders(): - items = list(TEMPLATE_ROOT.lister.list_folders()) - assert len(items) == 1 - assert JINJA2 in items - items = list(JINJA2.lister.list_folders()) - assert len(items) == 0 - -def test_lister_jinja2(): - folders = [] - files = [] - complete = [] - - with JINJA2.lister as lister: - - @lister.folder_visitor - def visit_folder(f): - folders.append(f) - - @lister.file_visitor - def visit_file(f): - files.append(f) - - @lister.finalizer - def visit_complete(): - assert INDEX in files - assert HELPERS in files - assert LAYOUT in files - complete.append(True) - - assert len(files) == 4 - assert len(folders) == 0 - assert len(complete) == 1 \ No newline at end of file diff --git a/hyde/tests/test_generate.py b/hyde/tests/test_generate.py index 1f3bbad..d2e43c9 100644 --- a/hyde/tests/test_generate.py +++ b/hyde/tests/test_generate.py @@ -6,13 +6,13 @@ Use nose """ from hyde.generator import Generator -from hyde.fs import FS, File, Folder from hyde.model import Config from hyde.site import Site -from nose.tools import raises, with_setup, nottest from pyquery import PyQuery +from fswrap import File, Folder + TEST_SITE = File(__file__).parent.child_folder('_test') class TestGenerator(object): diff --git a/hyde/tests/test_initialize.py b/hyde/tests/test_initialize.py index 728f443..0345dba 100644 --- a/hyde/tests/test_initialize.py +++ b/hyde/tests/test_initialize.py @@ -8,8 +8,9 @@ Use nose from hyde.engine import Engine from hyde.exceptions import HydeException -from hyde.fs import File, Folder from hyde.layout import Layout + +from fswrap import File, Folder from nose.tools import raises, with_setup, nottest TEST_SITE = File(__file__).parent.child_folder('_test') diff --git a/hyde/tests/test_jinja2template.py b/hyde/tests/test_jinja2template.py index 6308361..9fcd2d0 100644 --- a/hyde/tests/test_jinja2template.py +++ b/hyde/tests/test_jinja2template.py @@ -7,18 +7,19 @@ Use nose Some code borrowed from rwbench.py from the jinja2 examples """ from datetime import datetime +from random import choice, randrange + from hyde.ext.templates.jinja import Jinja2Template -from hyde.fs import File from hyde.site import Site from hyde.generator import Generator from hyde.model import Config +from fswrap import File from jinja2.utils import generate_lorem_ipsum -from random import choice, randrange -import yaml - -from pyquery import PyQuery from nose.tools import nottest +from pyquery import PyQuery + +import yaml ROOT = File(__file__).parent JINJA2 = ROOT.child_folder('templates/jinja2') @@ -623,7 +624,7 @@ Hyde & Jinja. assert "reference" not in html - def test_yaml_tag(salf): + def test_yaml_tag(self): text = """ {% yaml test %} diff --git a/hyde/tests/test_layout.py b/hyde/tests/test_layout.py index bc3d446..1899ab9 100644 --- a/hyde/tests/test_layout.py +++ b/hyde/tests/test_layout.py @@ -4,11 +4,12 @@ Use nose `$ pip install nose` `$ nosetests` """ +import os -from hyde.fs import File, Folder from hyde.layout import Layout, HYDE_DATA, LAYOUTS -from nose.tools import raises, with_setup, nottest -import os + +from fswrap import File +from nose.tools import nottest, with_setup DATA_ROOT = File(__file__).parent.child_folder('data') LAYOUT_ROOT = DATA_ROOT.child_folder(LAYOUTS) diff --git a/hyde/tests/test_loader.py b/hyde/tests/test_loader.py deleted file mode 100644 index d3f757e..0000000 --- a/hyde/tests/test_loader.py +++ /dev/null @@ -1,81 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Use nose -`$ pip install nose` -`$ nosetests` -""" - -from hyde.loader import load_python_object -from nose.tools import raises -import os - -from hyde.exceptions import HydeException -from hyde.fs import File, Folder -from hyde.generator import Generator -from hyde.site import Site - - - -def test_can_load_locals(): - - file_class = load_python_object('hyde.fs.File') - assert file_class - - f = file_class(__file__) - assert f - - assert f.name == os.path.basename(__file__) - - -def test_can_load_from_python_path(): - - markdown = load_python_object('markdown.markdown') - assert markdown - - assert "