Revision 511913cb
b/cloudcms/admin.py | ||
---|---|---|
40 | 40 |
raw_id_fields = ('logo', 'favicon') |
41 | 41 |
|
42 | 42 |
|
43 |
class ClientVersionSourceAdminInline(admin.StackedInline): |
|
44 |
model = models.ClientVersionSource |
|
45 |
raw_id_fields = ('logo',) |
|
46 |
extra = 1 |
|
47 |
|
|
48 |
class ClientAdmin(admin.ModelAdmin): |
|
49 |
inlines = [ClientVersionSourceAdminInline] |
|
50 |
|
|
51 |
|
|
43 | 52 |
admin.site.register(models.Application, ApplicationAdmin) |
53 |
admin.site.register(models.Client, ClientAdmin) |
|
44 | 54 |
|
b/cloudcms/clients.py | ||
---|---|---|
1 |
""" |
|
2 |
CMS dynamic application clients module |
|
3 |
|
|
4 |
Helper module to automatically retrieve client download links from different |
|
5 |
sources (e.g. redmine files page). |
|
6 |
""" |
|
7 |
|
|
8 |
import urllib, urllib2, cookielib, urlparse |
|
9 |
|
|
10 |
from datetime import datetime |
|
11 |
from lxml import html |
|
12 |
|
|
13 |
from synnefo import settings |
|
14 |
|
|
15 |
CLIENTS_CACHE_TIMEOUT = getattr(settings, 'CLOUDCMS_CLIENTS_CACHE_TIMEOUT', 120) |
|
16 |
|
|
17 |
class VersionSource(object): |
|
18 |
""" |
|
19 |
Base class for the different version source handlers. |
|
20 |
""" |
|
21 |
def __init__(self, link=None, os="linux", arch="all", regex=".", name=None, |
|
22 |
cache_backend=None, extra_options={}): |
|
23 |
self.os = os |
|
24 |
self.arch = arch |
|
25 |
self.link = link |
|
26 |
self.versions = [] |
|
27 |
extra_options.update({'source_type': self.source_type, 'os': os}) |
|
28 |
self.extra_version_options = extra_options |
|
29 |
|
|
30 |
self.cache_backend = cache_backend |
|
31 |
self.cache_key = self.os + self.arch + self.link |
|
32 |
|
|
33 |
if not name: |
|
34 |
self.name = os |
|
35 |
|
|
36 |
# generic urllib2 opener |
|
37 |
self.opener = urllib2.build_opener( |
|
38 |
urllib2.HTTPRedirectHandler(), |
|
39 |
urllib2.HTTPHandler(debuglevel=0), |
|
40 |
urllib2.HTTPSHandler(debuglevel=0), |
|
41 |
urllib2.HTTPCookieProcessor(cookielib.CookieJar())) |
|
42 |
|
|
43 |
def get_url(self, url): |
|
44 |
""" |
|
45 |
Load url content and return the html etree object. |
|
46 |
""" |
|
47 |
return html.document_fromstring(self.opener.open(url).read()) |
|
48 |
|
|
49 |
def load(self): |
|
50 |
""" |
|
51 |
Fill self.versions attribute with dict objects of the following format |
|
52 |
|
|
53 |
{'date': datetime.datetime(2012, 3, 16, 14, 29), |
|
54 |
'link': 'http://www.domain.com/clientdownload.exe', |
|
55 |
'name': 'Client download', |
|
56 |
'os': 'windows', |
|
57 |
'version': None} |
|
58 |
""" |
|
59 |
raise NotImplemented |
|
60 |
|
|
61 |
def update(self): |
|
62 |
""" |
|
63 |
Load wrapper which handles versions caching if cache_backend is set |
|
64 |
""" |
|
65 |
if self.cache_backend: |
|
66 |
self.versions = self.cache_backend.get(self.cache_key) |
|
67 |
|
|
68 |
if not self.versions: |
|
69 |
self.load() |
|
70 |
|
|
71 |
if self.cache_backend: |
|
72 |
self.cache_backend.set(self.cache_key, self.versions, CLIENTS_CACHE_TIMEOUT) |
|
73 |
|
|
74 |
def get_latest(self): |
|
75 |
""" |
|
76 |
Return the latest versions |
|
77 |
""" |
|
78 |
|
|
79 |
# update versions |
|
80 |
self.update() |
|
81 |
|
|
82 |
# check that at least one version is available |
|
83 |
if len(self.versions): |
|
84 |
version = self.versions[0] |
|
85 |
version.update(self.extra_version_options) |
|
86 |
return version |
|
87 |
|
|
88 |
return None |
|
89 |
|
|
90 |
|
|
91 |
class RedmineSource(VersionSource): |
|
92 |
""" |
|
93 |
Parse a redmine project files page and return the list of existing files. |
|
94 |
""" |
|
95 |
source_type = 'redmine_files' |
|
96 |
|
|
97 |
def load(self): |
|
98 |
""" |
|
99 |
Load redmine files url and extract downloads. Also parse date to be |
|
100 |
able to identify latest download. |
|
101 |
""" |
|
102 |
spliturl = urlparse.urlsplit(self.link) |
|
103 |
baseurl = spliturl.geturl().replace(spliturl.path, '') |
|
104 |
html = self.get_url(self.link) |
|
105 |
files = html.xpath("//tr[contains(@class, 'file')]") |
|
106 |
|
|
107 |
# helper lambdas |
|
108 |
def _parse_row(row): |
|
109 |
name = row.xpath("td[@class='filename']/a")[0].text |
|
110 |
link = baseurl + row.xpath("td[@class='filename']/a")[0].attrib.get('href') |
|
111 |
strdate = row.xpath("td[@class='created_on']")[0].text |
|
112 |
date = datetime.strptime(strdate, '%m/%d/%Y %I:%M %p') |
|
113 |
return {'name': name, 'link': link, 'date': date, 'version': None} |
|
114 |
|
|
115 |
versions = map(_parse_row, files) |
|
116 |
versions.sort(reverse=True, key=lambda r:r['date']) |
|
117 |
self.versions = versions |
|
118 |
return self |
|
119 |
|
|
120 |
|
|
121 |
class DirectSource(VersionSource): |
|
122 |
""" |
|
123 |
Direct link to a version. Dummy VersionSource which always returns one entry |
|
124 |
for the provided link. |
|
125 |
""" |
|
126 |
source_type = 'direct' |
|
127 |
|
|
128 |
def load(self): |
|
129 |
self.versions = [{'name': self.name, 'link': self.link, 'date': None}] |
|
130 |
return self.versions |
|
131 |
|
|
132 |
|
|
133 |
class LinkSource(DirectSource): |
|
134 |
""" |
|
135 |
Used when version exists in some other url (e.g. apple store client) |
|
136 |
""" |
|
137 |
source_type = 'link' |
|
138 |
|
|
139 |
|
|
140 |
class ClientVersions(object): |
|
141 |
""" |
|
142 |
Client versions manager. Given a sources dict like:: |
|
143 |
|
|
144 |
{'windows': {'source_type': 'direct', 'args': |
|
145 |
['http://clients.com/win.exe'], 'kwargs': {}}, |
|
146 |
'linux': {'redmine_files': 'direct', |
|
147 |
'args': ['http://redmine.com/projects/client/files'], |
|
148 |
'kwargs': {}}} |
|
149 |
|
|
150 |
initializes a dict of proper VersionSource objects. |
|
151 |
""" |
|
152 |
|
|
153 |
def __init__(self, sources, cache_backend=None): |
|
154 |
self._sources = sources |
|
155 |
self.sources = {} |
|
156 |
|
|
157 |
for s in self._sources: |
|
158 |
source_params = self._sources.get(s) |
|
159 |
if source_params['type'] in SOURCE_TYPES: |
|
160 |
kwargs = {'os': s, 'cache_backend': cache_backend} |
|
161 |
args = source_params.get('args', []) |
|
162 |
self.sources[s] = SOURCE_TYPES[source_params['type']](*args, **kwargs) |
|
163 |
|
|
164 |
def get_latest_versions(self): |
|
165 |
""" |
|
166 |
Return the latest version of each version source. |
|
167 |
""" |
|
168 |
for os, source in self.sources.iteritems(): |
|
169 |
yield source.get_latest() |
|
170 |
|
|
171 |
|
|
172 |
# SOURCE TYPES CLASS MAP |
|
173 |
SOURCE_TYPES = { |
|
174 |
'redmine_files': RedmineSource, |
|
175 |
'direct': DirectSource, |
|
176 |
'link': LinkSource |
|
177 |
} |
|
178 |
|
b/cloudcms/cms.py | ||
---|---|---|
139 | 139 |
Page.create_content_type(VideoSection) |
140 | 140 |
Page.create_content_type(LatestEntries) |
141 | 141 |
Page.create_content_type(IntroButton) |
142 |
Page.create_content_type(ClientDownload) |
|
142 | 143 |
Page.create_content_type(ImageContent, POSITION_CHOICES=( |
143 | 144 |
('default', 'Default position'), |
144 | 145 |
)) |
b/cloudcms/content.py | ||
---|---|---|
196 | 196 |
return render_to_string(['content/intro_images.html'], {'content': self}) |
197 | 197 |
|
198 | 198 |
|
199 |
class ClientDownload(models.Model): |
|
200 |
|
|
201 |
client = models.ForeignKey('cloudcms.Client') |
|
202 |
|
|
203 |
@property |
|
204 |
def media(self): |
|
205 |
return forms.Media(js=( |
|
206 |
settings.MEDIA_URL + 'cloudcms/' + 'js/' + 'client-downloads.js',)) |
|
207 |
|
|
208 |
class Meta: |
|
209 |
abstract = True |
|
210 |
verbose_name = _('client download') |
|
211 |
verbose_name_plural = _('client downloads') |
|
212 |
|
|
213 |
def render(self, **kwrags): |
|
214 |
return render_to_string(['content/client_downloads.html'], {'content': self}) |
b/cloudcms/migrate/page/0009_auto__add_resourceslist__add_clientdownload.py | ||
---|---|---|
1 |
# encoding: utf-8 |
|
2 |
import datetime |
|
3 |
from south.db import db |
|
4 |
from south.v2 import SchemaMigration |
|
5 |
from django.db import models |
|
6 |
|
|
7 |
class Migration(SchemaMigration): |
|
8 |
|
|
9 |
def forwards(self, orm): |
|
10 |
|
|
11 |
# Adding model 'ClientDownload' |
|
12 |
db.create_table('page_page_clientdownload', ( |
|
13 |
('ordering', self.gf('django.db.models.fields.IntegerField')(default=0)), |
|
14 |
('region', self.gf('django.db.models.fields.CharField')(max_length=255)), |
|
15 |
('client', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['cloudcms.Client'])), |
|
16 |
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), |
|
17 |
('parent', self.gf('django.db.models.fields.related.ForeignKey')(related_name='clientdownload_set', to=orm['page.Page'])), |
|
18 |
)) |
|
19 |
db.send_create_signal('page', ['ClientDownload']) |
|
20 |
|
|
21 |
|
|
22 |
def backwards(self, orm): |
|
23 |
|
|
24 |
# Deleting model 'ClientDownload' |
|
25 |
db.delete_table('page_page_clientdownload') |
|
26 |
|
|
27 |
|
|
28 |
models = { |
|
29 |
'cloudcms.client': { |
|
30 |
'Meta': {'object_name': 'Client'}, |
|
31 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
32 |
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), |
|
33 |
'uid': ('django.db.models.fields.CharField', [], {'max_length': '255'}) |
|
34 |
}, |
|
35 |
'medialibrary.category': { |
|
36 |
'Meta': {'object_name': 'Category'}, |
|
37 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
38 |
'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['medialibrary.Category']"}), |
|
39 |
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '150', 'db_index': 'True'}), |
|
40 |
'title': ('django.db.models.fields.CharField', [], {'max_length': '200'}) |
|
41 |
}, |
|
42 |
'medialibrary.mediafile': { |
|
43 |
'Meta': {'object_name': 'MediaFile'}, |
|
44 |
'categories': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['medialibrary.Category']", 'null': 'True', 'blank': 'True'}), |
|
45 |
'copyright': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}), |
|
46 |
'created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), |
|
47 |
'file': ('django.db.models.fields.files.FileField', [], {'max_length': '255'}), |
|
48 |
'file_size': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), |
|
49 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
50 |
'type': ('django.db.models.fields.CharField', [], {'max_length': '12'}) |
|
51 |
}, |
|
52 |
'page.aboutblock': { |
|
53 |
'Meta': {'object_name': 'AboutBlock', 'db_table': "'page_page_aboutblock'"}, |
|
54 |
'color': ('django.db.models.fields.CharField', [], {'max_length': '200'}), |
|
55 |
'content': ('django.db.models.fields.TextField', [], {}), |
|
56 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
57 |
'image': ('feincms.module.medialibrary.fields.MediaFileForeignKey', [], {'to': "orm['medialibrary.MediaFile']", 'null': 'True', 'blank': 'True'}), |
|
58 |
'image_position': ('django.db.models.fields.CharField', [], {'max_length': '200'}), |
|
59 |
'offset_left': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), |
|
60 |
'offset_top': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), |
|
61 |
'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}), |
|
62 |
'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'aboutblock_set'", 'to': "orm['page.Page']"}), |
|
63 |
'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}), |
|
64 |
'title': ('django.db.models.fields.CharField', [], {'max_length': '200'}) |
|
65 |
}, |
|
66 |
'page.applicationcontent': { |
|
67 |
'Meta': {'object_name': 'ApplicationContent', 'db_table': "'page_page_applicationcontent'"}, |
|
68 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
69 |
'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}), |
|
70 |
'parameters': ('feincms.contrib.fields.JSONField', [], {'null': 'True'}), |
|
71 |
'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'applicationcontent_set'", 'to': "orm['page.Page']"}), |
|
72 |
'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}), |
|
73 |
'urlconf_path': ('django.db.models.fields.CharField', [], {'max_length': '100'}) |
|
74 |
}, |
|
75 |
'page.clientdownload': { |
|
76 |
'Meta': {'object_name': 'ClientDownload', 'db_table': "'page_page_clientdownload'"}, |
|
77 |
'client': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cloudcms.Client']"}), |
|
78 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
79 |
'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}), |
|
80 |
'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'clientdownload_set'", 'to': "orm['page.Page']"}), |
|
81 |
'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}) |
|
82 |
}, |
|
83 |
'page.imagecontent': { |
|
84 |
'Meta': {'object_name': 'ImageContent', 'db_table': "'page_page_imagecontent'"}, |
|
85 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
86 |
'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}), |
|
87 |
'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}), |
|
88 |
'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'imagecontent_set'", 'to': "orm['page.Page']"}), |
|
89 |
'position': ('django.db.models.fields.CharField', [], {'default': "'default'", 'max_length': '10'}), |
|
90 |
'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}) |
|
91 |
}, |
|
92 |
'page.introbutton': { |
|
93 |
'Meta': {'object_name': 'IntroButton', 'db_table': "'page_page_introbutton'"}, |
|
94 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
95 |
'image_1': ('feincms.module.medialibrary.fields.MediaFileForeignKey', [], {'blank': 'True', 'related_name': "'as_image1'", 'null': 'True', 'to': "orm['medialibrary.MediaFile']"}), |
|
96 |
'image_2': ('feincms.module.medialibrary.fields.MediaFileForeignKey', [], {'blank': 'True', 'related_name': "'as_image2'", 'null': 'True', 'to': "orm['medialibrary.MediaFile']"}), |
|
97 |
'image_3': ('feincms.module.medialibrary.fields.MediaFileForeignKey', [], {'blank': 'True', 'related_name': "'as_image3'", 'null': 'True', 'to': "orm['medialibrary.MediaFile']"}), |
|
98 |
'link': ('django.db.models.fields.CharField', [], {'default': "'/welcome'", 'max_length': '255'}), |
|
99 |
'link_title': ('django.db.models.fields.CharField', [], {'default': "'~okeanos'", 'max_length': '255'}), |
|
100 |
'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}), |
|
101 |
'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'introbutton_set'", 'to': "orm['page.Page']"}), |
|
102 |
'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}) |
|
103 |
}, |
|
104 |
'page.latestentries': { |
|
105 |
'Meta': {'object_name': 'LatestEntries', 'db_table': "'page_page_latestentries'"}, |
|
106 |
'display_text': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
107 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
108 |
'limit': ('django.db.models.fields.PositiveIntegerField', [], {'default': '3'}), |
|
109 |
'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}), |
|
110 |
'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'latestentries_set'", 'to': "orm['page.Page']"}), |
|
111 |
'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}), |
|
112 |
'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) |
|
113 |
}, |
|
114 |
'page.loginform': { |
|
115 |
'Meta': {'object_name': 'LoginForm', 'db_table': "'page_page_loginform'"}, |
|
116 |
'action_url': ('django.db.models.fields.CharField', [], {'max_length': '100'}), |
|
117 |
'bottom_content': ('django.db.models.fields.TextField', [], {'blank': 'True'}), |
|
118 |
'display_forgot_password': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
119 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
120 |
'logged_in_content': ('django.db.models.fields.TextField', [], {'blank': 'True'}), |
|
121 |
'next_url': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), |
|
122 |
'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}), |
|
123 |
'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'loginform_set'", 'to': "orm['page.Page']"}), |
|
124 |
'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}), |
|
125 |
'title': ('django.db.models.fields.CharField', [], {'max_length': '200'}) |
|
126 |
}, |
|
127 |
'page.mediafilecontent': { |
|
128 |
'Meta': {'object_name': 'MediaFileContent', 'db_table': "'page_page_mediafilecontent'"}, |
|
129 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
130 |
'mediafile': ('feincms.module.medialibrary.fields.MediaFileForeignKey', [], {'related_name': "'+'", 'to': "orm['medialibrary.MediaFile']"}), |
|
131 |
'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}), |
|
132 |
'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'mediafilecontent_set'", 'to': "orm['page.Page']"}), |
|
133 |
'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}), |
|
134 |
'type': ('django.db.models.fields.CharField', [], {'default': "'lightbox'", 'max_length': '20'}) |
|
135 |
}, |
|
136 |
'page.page': { |
|
137 |
'Meta': {'object_name': 'Page'}, |
|
138 |
'_cached_url': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '300', 'db_index': 'True', 'blank': 'True'}), |
|
139 |
'_content_title': ('django.db.models.fields.TextField', [], {'blank': 'True'}), |
|
140 |
'_page_title': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), |
|
141 |
'active': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
142 |
'creation_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), |
|
143 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
144 |
'in_navigation': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
145 |
'language': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '10'}), |
|
146 |
'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), |
|
147 |
'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), |
|
148 |
'meta_description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), |
|
149 |
'meta_keywords': ('django.db.models.fields.TextField', [], {'blank': 'True'}), |
|
150 |
'modification_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), |
|
151 |
'navigation_extension': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), |
|
152 |
'override_url': ('django.db.models.fields.CharField', [], {'max_length': '300', 'blank': 'True'}), |
|
153 |
'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['page.Page']"}), |
|
154 |
'publication_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 5, 4, 11, 30)'}), |
|
155 |
'publication_end_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), |
|
156 |
'redirect_to': ('django.db.models.fields.CharField', [], {'max_length': '300', 'blank': 'True'}), |
|
157 |
'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), |
|
158 |
'site': ('django.db.models.fields.related.ForeignKey', [], {'default': '1', 'to': "orm['sites.Site']"}), |
|
159 |
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '150', 'db_index': 'True'}), |
|
160 |
'symlinked_page': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'page_page_symlinks'", 'null': 'True', 'to': "orm['page.Page']"}), |
|
161 |
'template_key': ('django.db.models.fields.CharField', [], {'default': "'basic'", 'max_length': '255'}), |
|
162 |
'title': ('django.db.models.fields.CharField', [], {'max_length': '200'}), |
|
163 |
'translation_of': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'translations'", 'null': 'True', 'to': "orm['page.Page']"}), |
|
164 |
'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}) |
|
165 |
}, |
|
166 |
'page.rawcontent': { |
|
167 |
'Meta': {'object_name': 'RawContent', 'db_table': "'page_page_rawcontent'"}, |
|
168 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
169 |
'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}), |
|
170 |
'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'rawcontent_set'", 'to': "orm['page.Page']"}), |
|
171 |
'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}), |
|
172 |
'text': ('django.db.models.fields.TextField', [], {'blank': 'True'}) |
|
173 |
}, |
|
174 |
'page.resourceslist': { |
|
175 |
'Meta': {'object_name': 'ResourcesList', 'db_table': "'page_page_resourceslist'"}, |
|
176 |
'filter_title': ('django.db.models.fields.CharField', [], {'max_length': '255'}), |
|
177 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
178 |
'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}), |
|
179 |
'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'resourceslist_set'", 'to': "orm['page.Page']"}), |
|
180 |
'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}) |
|
181 |
}, |
|
182 |
'page.richtextcontent': { |
|
183 |
'Meta': {'object_name': 'RichTextContent', 'db_table': "'page_page_richtextcontent'"}, |
|
184 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
185 |
'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}), |
|
186 |
'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'richtextcontent_set'", 'to': "orm['page.Page']"}), |
|
187 |
'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}), |
|
188 |
'text': ('django.db.models.fields.TextField', [], {'blank': 'True'}) |
|
189 |
}, |
|
190 |
'page.sectioncontent': { |
|
191 |
'Meta': {'object_name': 'SectionContent', 'db_table': "'page_page_sectioncontent'"}, |
|
192 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
193 |
'mediafile': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'page_sectioncontent_set'", 'null': 'True', 'to': "orm['medialibrary.MediaFile']"}), |
|
194 |
'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}), |
|
195 |
'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'sectioncontent_set'", 'to': "orm['page.Page']"}), |
|
196 |
'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}), |
|
197 |
'richtext': ('django.db.models.fields.TextField', [], {'blank': 'True'}), |
|
198 |
'title': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}), |
|
199 |
'type': ('django.db.models.fields.CharField', [], {'default': "'block'", 'max_length': '10'}) |
|
200 |
}, |
|
201 |
'page.templatecontent': { |
|
202 |
'Meta': {'object_name': 'TemplateContent', 'db_table': "'page_page_templatecontent'"}, |
|
203 |
'filename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), |
|
204 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
205 |
'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}), |
|
206 |
'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'templatecontent_set'", 'to': "orm['page.Page']"}), |
|
207 |
'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}) |
|
208 |
}, |
|
209 |
'page.twitterfeed': { |
|
210 |
'Meta': {'object_name': 'TwitterFeed', 'db_table': "'page_page_twitterfeed'"}, |
|
211 |
'account': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}), |
|
212 |
'avatar': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
213 |
'extra_params': ('django.db.models.fields.TextField', [], {'blank': 'True'}), |
|
214 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
215 |
'limit': ('django.db.models.fields.PositiveIntegerField', [], {'default': '10'}), |
|
216 |
'nots': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}), |
|
217 |
'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}), |
|
218 |
'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'twitterfeed_set'", 'to': "orm['page.Page']"}), |
|
219 |
'query': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}), |
|
220 |
'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}), |
|
221 |
'replies': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), |
|
222 |
'retweets': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), |
|
223 |
'tag': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}), |
|
224 |
'title': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}) |
|
225 |
}, |
|
226 |
'page.videocontent': { |
|
227 |
'Meta': {'object_name': 'VideoContent', 'db_table': "'page_page_videocontent'"}, |
|
228 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
229 |
'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}), |
|
230 |
'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'videocontent_set'", 'to': "orm['page.Page']"}), |
|
231 |
'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}), |
|
232 |
'video': ('django.db.models.fields.URLField', [], {'max_length': '200'}) |
|
233 |
}, |
|
234 |
'page.videosection': { |
|
235 |
'Meta': {'object_name': 'VideoSection', 'db_table': "'page_page_videosection'"}, |
|
236 |
'alt_text': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), |
|
237 |
'extra_url_params': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}), |
|
238 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
239 |
'image': ('feincms.module.medialibrary.fields.MediaFileForeignKey', [], {'blank': 'True', 'related_name': "'as_image_for_video_section'", 'null': 'True', 'to': "orm['medialibrary.MediaFile']"}), |
|
240 |
'image_hover': ('feincms.module.medialibrary.fields.MediaFileForeignKey', [], {'blank': 'True', 'related_name': "'as_hover_for_video_section'", 'null': 'True', 'to': "orm['medialibrary.MediaFile']"}), |
|
241 |
'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}), |
|
242 |
'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'videosection_set'", 'to': "orm['page.Page']"}), |
|
243 |
'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}), |
|
244 |
'section_title': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}), |
|
245 |
'video_height': ('django.db.models.fields.PositiveIntegerField', [], {'default': '550'}), |
|
246 |
'video_link': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}), |
|
247 |
'video_title': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}), |
|
248 |
'video_width': ('django.db.models.fields.PositiveIntegerField', [], {'default': '700'}) |
|
249 |
}, |
|
250 |
'sites.site': { |
|
251 |
'Meta': {'object_name': 'Site', 'db_table': "'django_site'"}, |
|
252 |
'domain': ('django.db.models.fields.CharField', [], {'max_length': '100'}), |
|
253 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
254 |
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) |
|
255 |
} |
|
256 |
} |
|
257 |
|
|
258 |
complete_apps = ['page'] |
b/cloudcms/migrations/0006_auto__add_clientversionsource__add_client.py | ||
---|---|---|
1 |
# encoding: utf-8 |
|
2 |
import datetime |
|
3 |
from south.db import db |
|
4 |
from south.v2 import SchemaMigration |
|
5 |
from django.db import models |
|
6 |
|
|
7 |
class Migration(SchemaMigration): |
|
8 |
|
|
9 |
def forwards(self, orm): |
|
10 |
|
|
11 |
# Adding model 'ClientVersionSource' |
|
12 |
db.create_table('cloudcms_clientversionsource', ( |
|
13 |
('source_type', self.gf('django.db.models.fields.CharField')(max_length=60)), |
|
14 |
('link', self.gf('django.db.models.fields.CharField')(max_length=255)), |
|
15 |
('architecture', self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True)), |
|
16 |
('logo', self.gf('feincms.module.medialibrary.fields.MediaFileForeignKey')(to=orm['medialibrary.MediaFile'], null=True, blank=True)), |
|
17 |
('os', self.gf('django.db.models.fields.CharField')(max_length=255)), |
|
18 |
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), |
|
19 |
)) |
|
20 |
db.send_create_signal('cloudcms', ['ClientVersionSource']) |
|
21 |
|
|
22 |
# Adding model 'Client' |
|
23 |
db.create_table('cloudcms_client', ( |
|
24 |
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), |
|
25 |
('name', self.gf('django.db.models.fields.CharField')(max_length=255)), |
|
26 |
('uid', self.gf('django.db.models.fields.CharField')(max_length=255)), |
|
27 |
)) |
|
28 |
db.send_create_signal('cloudcms', ['Client']) |
|
29 |
|
|
30 |
# Adding M2M table for field sources on 'Client' |
|
31 |
db.create_table('cloudcms_client_sources', ( |
|
32 |
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), |
|
33 |
('client', models.ForeignKey(orm['cloudcms.client'], null=False)), |
|
34 |
('clientversionsource', models.ForeignKey(orm['cloudcms.clientversionsource'], null=False)) |
|
35 |
)) |
|
36 |
db.create_unique('cloudcms_client_sources', ['client_id', 'clientversionsource_id']) |
|
37 |
|
|
38 |
|
|
39 |
def backwards(self, orm): |
|
40 |
|
|
41 |
# Deleting model 'ClientVersionSource' |
|
42 |
db.delete_table('cloudcms_clientversionsource') |
|
43 |
|
|
44 |
# Deleting model 'Client' |
|
45 |
db.delete_table('cloudcms_client') |
|
46 |
|
|
47 |
# Removing M2M table for field sources on 'Client' |
|
48 |
db.delete_table('cloudcms_client_sources') |
|
49 |
|
|
50 |
|
|
51 |
models = { |
|
52 |
'cloudcms.application': { |
|
53 |
'Meta': {'object_name': 'Application'}, |
|
54 |
'app_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), |
|
55 |
'code': ('django.db.models.fields.CharField', [], {'max_length': '100'}), |
|
56 |
'extra_styles': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), |
|
57 |
'facebook_username': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), |
|
58 |
'favicon': ('feincms.module.medialibrary.fields.MediaFileForeignKey', [], {'blank': 'True', 'related_name': "'as_favicon'", 'null': 'True', 'to': "orm['medialibrary.MediaFile']"}), |
|
59 |
'footer_bottom': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), |
|
60 |
'footer_top': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), |
|
61 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
62 |
'index_url': ('django.db.models.fields.CharField', [], {'default': "'/'", 'max_length': '255'}), |
|
63 |
'linked_in_username': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), |
|
64 |
'logo': ('feincms.module.medialibrary.fields.MediaFileForeignKey', [], {'to': "orm['medialibrary.MediaFile']", 'null': 'True', 'blank': 'True'}), |
|
65 |
'show_twitter_feed_on_top': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
66 |
'site': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['sites.Site']"}), |
|
67 |
'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}), |
|
68 |
'twitter_username': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}) |
|
69 |
}, |
|
70 |
'cloudcms.client': { |
|
71 |
'Meta': {'object_name': 'Client'}, |
|
72 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
73 |
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), |
|
74 |
'sources': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['cloudcms.ClientVersionSource']", 'symmetrical': 'False'}), |
|
75 |
'uid': ('django.db.models.fields.CharField', [], {'max_length': '255'}) |
|
76 |
}, |
|
77 |
'cloudcms.clientversionsource': { |
|
78 |
'Meta': {'object_name': 'ClientVersionSource'}, |
|
79 |
'architecture': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), |
|
80 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
81 |
'link': ('django.db.models.fields.CharField', [], {'max_length': '255'}), |
|
82 |
'logo': ('feincms.module.medialibrary.fields.MediaFileForeignKey', [], {'to': "orm['medialibrary.MediaFile']", 'null': 'True', 'blank': 'True'}), |
|
83 |
'os': ('django.db.models.fields.CharField', [], {'max_length': '255'}), |
|
84 |
'source_type': ('django.db.models.fields.CharField', [], {'max_length': '60'}) |
|
85 |
}, |
|
86 |
'medialibrary.category': { |
|
87 |
'Meta': {'object_name': 'Category'}, |
|
88 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
89 |
'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['medialibrary.Category']"}), |
|
90 |
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '150', 'db_index': 'True'}), |
|
91 |
'title': ('django.db.models.fields.CharField', [], {'max_length': '200'}) |
|
92 |
}, |
|
93 |
'medialibrary.mediafile': { |
|
94 |
'Meta': {'object_name': 'MediaFile'}, |
|
95 |
'categories': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['medialibrary.Category']", 'null': 'True', 'blank': 'True'}), |
|
96 |
'copyright': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}), |
|
97 |
'created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), |
|
98 |
'file': ('django.db.models.fields.files.FileField', [], {'max_length': '255'}), |
|
99 |
'file_size': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), |
|
100 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
101 |
'type': ('django.db.models.fields.CharField', [], {'max_length': '12'}) |
|
102 |
}, |
|
103 |
'sites.site': { |
|
104 |
'Meta': {'object_name': 'Site', 'db_table': "'django_site'"}, |
|
105 |
'domain': ('django.db.models.fields.CharField', [], {'max_length': '100'}), |
|
106 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
107 |
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) |
|
108 |
} |
|
109 |
} |
|
110 |
|
|
111 |
complete_apps = ['cloudcms'] |
b/cloudcms/migrations/0007_auto__add_field_clientversionsource_client.py | ||
---|---|---|
1 |
# encoding: utf-8 |
|
2 |
import datetime |
|
3 |
from south.db import db |
|
4 |
from south.v2 import SchemaMigration |
|
5 |
from django.db import models |
|
6 |
|
|
7 |
class Migration(SchemaMigration): |
|
8 |
|
|
9 |
def forwards(self, orm): |
|
10 |
|
|
11 |
# Adding field 'ClientVersionSource.client' |
|
12 |
db.add_column('cloudcms_clientversionsource', 'client', self.gf('django.db.models.fields.related.ForeignKey')(default=1, to=orm['cloudcms.Client']), keep_default=False) |
|
13 |
|
|
14 |
# Removing M2M table for field sources on 'Client' |
|
15 |
db.delete_table('cloudcms_client_sources') |
|
16 |
|
|
17 |
|
|
18 |
def backwards(self, orm): |
|
19 |
|
|
20 |
# Deleting field 'ClientVersionSource.client' |
|
21 |
db.delete_column('cloudcms_clientversionsource', 'client_id') |
|
22 |
|
|
23 |
# Adding M2M table for field sources on 'Client' |
|
24 |
db.create_table('cloudcms_client_sources', ( |
|
25 |
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), |
|
26 |
('client', models.ForeignKey(orm['cloudcms.client'], null=False)), |
|
27 |
('clientversionsource', models.ForeignKey(orm['cloudcms.clientversionsource'], null=False)) |
|
28 |
)) |
|
29 |
db.create_unique('cloudcms_client_sources', ['client_id', 'clientversionsource_id']) |
|
30 |
|
|
31 |
|
|
32 |
models = { |
|
33 |
'cloudcms.application': { |
|
34 |
'Meta': {'object_name': 'Application'}, |
|
35 |
'app_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), |
|
36 |
'code': ('django.db.models.fields.CharField', [], {'max_length': '100'}), |
|
37 |
'extra_styles': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), |
|
38 |
'facebook_username': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), |
|
39 |
'favicon': ('feincms.module.medialibrary.fields.MediaFileForeignKey', [], {'blank': 'True', 'related_name': "'as_favicon'", 'null': 'True', 'to': "orm['medialibrary.MediaFile']"}), |
|
40 |
'footer_bottom': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), |
|
41 |
'footer_top': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), |
|
42 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
43 |
'index_url': ('django.db.models.fields.CharField', [], {'default': "'/'", 'max_length': '255'}), |
|
44 |
'linked_in_username': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), |
|
45 |
'logo': ('feincms.module.medialibrary.fields.MediaFileForeignKey', [], {'to': "orm['medialibrary.MediaFile']", 'null': 'True', 'blank': 'True'}), |
|
46 |
'show_twitter_feed_on_top': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
47 |
'site': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['sites.Site']"}), |
|
48 |
'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}), |
|
49 |
'twitter_username': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}) |
|
50 |
}, |
|
51 |
'cloudcms.client': { |
|
52 |
'Meta': {'object_name': 'Client'}, |
|
53 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
54 |
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), |
|
55 |
'uid': ('django.db.models.fields.CharField', [], {'max_length': '255'}) |
|
56 |
}, |
|
57 |
'cloudcms.clientversionsource': { |
|
58 |
'Meta': {'object_name': 'ClientVersionSource'}, |
|
59 |
'architecture': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), |
|
60 |
'client': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cloudcms.Client']"}), |
|
61 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
62 |
'link': ('django.db.models.fields.CharField', [], {'max_length': '255'}), |
|
63 |
'logo': ('feincms.module.medialibrary.fields.MediaFileForeignKey', [], {'to': "orm['medialibrary.MediaFile']", 'null': 'True', 'blank': 'True'}), |
|
64 |
'os': ('django.db.models.fields.CharField', [], {'max_length': '255'}), |
|
65 |
'source_type': ('django.db.models.fields.CharField', [], {'max_length': '60'}) |
|
66 |
}, |
|
67 |
'medialibrary.category': { |
|
68 |
'Meta': {'object_name': 'Category'}, |
|
69 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
70 |
'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['medialibrary.Category']"}), |
|
71 |
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '150', 'db_index': 'True'}), |
|
72 |
'title': ('django.db.models.fields.CharField', [], {'max_length': '200'}) |
|
73 |
}, |
|
74 |
'medialibrary.mediafile': { |
|
75 |
'Meta': {'object_name': 'MediaFile'}, |
|
76 |
'categories': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['medialibrary.Category']", 'null': 'True', 'blank': 'True'}), |
|
77 |
'copyright': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}), |
|
78 |
'created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), |
|
79 |
'file': ('django.db.models.fields.files.FileField', [], {'max_length': '255'}), |
|
80 |
'file_size': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), |
|
81 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
82 |
'type': ('django.db.models.fields.CharField', [], {'max_length': '12'}) |
|
83 |
}, |
|
84 |
'sites.site': { |
|
85 |
'Meta': {'object_name': 'Site', 'db_table': "'django_site'"}, |
|
86 |
'domain': ('django.db.models.fields.CharField', [], {'max_length': '100'}), |
|
87 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
88 |
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) |
|
89 |
} |
|
90 |
} |
|
91 |
|
|
92 |
complete_apps = ['cloudcms'] |
b/cloudcms/migrations/0008_auto__add_field_clientversionsource_file_regex__add_field_clientversio.py | ||
---|---|---|
1 |
# encoding: utf-8 |
|
2 |
import datetime |
|
3 |
from south.db import db |
|
4 |
from south.v2 import SchemaMigration |
|
5 |
from django.db import models |
|
6 |
|
|
7 |
class Migration(SchemaMigration): |
|
8 |
|
|
9 |
def forwards(self, orm): |
|
10 |
|
|
11 |
# Adding field 'ClientVersionSource.file_regex' |
|
12 |
db.add_column('cloudcms_clientversionsource', 'file_regex', self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True), keep_default=False) |
|
13 |
|
|
14 |
# Adding field 'ClientVersionSource.version_regex' |
|
15 |
db.add_column('cloudcms_clientversionsource', 'version_regex', self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True), keep_default=False) |
|
16 |
|
|
17 |
|
|
18 |
def backwards(self, orm): |
|
19 |
|
|
20 |
# Deleting field 'ClientVersionSource.file_regex' |
|
21 |
db.delete_column('cloudcms_clientversionsource', 'file_regex') |
|
22 |
|
|
23 |
# Deleting field 'ClientVersionSource.version_regex' |
|
24 |
db.delete_column('cloudcms_clientversionsource', 'version_regex') |
|
25 |
|
|
26 |
|
|
27 |
models = { |
|
28 |
'cloudcms.application': { |
|
29 |
'Meta': {'object_name': 'Application'}, |
|
30 |
'app_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), |
|
31 |
'code': ('django.db.models.fields.CharField', [], {'max_length': '100'}), |
|
32 |
'extra_styles': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), |
|
33 |
'facebook_username': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), |
|
34 |
'favicon': ('feincms.module.medialibrary.fields.MediaFileForeignKey', [], {'blank': 'True', 'related_name': "'as_favicon'", 'null': 'True', 'to': "orm['medialibrary.MediaFile']"}), |
|
35 |
'footer_bottom': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), |
|
36 |
'footer_top': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), |
|
37 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
38 |
'index_url': ('django.db.models.fields.CharField', [], {'default': "'/'", 'max_length': '255'}), |
|
39 |
'linked_in_username': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), |
|
40 |
'logo': ('feincms.module.medialibrary.fields.MediaFileForeignKey', [], {'to': "orm['medialibrary.MediaFile']", 'null': 'True', 'blank': 'True'}), |
|
41 |
'show_twitter_feed_on_top': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), |
|
42 |
'site': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['sites.Site']"}), |
|
43 |
'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}), |
|
44 |
'twitter_username': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}) |
|
45 |
}, |
|
46 |
'cloudcms.client': { |
|
47 |
'Meta': {'object_name': 'Client'}, |
|
48 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
49 |
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), |
|
50 |
'uid': ('django.db.models.fields.CharField', [], {'max_length': '255'}) |
|
51 |
}, |
|
52 |
'cloudcms.clientversionsource': { |
|
53 |
'Meta': {'object_name': 'ClientVersionSource'}, |
|
54 |
'architecture': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), |
|
55 |
'client': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cloudcms.Client']"}), |
|
56 |
'file_regex': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), |
|
57 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
58 |
'link': ('django.db.models.fields.CharField', [], {'max_length': '255'}), |
|
59 |
'logo': ('feincms.module.medialibrary.fields.MediaFileForeignKey', [], {'to': "orm['medialibrary.MediaFile']", 'null': 'True', 'blank': 'True'}), |
|
60 |
'os': ('django.db.models.fields.CharField', [], {'max_length': '255'}), |
|
61 |
'source_type': ('django.db.models.fields.CharField', [], {'max_length': '60'}), |
|
62 |
'version_regex': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}) |
|
63 |
}, |
|
64 |
'medialibrary.category': { |
|
65 |
'Meta': {'object_name': 'Category'}, |
|
66 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
67 |
'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['medialibrary.Category']"}), |
|
68 |
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '150', 'db_index': 'True'}), |
|
69 |
'title': ('django.db.models.fields.CharField', [], {'max_length': '200'}) |
|
70 |
}, |
|
71 |
'medialibrary.mediafile': { |
|
72 |
'Meta': {'object_name': 'MediaFile'}, |
|
73 |
'categories': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['medialibrary.Category']", 'null': 'True', 'blank': 'True'}), |
|
74 |
'copyright': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}), |
|
75 |
'created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), |
|
76 |
'file': ('django.db.models.fields.files.FileField', [], {'max_length': '255'}), |
|
77 |
'file_size': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), |
|
78 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
79 |
'type': ('django.db.models.fields.CharField', [], {'max_length': '12'}) |
|
80 |
}, |
|
81 |
'sites.site': { |
|
82 |
'Meta': {'object_name': 'Site', 'db_table': "'django_site'"}, |
|
83 |
'domain': ('django.db.models.fields.CharField', [], {'max_length': '100'}), |
|
84 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
85 |
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) |
|
86 |
} |
|
87 |
} |
|
88 |
|
|
89 |
complete_apps = ['cloudcms'] |
b/cloudcms/models.py | ||
---|---|---|
31 | 31 |
# interpreted as representing official policies, either expressed |
32 | 32 |
# or implied, of GRNET S.A. |
33 | 33 |
|
34 |
import datetime |
|
34 | 35 |
|
35 | 36 |
from django.db import models |
36 | 37 |
from django.conf import settings |
37 | 38 |
from django.contrib.sites import models as sites_models |
39 |
from django.core.cache import cache |
|
40 |
from django.utils import simplejson |
|
38 | 41 |
|
39 | 42 |
from feincms.module.medialibrary.fields import MediaFileForeignKey |
40 | 43 |
from feincms.module.medialibrary.models import MediaFile |
41 | 44 |
|
42 | 45 |
|
43 | 46 |
class Application(models.Model): |
47 |
""" |
|
48 |
Application object refers to the application each cms is deployed for. |
|
49 |
|
|
50 |
Each cms deployment should contain at least one application object linked |
|
51 |
to the site object the cms is deployed for. |
|
52 |
|
|
53 |
Enabling cloudcms.context_processors.application in CONTEXT_PROCESSROS setting |
|
54 |
let you can access the application object throughout the html templates. |
|
55 |
""" |
|
44 | 56 |
code = models.CharField('Identifier', max_length=100, null=False, blank=False, |
45 | 57 |
help_text="Just a codename of the application, to be used in "\ |
46 | 58 |
"several places where no free text is allowed"\ |
... | ... | |
74 | 86 |
return self.title |
75 | 87 |
|
76 | 88 |
|
89 |
# http://stackoverflow.com/a/2680060/114435 |
|
90 |
dthandler = lambda obj: obj.isoformat() if isinstance(obj, datetime.datetime) else None |
|
91 |
|
|
92 |
class Client(models.Model): |
|
93 |
""" |
|
94 |
Model which refers to a service/application client. Client model contains |
|
95 |
multiple ClientVersionSource to identify it's version downloads. |
|
96 |
""" |
|
97 |
uid = models.CharField(max_length=255) |
|
98 |
name = models.CharField(max_length=255) |
|
99 |
|
|
100 |
def get_sources(self): |
|
101 |
sources = {} |
|
102 |
from cloudcms.clients import ClientVersions |
|
103 |
for s in self.clientversionsource_set.all(): |
|
104 |
sources[s.os] = {'type': s.source_type, |
|
105 |
'args': [s.link]} |
|
106 |
|
|
107 |
return ClientVersions(sources, cache_backend=cache) |
|
108 |
|
|
109 |
def to_json(self): |
|
110 |
return simplejson.dumps(list(self.get_sources().get_latest_versions()), |
|
111 |
default=dthandler) |
|
112 |
|
|
113 |
def __unicode__(self): |
|
114 |
return self.name |
|
115 |
|
|
116 |
|
|
117 |
class ClientVersionSource(models.Model): |
|
118 |
""" |
|
119 |
Client version source. source_type choices should map to |
|
120 |
cloudcms.clients.SOURCE_TYPES. |
|
121 |
""" |
|
122 |
source_type = models.CharField(max_length=60, |
|
123 |
choices=(('link','Link'), |
|
124 |
('direct','Direct'), |
|
125 |
('redmine_files','Redmine files'))) |
|
126 |
os = models.CharField(max_length=255) |
|
127 |
link = models.CharField(max_length=255) |
|
128 |
logo = MediaFileForeignKey(MediaFile, blank=True, null=True) |
|
129 |
architecture = models.CharField(max_length=255, null=True, blank=True, |
|
130 |
help_text="""Depending the source type this can be left empty and |
|
131 |
let source type identify the architecture""") |
|
132 |
client = models.ForeignKey(Client) |
|
133 |
version_regex = models.CharField(max_length=255, help_text="""Regular expression to |
|
134 |
match the version of the file based on retrieved source filenames |
|
135 |
(used in redmine source types)""", null=True, blank=True) |
|
136 |
file_regex = models.CharField(max_length=255, help_text="""Return only files that |
|
137 |
match this expression""", null=True, blank=True) |
|
138 |
|
|
139 |
def __unicode__(self): |
|
140 |
return "[%s] %s" % (self.get_source_type_display(), self.os) |
|
141 |
|
|
142 |
|
|
77 | 143 |
# hook for feincms configuration, is this appropriate place ??? who knows |
78 | 144 |
from cloudcms.cms import * |
79 | 145 |
|
b/cloudcms/static/cloudcms/js/client-downloads.js | ||
---|---|---|
1 |
var ClientDownloads = function(wrapper, clients) { |
|
2 |
this.el = $(wrapper); |
|
3 |
this.clients = clients; |
|
4 |
} |
|
5 |
|
|
6 |
ClientDownloads.prototype.update = function() { |
|
7 |
console.log("updating clients"); |
|
8 |
} |
|
9 |
|
b/cloudcms/templates/content/client_downloads.html | ||
---|---|---|
1 |
<div class="clients-wrapper"> |
|
2 |
<ul> |
|
3 |
</ul> |
|
4 |
</div> |
|
5 |
|
|
6 |
<script> |
|
7 |
$(document).ready(function(){ |
|
8 |
if (window.ClientDownloads) { |
|
9 |
var clients_data = {{ content.client.to_json|safe }}; |
|
10 |
var clients = new ClientDownloads(".clients-wrapper", clients_data); |
|
11 |
clients.update(); |
|
12 |
} |
|
13 |
}) |
|
14 |
</script> |
Also available in: Unified diff