@@ -0,0 +1,22 @@ | |||
The MIT License | |||
Copyright (c) 2009 - 2010 Lakshmi Vyasarajan, Ringce.com | |||
Permission is hereby granted, free of charge, to any person obtaining a copy | |||
of this software and associated documentation files (the "Software"), to deal | |||
in the Software without restriction, including without limitation the rights | |||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||
copies of the Software, and to permit persons to whom the Software is | |||
furnished to do so, subject to the following conditions: | |||
The above copyright notice and this permission notice shall be included in | |||
all copies or substantial portions of the Software. | |||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |||
THE SOFTWARE. | |||
@@ -0,0 +1,107 @@ | |||
{% extends "root.html" %} | |||
{% block all %} | |||
<!doctype html> | |||
<!-- https://github.com/paulirish/html5-boilerplate/blob/master/index.html --> | |||
<!-- paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/ --> | |||
<!--[if lt IE 7 ]> <html lang="en" class="no-js ie6"> <![endif]--> | |||
<!--[if IE 7 ]> <html lang="en" class="no-js ie7"> <![endif]--> | |||
<!--[if IE 8 ]> <html lang="en" class="no-js ie8"> <![endif]--> | |||
<!--[if (gte IE 9)|!(IE)]><!--> <html lang="en" class="no-js"> <!--<![endif]--> | |||
<head> | |||
{% block starthead %}{% endblock starthead %} | |||
<meta charset="{{page.meta.charset|default('utf-8')}}"> | |||
<!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame | |||
Remove this if you use the .htaccess --> | |||
<meta http-equiv="X-UA-Compatible" content="{{page.meta.compatibility|default('IE=edge,chrome=1')"> | |||
<!-- encoding must be specified within the first 512 bytes www.whatwg.org/specs/web-apps/current-work/multipage/semantics.html#charset --> | |||
<!-- meta element for compatibility mode needs to be before all elements except title & meta msdn.microsoft.com/en-us/library/cc288325(VS.85).aspx --> | |||
<!-- Chrome Frame is only invoked if meta element for compatibility mode is within the first 1K bytes code.google.com/p/chromium/issues/detail?id=23003 --> | |||
<title>{% block title %}{{page.meta.title}}{% endblock %}</title> | |||
<meta name="description" content="{{page.meta.description}}"> | |||
<meta name="author" content="{{page.meta.author}}"> | |||
<!-- Mobile viewport optimized: j.mp/bplateviewport --> | |||
<meta name="viewport" content="{{page.meta.viewport|default('width=device-width, initial-scale=1.0')"> | |||
{% block favicons %} | |||
<!-- Place favicon.ico & apple-touch-icon.png in the root of your domain and delete these references --> | |||
<link rel="shortcut icon" href="{% media '/favicon.ico' %}"> | |||
<link rel="apple-touch-icon" href="{% media '/apple-touch-icon.png' %}"> | |||
{% endblock favicons %} | |||
{% block css %} | |||
<!-- CSS : implied media="all" --> | |||
<link rel="stylesheet" href="{% media 'css/site.css' %}"> | |||
<!-- Uncomment if you are specifically targeting less enabled mobile browsers | |||
<link rel="stylesheet" media="handheld" href="css/handheld.css?v=2"> --> | |||
{% endblock css %} | |||
{% block headjs %} | |||
<!-- All JavaScript at the bottom, except for Modernizr which enables HTML5 elements & feature detects --> | |||
<script src="{% media 'js/libs/modernizr-1.6.min.js' %}"></script> | |||
{% endblock headjs %} | |||
{% block endhead %}{% endblock endhead %} | |||
</head> | |||
<body id="{{page.id if page.id else page.base_name}}"> | |||
<div id="container"> | |||
<header> | |||
</header> | |||
<div id="main" role="main"> | |||
</div> | |||
<footer> | |||
</footer> | |||
</div> <!--! end of #container --> | |||
<!-- Javascript at the bottom for fast page loading --> | |||
<!-- Grab Google CDN's jQuery. fall back to local if necessary --> | |||
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.js"></script> | |||
<script>!window.jQuery && document.write(unescape('%3Cscript src="js/libs/jquery-1.4.4.js"%3E%3C/script%3E'))</script> | |||
<!-- scripts concatenated and minified via ant build script--> | |||
<script src="js/plugins.js"></script> | |||
<script src="js/script.js"></script> | |||
<!-- end concatenated and minified scripts--> | |||
<!--[if lt IE 7 ]> | |||
<script> | |||
// More information on tackling transparent PNGs for IE goo.gl/mZiyb | |||
//fix any <img> or .png_bg background-images | |||
$.getScript("js/libs/dd_belatedpng.js",function(){ DD_belatedPNG.fix('img, .png_bg'); }); | |||
</script> | |||
<![endif]--> | |||
<!-- yui profiler and profileviewer - remove for production --> | |||
<script src="js/profiling/yahoo-profiling.min.js"></script> | |||
<script src="js/profiling/config.js"></script> | |||
<!-- end profiling code --> | |||
<!-- asynchronous google analytics: mathiasbynens.be/notes/async-analytics-snippet | |||
change the UA-XXXXX-X to be your site's ID --> | |||
<script> | |||
var _gaq = [['_setAccount', 'UA-XXXXX-X'], ['_trackPageview']]; | |||
(function(d, t) { | |||
var g = d.createElement(t), | |||
s = d.getElementsByTagName(t)[0]; | |||
g.async = true; | |||
g.src = ('https:' == location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; | |||
s.parentNode.insertBefore(g, s); | |||
})(document, 'script'); | |||
</script> | |||
</body> | |||
</html> | |||
{% endblock %} |
@@ -0,0 +1 @@ | |||
{% block all %}{% endblock %} |
@@ -0,0 +1,16 @@ | |||
{% extends "demo.django" %} | |||
{%hyde | |||
title: | |||
description: | |||
teaser: | |||
standalone: generator.htm | |||
%} | |||
{% block introduction %} | |||
{% endblock introduction %} | |||
{% block documentation %} | |||
{% endblock documentation %} |
@@ -0,0 +1,678 @@ | |||
""" | |||
Unified interface for performing file system tasks. Uses os, os.path. shutil | |||
and distutil to perform the tasks. The behavior of some functions is slightly | |||
contaminated with requirements from Hyde: For example, the backup function | |||
deletes the directory that is being backed up. | |||
""" | |||
import os | |||
import shutil | |||
import codecs | |||
import fnmatch | |||
from datetime import datetime | |||
# pylint: disable-msg=E0611 | |||
from distutils import dir_util, file_util | |||
@staticmethod | |||
def filter_hidden_inplace(item_list): | |||
""" | |||
Given a list of filenames, removes filenames for invisible files (whose | |||
names begin with dots) or files whose names end in tildes '~'. | |||
Does not remove files with the filname '.htaccess'. | |||
The list is modified in-place; this function has no return value. | |||
""" | |||
if not item_list: | |||
return | |||
wanted = filter( | |||
lambda item: | |||
not ((item.startswith('.') and item != ".htaccess") | |||
or item.endswith('~')), | |||
item_list) | |||
count = len(item_list) | |||
good_item_count = len(wanted) | |||
if count == good_item_count: | |||
return | |||
item_list[:good_item_count] = wanted | |||
for _ in range(good_item_count, count): | |||
item_list.pop() | |||
@staticmethod | |||
def get_path_fragment(root_dir, a_dir): | |||
""" | |||
Gets the path fragment starting at root_dir to a_dir | |||
""" | |||
current_dir = a_dir | |||
current_fragment = '' | |||
while not current_dir == root_dir: | |||
(current_dir, current_fragment_part) = os.path.split(current_dir) | |||
current_fragment = os.path.join( | |||
current_fragment_part, current_fragment) | |||
return current_fragment | |||
@staticmethod | |||
def get_mirror_dir(directory, source_root, mirror_root, ignore_root = False): | |||
""" | |||
Returns the mirror directory from source_root to mirror_root | |||
""" | |||
current_fragment = get_path_fragment(source_root, directory) | |||
if not current_fragment: | |||
return mirror_root | |||
mirror_directory = mirror_root | |||
if not ignore_root: | |||
mirror_directory = os.path.join( | |||
mirror_root, | |||
os.path.basename(source_root)) | |||
mirror_directory = os.path.join( | |||
mirror_directory, current_fragment) | |||
return mirror_directory | |||
@staticmethod | |||
def mirror_dir_tree(directory, source_root, mirror_root, ignore_root = False): | |||
""" | |||
Create the mirror directory tree | |||
""" | |||
mirror_directory = get_mirror_dir( | |||
directory, source_root, | |||
mirror_root, ignore_root) | |||
try: | |||
os.makedirs(mirror_directory) | |||
except os.error: | |||
pass | |||
return mirror_directory | |||
class FileSystemEntity(object): | |||
""" | |||
Base class for files and folders. | |||
""" | |||
def __init__(self, path): | |||
super(FileSystemEntity, self).__init__() | |||
if path is FileSystemEntity: | |||
self.path = path.path | |||
else: | |||
self.path = path | |||
def __str__(self): | |||
return self.path | |||
def __repr__(self): | |||
return self.path | |||
def allow(self, include=None, exclude=None): | |||
""" | |||
Given a set of wilcard patterns in the include and exclude arguments, | |||
tests if the patterns allow this item for processing. | |||
The exclude parameter is processed first as a broader filter and then | |||
include is used as a narrower filter to override the results for more | |||
specific files. | |||
Example: | |||
exclude = (".*", "*~") | |||
include = (".htaccess") | |||
""" | |||
if not include: | |||
include = () | |||
if not exclude: | |||
exclude = () | |||
if reduce(lambda result, | |||
pattern: result or | |||
fnmatch.fnmatch(self.name, pattern), include, False): | |||
return True | |||
if reduce(lambda result, pattern: | |||
result and not fnmatch.fnmatch(self.name, pattern), | |||
exclude, True): | |||
return True | |||
return False | |||
@property | |||
def humblepath(self): | |||
""" | |||
Expands variables, user, normalizes path and case and coverts | |||
to absolute. | |||
""" | |||
return os.path.abspath( | |||
os.path.normpath( | |||
os.path.normcase( | |||
os.path.expandvars( | |||
os.path.expanduser(self.path))))) | |||
def same_as(self, other): | |||
""" | |||
Checks if the path of this object is same as `other`. `other` must | |||
be a FileSystemEntity. | |||
""" | |||
return (self.humblepath.rstrip(os.sep) == | |||
other.humblepath.rstrip(os.sep)) | |||
@property | |||
def exists(self): | |||
""" | |||
Checks if the entity exists in the file system. | |||
""" | |||
return os.path.exists(self.path) | |||
@property | |||
def isdir(self): | |||
""" | |||
Is this a folder. | |||
""" | |||
return os.path.isdir(self.path) | |||
@property | |||
def stats(self): | |||
""" | |||
Shortcut for os.stat. | |||
""" | |||
return os.stat(self.path) | |||
@property | |||
def name(self): | |||
""" | |||
Name of the entity. Calls os.path.basename. | |||
""" | |||
return os.path.basename(self.path) | |||
@property | |||
def parent(self): | |||
""" | |||
The parent folder. Returns a `Folder` object. | |||
""" | |||
return Folder(os.path.dirname(self.path)) | |||
def __get_destination__(self, destination): | |||
""" | |||
Returns a File or Folder object that would represent this entity | |||
if it were copied or moved to `destination`. `destination` must be | |||
an instance of File or Folder. | |||
""" | |||
if os.path.isdir(str(destination)): | |||
target = destination.child(self.name) | |||
if os.path.isdir(self.path): | |||
return Folder(target) | |||
else: return File(target) | |||
else: | |||
return destination | |||
# pylint: disable-msg=R0904,W0142 | |||
class File(FileSystemEntity): | |||
""" | |||
Encapsulates commonly used functions related to files. | |||
""" | |||
def __init__(self, path): | |||
super(File, self).__init__(path) | |||
@property | |||
def size(self): | |||
""" | |||
Gets the file size | |||
""" | |||
return os.path.getsize(self.path) | |||
#return 1 | |||
def has_extension(self, extension): | |||
""" | |||
Checks if this file has the given extension. | |||
""" | |||
return self.extension == extension | |||
def delete(self): | |||
""" | |||
Deletes if the file exists. | |||
""" | |||
if self.exists: | |||
os.remove(self.path) | |||
@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 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 another_file.last_modified > self.last_modified | |||
@property | |||
def path_without_extension(self): | |||
""" | |||
The full path of the file without its extension. | |||
""" | |||
return os.path.splitext(self.path)[0] | |||
@property | |||
def name_without_extension(self): | |||
""" | |||
Name of the file without its extension. | |||
""" | |||
return os.path.splitext(self.name)[0] | |||
@property | |||
def extension(self): | |||
""" | |||
File's extension prefixed with a dot. | |||
""" | |||
return os.path.splitext(self.path)[1] | |||
@property | |||
def kind(self): | |||
""" | |||
File's extension without a dot prefix. | |||
""" | |||
return self.extension.lstrip(".") | |||
def move_to(self, destination): | |||
""" | |||
Moves the file to the given destination. Returns a File | |||
object that represents the target file. `destination` must | |||
be a File or Folder object. | |||
""" | |||
shutil.move(self.path, str(destination)) | |||
return self.__get_destination__(destination) | |||
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. | |||
""" | |||
shutil.copy(self.path, str(destination)) | |||
return self.__get_destination__(destination) | |||
def write(self, text, encoding="utf-8"): | |||
""" | |||
Writes the given text to the file using the given encoding. | |||
""" | |||
fout = codecs.open(self.path, 'w', encoding) | |||
fout.write(text) | |||
fout.close() | |||
def read_all(self): | |||
""" | |||
Reads from the file and returns the content as a string. | |||
""" | |||
fin = codecs.open(self.path, 'r') | |||
read_text = fin.read() | |||
fin.close() | |||
return read_text | |||
# pylint: disable-msg=R0904,W0142 | |||
class Folder(FileSystemEntity): | |||
""" | |||
Encapsulates commonly used directory functions. | |||
""" | |||
def __init__(self, path): | |||
super(Folder, self).__init__(path) | |||
def __str__(self): | |||
return self.path | |||
def __repr__(self): | |||
return self.path | |||
def delete(self): | |||
""" | |||
Deletes the directory if it exists. | |||
""" | |||
if self.exists: | |||
shutil.rmtree(self.path) | |||
def depth(self): | |||
""" | |||
Returns the number of ancestors of this directory. | |||
""" | |||
return len(self.path.split(os.sep)) | |||
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: | |||
os.makedirs(self.path) | |||
except os.error: | |||
pass | |||
return self | |||
def is_parent_of(self, other_entity): | |||
""" | |||
Returns True if this directory is a direct parent of the the given | |||
directory. | |||
""" | |||
return self.same_as(other_entity.parent) | |||
def is_ancestor_of(self, other_entity): | |||
""" | |||
Returns True if this directory is in the path of the given directory. | |||
Note that this will return True if the given directory is same as this. | |||
""" | |||
folder = other_entity | |||
while not folder.parent.same_as(folder): | |||
folder = folder.parent | |||
if self.same_as(folder): | |||
return True | |||
return False | |||
def child(self, name): | |||
""" | |||
Returns a path of a child item represented by `name`. | |||
""" | |||
return os.path.join(self.path, name) | |||
def child_folder(self, *args): | |||
""" | |||
Returns a Folder object by joining the path component in args | |||
to this directory's path. | |||
""" | |||
return Folder(os.path.join(self.path, *args)) | |||
def child_folder_with_fragment(self, fragment): | |||
""" | |||
Returns a Folder object by joining the fragment to | |||
this directory's path. | |||
""" | |||
return Folder(os.path.join(self.path, fragment.lstrip(os.sep))) | |||
def get_fragment(self, root): | |||
""" | |||
Returns the path fragment of this directory starting with the given | |||
directory. | |||
""" | |||
return get_path_fragment(str(root), self.path) | |||
def get_mirror_folder(self, root, mirror_root, ignore_root=False): | |||
""" | |||
Returns a Folder object that reperesents if the entire fragment of this | |||
directory starting with `root` were copied to `mirror_root`. If ignore_root | |||
is True, the mirror does not include `root` directory itself. | |||
Example: | |||
Current Directory: /usr/local/hyde/stuff | |||
root: /usr/local/hyde | |||
mirror_root: /usr/tmp | |||
Result: | |||
if ignore_root == False: | |||
Folder(/usr/tmp/hyde/stuff) | |||
if ignore_root == True: | |||
Folder(/usr/tmp/stuff) | |||
""" | |||
path = get_mirror_dir(self.path, | |||
str(root), str(mirror_root), ignore_root) | |||
return Folder(path) | |||
def create_mirror_folder(self, root, mirror_root, ignore_root=False): | |||
""" | |||
Creates the mirror directory returned by `get_mirror_folder` | |||
""" | |||
mirror_folder = self.get_mirror_folder( | |||
root, mirror_root, ignore_root) | |||
mirror_folder.make() | |||
return mirror_folder | |||
def backup(self, destination): | |||
""" | |||
Creates a backup of this directory in the given destination. The backup is | |||
suffixed with a number for uniqueness. Deletes this directory after backup | |||
is complete. | |||
""" | |||
new_name = self.name | |||
count = 0 | |||
dest = Folder(destination.child(new_name)) | |||
while(True): | |||
dest = Folder(destination.child(new_name)) | |||
if not dest.exists: | |||
break | |||
else: | |||
count = count + 1 | |||
new_name = self.name + str(count) | |||
dest.make() | |||
dest.move_contents_of(self) | |||
self.delete() | |||
return dest | |||
def move_to(self, destination): | |||
""" | |||
Moves this directory to the given destination. Returns a Folder object | |||
that represents the moved directory. | |||
""" | |||
shutil.copytree(self.path, str(destination)) | |||
shutil.rmtree(self.path) | |||
return self.__get_destination__(destination) | |||
def copy_to(self, destination): | |||
""" | |||
Copies this directory to the given destination. Returns a Folder object | |||
that represents the moved directory. | |||
""" | |||
shutil.copytree(self.path, str(destination)) | |||
return self.__get_destination__(destination) | |||
def move_folder_from(self, source, incremental=False): | |||
""" | |||
Moves the given source directory to this directory. If incremental is True | |||
only newer objects are overwritten. | |||
""" | |||
self.copy_folder_from(source, incremental) | |||
shutil.rmtree(str(source)) | |||
def copy_folder_from(self, source, incremental=False): | |||
""" | |||
Copies the given source directory to this directory. If incremental is True | |||
only newer objects are overwritten. | |||
""" | |||
# 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. | |||
# | |||
# pylint: disable-msg=C0111,W0232 | |||
target_root = self | |||
# pylint: disable-msg=R0903 | |||
class _DirCreator: | |||
@staticmethod | |||
def visit_folder(folder): | |||
target = folder.get_mirror_folder( | |||
source.parent, target_root, ignore_root=True) | |||
target.make() | |||
source.walk(_DirCreator) | |||
dir_util.copy_tree(str(source), | |||
self.child(source.name), | |||
update=incremental) | |||
def move_contents_of(self, source, move_empty_folders=True, | |||
incremental=False): | |||
""" | |||
Moves the contents of the given source directory to this directory. If | |||
incremental is True only newer objects are overwritten. | |||
""" | |||
# pylint: disable-msg=C0111,W0232 | |||
class _Mover: | |||
@staticmethod | |||
def visit_folder(folder): | |||
self.move_folder_from(folder, incremental) | |||
@staticmethod | |||
def visit_file(a_file): | |||
self.move_file_from(a_file, incremental) | |||
source.list(_Mover, move_empty_folders) | |||
def copy_contents_of(self, source, copy_empty_folders=True, | |||
incremental=False): | |||
""" | |||
Copies the contents of the given source directory to this directory. If | |||
incremental is True only newer objects are overwritten. | |||
""" | |||
# pylint: disable-msg=C0111,W0232 | |||
class _Copier: | |||
@staticmethod | |||
def visit_folder(folder): | |||
self.copy_folder_from(folder, incremental) | |||
@staticmethod | |||
def visit_file(a_file): | |||
self.copy_file_from(a_file, incremental) | |||
source.list(_Copier, copy_empty_folders) | |||
def move_file_from(self, source, incremental=False): | |||
""" | |||
Moves the given source file to this directory. If incremental is True the | |||
move is performed only if the source file is newer. | |||
""" | |||
self.copy_file_from(source, incremental) | |||
source.delete() | |||
def copy_file_from(self, source, incremental=False): | |||
""" | |||
Copies the given source file to this directory. If incremental is True the | |||
move is performed only if the source file is newer. | |||
""" | |||
file_util.copy_file(str(source), self.path, update=incremental) | |||
def list(self, visitor, list_empty_folders=True): | |||
""" | |||
Calls the visitor.visit_file or visitor.visit_folder for each file or folder | |||
in this directory. If list_empty_folders is False folders that are empty are | |||
skipped. | |||
""" | |||
a_files = os.listdir(self.path) | |||
for a_file in a_files: | |||
path = os.path.join(self.path, str(a_file)) | |||
if os.path.isdir(path): | |||
if not list_empty_folders: | |||
if Folder(path).empty(): | |||
continue | |||
visitor.visit_folder(Folder(path)) | |||
else: | |||
visitor.visit_file(File(path)) | |||
def empty(self): | |||
""" | |||
Checks if this directory or any of its subdirectories contain files. | |||
""" | |||
paths = os.listdir(self.path) | |||
for path in paths: | |||
if os.path.isdir(path): | |||
if not Folder(path).empty(): | |||
return False | |||
else: | |||
return False | |||
return True | |||
def walk(self, visitor = None, pattern = None): | |||
""" | |||
Walks the entire hirearchy of this directory starting with itself. | |||
Calls visitor.visit_folder first and then calls visitor.visit_file for | |||
any files found. After all files and folders have been exhausted | |||
visitor.visit_complete is called. | |||
If a pattern is provided, only the files that match the pattern are | |||
processed. | |||
If visitor.visit_folder returns False, the files in the folder are not | |||
processed. | |||
""" | |||
def __visit_folder__(visitor, folder): | |||
process_folder = True | |||
if visitor and hasattr(visitor,'visit_folder'): | |||
process_folder = visitor.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__(visitor, a_file): | |||
if visitor and hasattr(visitor,'visit_file'): | |||
visitor.visit_file(a_file) | |||
def __visit_complete__(visitor): | |||
if visitor and hasattr(visitor,'visit_complete'): | |||
visitor.visit_complete() | |||
for root, dirs, a_files in os.walk(self.path): | |||
folder = Folder(root) | |||
if not __visit_folder__(visitor, folder): | |||
dirs[:] = [] | |||
continue | |||
for a_file in a_files: | |||
if not pattern or fnmatch.fnmatch(a_file, pattern): | |||
__visit_file__(visitor, File(folder.child(a_file))) | |||
__visit_complete__(visitor) |
@@ -0,0 +1,28 @@ | |||
""" | |||
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 | |||
import fnmatch | |||
import os | |||
import shutil | |||
from datetime import datetime | |||
# pylint: disable-msg=E0611 | |||
from distutils import dir_util, file_util | |||
class FS(object): | |||
""" | |||
The base file system object | |||
""" | |||
def __init__(self, path): | |||
super(FS, self).__init__() | |||
self.path = str(path) | |||
def __str__(self): | |||
return self.path | |||
def __repr__(self): | |||
return self.path |
@@ -0,0 +1,16 @@ | |||
{% extends "demo.django" %} | |||
{%hyde | |||
title: | |||
description: | |||
teaser: | |||
standalone: layout.htm | |||
%} | |||
{% block introduction %} | |||
{% endblock introduction %} | |||
{% block documentation %} | |||
{% endblock documentation %} |
@@ -0,0 +1,16 @@ | |||
{% extends "demo.django" %} | |||
{%hyde | |||
title: | |||
description: | |||
teaser: | |||
standalone: plugin.htm | |||
%} | |||
{% block introduction %} | |||
{% endblock introduction %} | |||
{% block documentation %} | |||
{% endblock documentation %} |
@@ -0,0 +1,14 @@ | |||
""" | |||
Use nose | |||
`$ pip install nose` | |||
`$ nosetests` | |||
""" | |||
from hyde.fs import FS | |||
def test_representation(): | |||
f = FS(__file__) | |||
assert f.path == __file__ | |||
assert str(f) == __file__ | |||
assert repr(f) == __file__ | |||
@@ -0,0 +1,16 @@ | |||
{% extends "demo.django" %} | |||
{%hyde | |||
title: | |||
description: | |||
teaser: | |||
standalone: theme.htm | |||
%} | |||
{% block introduction %} | |||
{% endblock introduction %} | |||
{% block documentation %} | |||
{% endblock documentation %} |
@@ -0,0 +1,267 @@ | |||
[MASTER] | |||
# Profiled execution. | |||
profile=no | |||
# Add <file or directory> to the black list. It should be a base name, not a | |||
# path. You may set this option multiple times. | |||
#ignore=.svn | |||
# Pickle collected data for later comparisons. | |||
persistent=yes | |||
# Set the cache size for astng objects. | |||
cache-size=500 | |||
# List of plugins (as comma separated values of python modules names) to load, | |||
# usually to register additional checkers. | |||
load-plugins= | |||
[MESSAGES CONTROL] | |||
# Enable only checker(s) with the given id(s). This option conflicts with the | |||
# disable-checker option | |||
#enable-checker= | |||
# Enable all checker(s) except those with the given id(s). This option | |||
# conflicts with the enable-checker option | |||
#disable-checker=design | |||
# Enable all messages in the listed categories. | |||
#enable-msg-cat= | |||
# Disable all messages in the listed categories. | |||
#disable-msg-cat= | |||
# Enable the message(s) with the given id(s). | |||
#enable-msg= | |||
# Disable the message(s) with the given id(s). | |||
# List of all available ids: http://www.logilab.org/card/pylintfeatures | |||
# Disabled messages: | |||
# I0011: Locally disabling %s Used when an inline option disable a message or a messages category. | |||
disable-msg=I0011 | |||
[REPORTS] | |||
# set the output format. Available formats are text, parseable, colorized, msvs | |||
# (visual studio) and html | |||
output-format=text | |||
# Include message's id in output | |||
include-ids=yes | |||
# Put messages in a separate file for each module / package specified on the | |||
# command line instead of printing them on stdout. Reports (if any) will be | |||
# written in a file name "pylint_global.[txt|html]". | |||
files-output=no | |||
# Tells wether to display a full report or only the messages | |||
reports=yes | |||
# Python expression which should return a note less than 10 (10 is the highest | |||
# note).You have access to the variables errors warning, statement which | |||
# respectivly contain the number of errors / warnings messages and the total | |||
# number of statements analyzed. This is used by the global evaluation report | |||
# (R0004). | |||
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) | |||
# Add a comment according to your evaluation note. This is used by the global | |||
# evaluation report (R0004). | |||
comment=no | |||
# Enable the report(s) with the given id(s). | |||
#enable-report= | |||
# Disable the report(s) with the given id(s). | |||
#disable-report= | |||
# checks for : | |||
# * doc strings | |||
# * modules / classes / functions / methods / arguments / variables name | |||
# * number of arguments, local variables, branchs, returns and statements in | |||
# functions, methods | |||
# * required module attributes | |||
# * dangerous default values as arguments | |||
# * redefinition of function / method / class | |||
# * uses of the global statement | |||
# | |||
[BASIC] | |||
# Required attributes for module, separated by a comma | |||
required-attributes= | |||
# Regular expression which should only match functions or classes name which do | |||
# not require a docstring | |||
no-docstring-rgx=__.*__ | |||
# Regular expression which should only match correct module names | |||
module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ | |||
# Regular expression which should only match correct module level names | |||
const-rgx=(([A-Z_][A-Z1-9_]*)|(__.*__)|([a-z_][a-z0-9_]*))$ | |||
# Regular expression which should only match correct class names | |||
class-rgx=[_a-zA-Z0-9]+$ | |||
# Regular expression which should only match correct function names | |||
function-rgx=[a-z_][a-zA-Z0-9_]{2,40}$ | |||
# Regular expression which should only match correct method names | |||
method-rgx=[a-z_][a-zA-Z0-9_]{2,40}$ | |||
# Regular expression which should only match correct instance attribute names | |||
attr-rgx=[a-z_][a-z0-9_]{1,30}$ | |||
#alternative | |||
#attr-rgx=([a-z_][a-z0-9_]{2,30}|([a-z_][a-zA-Z0-9]{2,30}))$ | |||
# Regular expression which should only match correct argument names | |||
argument-rgx=[a-z_][a-z0-9_]{1,30}$ | |||
# Regular expression which should only match correct variable names | |||
variable-rgx=[a-z_][a-zA-Z0-9_]{1,30}$ | |||
# Regular expression which should only match correct list comprehension / | |||
# generator expression variable names | |||
inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ | |||
# Good variable names which should always be accepted, separated by a comma | |||
good-names=i,j,k,ex,Run,_ | |||
# Bad variable names which should always be refused, separated by a comma | |||
bad-names=foo,bar,baz,toto,tutu,tata | |||
# List of builtins function names that should not be used, separated by a comma | |||
bad-functions= | |||
# try to find bugs in the code using type inference | |||
# | |||
[TYPECHECK] | |||
# Tells wether missing members accessed in mixin class should be ignored. A | |||
# mixin class is detected if its name ends with "mixin" (case insensitive). | |||
ignore-mixin-members=yes | |||
# List of classes names for which member attributes should not be checked | |||
# (useful for classes with attributes dynamicaly set). | |||
ignored-classes=SQLObject | |||
# When zope mode is activated, consider the acquired-members option to ignore | |||
# access to some undefined attributes. | |||
zope=no | |||
# List of members which are usually get through zope's acquisition mecanism and | |||
# so shouldn't trigger E0201 when accessed (need zope=yes to be considered). | |||
acquired-members=REQUEST,acl_users,aq_parent | |||
# checks for | |||
# * unused variables / imports | |||
# * undefined variables | |||
# * redefinition of variable from builtins or from an outer scope | |||
# * use of variable before assigment | |||
# | |||
[VARIABLES] | |||
# Tells wether we should check for unused import in __init__ files. | |||
init-import=no | |||
# A regular expression matching names used for dummy variables (i.e. not used). | |||
dummy-variables-rgx=_|dummy | |||
# List of additional names supposed to be defined in builtins. Remember that | |||
# you should avoid to define new builtins when possible. | |||
additional-builtins= | |||
# checks for : | |||
# * methods without self as first argument | |||
# * overridden methods signature | |||
# * access only to existant members via self | |||
# * attributes not defined in the __init__ method | |||
# * supported interfaces implementation | |||
# * unreachable code | |||
# | |||
[CLASSES] | |||
# List of interface methods to ignore, separated by a comma. This is used for | |||
# instance to not check methods defines in Zope's Interface base class. | |||
ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by | |||
# List of method names used to declare (i.e. assign) instance attributes. | |||
defining-attr-methods=__init__,__new__,setUp | |||
# checks for | |||
# * external modules dependencies | |||
# * relative / wildcard imports | |||
# * cyclic imports | |||
# * uses of deprecated modules | |||
# | |||
[IMPORTS] | |||
# Deprecated modules which should not be used, separated by a comma | |||
deprecated-modules=regsub,string,TERMIOS,Bastion,rexec | |||
# Create a graph of every (i.e. internal and external) dependencies in the | |||
# given file (report R0402 must not be disabled) | |||
import-graph= | |||
# Create a graph of external dependencies in the given file (report R0402 must | |||
# not be disabled) | |||
ext-import-graph= | |||
# Create a graph of internal dependencies in the given file (report R0402 must | |||
# not be disabled) | |||
int-import-graph= | |||
# checks for : | |||
# * unauthorized constructions | |||
# * strict indentation | |||
# * line length | |||
# * use of <> instead of != | |||
# | |||
[FORMAT] | |||
# Maximum number of characters on a single line. | |||
max-line-length=120 | |||
# Maximum number of lines in a module | |||
max-module-lines=1000 | |||
# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 | |||
# tab). | |||
#indent-string=' ' | |||
# checks for: | |||
# * warning notes in the code like TODO | |||
# * PEP 263: source code with non ascii character but no encoding declaration | |||
# | |||
[MISCELLANEOUS] | |||
# List of note tags to take in consideration, separated by a comma. | |||
notes=TODO | |||
# checks for similarities and duplicated code. This computation may be | |||
# memory / CPU intensive, so you should disable it if you experiments some | |||
# problems. | |||
# | |||
[SIMILARITIES] | |||
# Minimum lines number of a similarity. | |||
min-similarity-lines=4 | |||
# Ignore comments when computing similarities. | |||
ignore-comments=yes | |||
# Ignore docstrings when computing similarities. | |||
ignore-docstrings=yes |