-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmodels.py
123 lines (92 loc) · 3.48 KB
/
models.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# -*- coding:utf-8 -*-
"""
@author: wTayyeb https://github.com/wtayyeb
@license: MIT
"""
import json
import logging
import os
from django.conf import settings
from django.contrib.sites.models import Site, SITE_CACHE
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
from .threadlocals import get_thread_variable
logger = logging.getLogger(__name__)
@python_2_unicode_compatible
class Theme(object):
_metadata_filename = 'metadata.json'
def __init__(self, slug, *args, **kwargs):
super(Theme, self).__init__(*args, **kwargs)
self.slug = slug
self._metadata = {}
self.metadata_ready = None
def read_metadata(self):
filename = os.path.join(settings.THEMING_ROOT, self.slug, self._metadata_filename)
try:
with open(filename, 'r') as f:
self._metadata = json.load(f)
self.metadata_ready = True
except IOError:
self._metadata = {}
self.metadata_ready = False
def __getattr__(self, key):
if key not in ('name', 'description', 'author', 'version'):
raise AttributeError
if self.metadata_ready is None:
self.read_metadata()
if self.metadata_ready is False:
logger.debug('theme %s have no metadata or its metadata is not a valid json' % self.slug)
val = self._metadata.get(key)
if val is None and key is 'name':
val = self.slug.title()
return val
def __str__(self, *args, **kwargs):
return '<Theme `%s`>' % self.slug
class ThemeManager(object):
def __init__(self, *args, **kwargs):
super(ThemeManager, self).__init__(*args, **kwargs)
self._themes = None
self.host = None
def find_themes(self, force=False):
if self._themes is None or force:
self._themes = {}
root = settings.THEMING_ROOT
for dirname in os.listdir(root):
if not dirname.startswith('~'):
self._themes[dirname] = Theme(dirname)
return self._themes
def get_themes_choice(self):
themes = self.find_themes()
choices = []
for theme in themes.values():
choices.append((theme.slug, theme.name))
return choices
def get_current_theme(self):
sitetheme = get_thread_variable('sitetheme')
if sitetheme:
theme = sitetheme.theme
else:
theme = self.get_theme(settings.THEMING_DEFAULT_THEME)
return theme
def get_theme(self, theme_slug):
self.find_themes()
return self._themes[theme_slug]
thememanager = ThemeManager()
@python_2_unicode_compatible
class SiteTheme(models.Model):
site = models.OneToOneField(Site)
theme_slug = models.CharField(max_length=100, choices=thememanager.get_themes_choice())
site_title = models.CharField(max_length=255, default='', blank=True)
site_description = models.CharField(max_length=255, default='', blank=True)
@property
def theme(self):
return thememanager.get_theme(self.theme_slug)
def __str__(self):
theme = self.theme
return '%s : [%s] %s' % (self.site, theme.slug, theme.name)
def delete(self, using=None):
SITE_CACHE.pop(self.site.domain, None)
return super(SiteTheme, self).delete(using=using)
def save(self, *args, **kwargs):
SITE_CACHE.pop(self.site.domain, None)
return super(SiteTheme, self).save(*args, **kwargs)