| 1 | from django.conf import settings |
|---|
| 2 | import re |
|---|
| 3 | import os |
|---|
| 4 | import telemeta |
|---|
| 5 | import mimetypes |
|---|
| 6 | |
|---|
| 7 | PAGES_ROOT = os.path.join(os.path.dirname(telemeta.__file__), 'pages') |
|---|
| 8 | |
|---|
| 9 | class PageTextContent(object): |
|---|
| 10 | def __init__(self, filename, path): |
|---|
| 11 | self.filename = filename |
|---|
| 12 | self.path = path |
|---|
| 13 | |
|---|
| 14 | def __iter__(self): |
|---|
| 15 | file = open(self.filename, 'r') |
|---|
| 16 | for line in file: |
|---|
| 17 | yield line.rstrip('\r\n') |
|---|
| 18 | file.close() |
|---|
| 19 | |
|---|
| 20 | def __unicode__(self): |
|---|
| 21 | file = open(self.filename, 'r') |
|---|
| 22 | data = file.read() |
|---|
| 23 | file.close() |
|---|
| 24 | return data |
|---|
| 25 | |
|---|
| 26 | class PageAttachment(object): |
|---|
| 27 | def __init__(self, filename, path): |
|---|
| 28 | self.filename = filename |
|---|
| 29 | self.path = path |
|---|
| 30 | |
|---|
| 31 | def mimetype(self): |
|---|
| 32 | type, encoding = mimetypes.guess_type(self.filename) |
|---|
| 33 | return type |
|---|
| 34 | |
|---|
| 35 | def __iter__(self): |
|---|
| 36 | file = open(self.filename, 'rb') |
|---|
| 37 | buffer_size = 0x10000 |
|---|
| 38 | while True: |
|---|
| 39 | chunk = file.read(buffer_size) |
|---|
| 40 | yield chunk |
|---|
| 41 | if len(chunk) < buffer_size: |
|---|
| 42 | break |
|---|
| 43 | |
|---|
| 44 | file.close() |
|---|
| 45 | |
|---|
| 46 | def language_code(request=None): |
|---|
| 47 | code = (request and getattr(request, 'LANGUAGE_CODE', None)) or settings.LANGUAGE_CODE |
|---|
| 48 | cut = re.split('[_-]', code) |
|---|
| 49 | code = cut[0] |
|---|
| 50 | return code.lower() |
|---|
| 51 | |
|---|
| 52 | def project_dir(): |
|---|
| 53 | import settings as settings_mod |
|---|
| 54 | if '__init__.py' in settings_mod.__file__: |
|---|
| 55 | p = os.path.dirname(settings_mod.__file__) |
|---|
| 56 | else: |
|---|
| 57 | p = settings_mod.__file__ |
|---|
| 58 | project_directory, settings_filename = os.path.split(p) |
|---|
| 59 | if project_directory == os.curdir or not project_directory: |
|---|
| 60 | project_directory = os.getcwd() |
|---|
| 61 | |
|---|
| 62 | return project_directory |
|---|
| 63 | |
|---|
| 64 | def resolve_page_file(root, relative_path, ignore_slash_issue=False): |
|---|
| 65 | root = os.path.realpath(root) |
|---|
| 66 | filename = None |
|---|
| 67 | current = root |
|---|
| 68 | is_attachment = False |
|---|
| 69 | for node in relative_path.split('/'): |
|---|
| 70 | if not node: |
|---|
| 71 | continue |
|---|
| 72 | current = os.path.join(current, node) |
|---|
| 73 | rst = current + '.rst' |
|---|
| 74 | if os.path.isfile(rst): |
|---|
| 75 | filename = rst |
|---|
| 76 | break |
|---|
| 77 | elif os.path.isfile(current): |
|---|
| 78 | filename = current |
|---|
| 79 | is_attachment = True |
|---|
| 80 | elif not os.path.isdir(current): |
|---|
| 81 | break |
|---|
| 82 | |
|---|
| 83 | if not filename and os.path.isdir(current): |
|---|
| 84 | rst = os.path.join(current, 'index.rst') |
|---|
| 85 | if os.path.isfile(rst): |
|---|
| 86 | if not ignore_slash_issue and relative_path[-1:] != '/': |
|---|
| 87 | raise MalformedPagePath("The relative page os.path must end with a slash when " |
|---|
| 88 | "resolving an implicit directory index") |
|---|
| 89 | filename = rst |
|---|
| 90 | |
|---|
| 91 | if filename: |
|---|
| 92 | filename = os.path.realpath(filename) |
|---|
| 93 | if filename.index(root) != 0: |
|---|
| 94 | filename = None |
|---|
| 95 | |
|---|
| 96 | if filename: |
|---|
| 97 | if is_attachment: |
|---|
| 98 | return PageAttachment(filename, relative_path) |
|---|
| 99 | else: |
|---|
| 100 | return PageTextContent(filename, relative_path) |
|---|
| 101 | |
|---|
| 102 | return None |
|---|
| 103 | |
|---|
| 104 | def get_page_content(request, relative_path, ignore_slash_issue=False): |
|---|
| 105 | lang = language_code(request) |
|---|
| 106 | userroot = os.path.join(project_dir(), 'telemeta-pages') |
|---|
| 107 | rootlist = [os.path.join(userroot, lang), os.path.join(userroot, 'default'), |
|---|
| 108 | os.path.join(PAGES_ROOT, lang), os.path.join(PAGES_ROOT, 'default')] |
|---|
| 109 | for root in rootlist: |
|---|
| 110 | content = resolve_page_file(root, relative_path, ignore_slash_issue=ignore_slash_issue) |
|---|
| 111 | if content: |
|---|
| 112 | return content |
|---|
| 113 | |
|---|
| 114 | return None |
|---|
| 115 | |
|---|
| 116 | class MalformedPagePath(Exception): |
|---|
| 117 | pass |
|---|
| 118 | |
|---|