Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

first commit

  • Loading branch information...
commit ba5e9d3a8680ae51bb046189da6461486d54a17f 0 parents
@justquick authored
Showing with 23,444 additions and 0 deletions.
  1. +58 −0 README.txt
  2. +1 −0  __init__.py
  3. BIN  __init__.pyc
  4. 0  apps/api/__init__.py
  5. BIN  apps/api/__init__.pyc
  6. +31 −0 apps/api/handlers.py
  7. BIN  apps/api/handlers.pyc
  8. +9 −0 apps/api/urls.py
  9. BIN  apps/api/urls.pyc
  10. +3 −0  apps/django_ext/__init__.py
  11. BIN  apps/django_ext/__init__.pyc
  12. 0  apps/django_ext/admin.py
  13. BIN  apps/django_ext/admin.pyc
  14. +25 −0 apps/django_ext/cache.py
  15. +133 −0 apps/django_ext/fields.py
  16. +1 −0  apps/django_ext/management/__init__.py
  17. BIN  apps/django_ext/management/__init__.pyc
  18. 0  apps/django_ext/management/commands/__init__.py
  19. +20 −0 apps/django_ext/management/commands/delete_contenttypes.py
  20. +17 −0 apps/django_ext/management/commands/flush_all_memcached.py
  21. +87 −0 apps/django_ext/managers.py
  22. +48 −0 apps/django_ext/middleware.py
  23. +1 −0  apps/django_ext/models.py
  24. BIN  apps/django_ext/models.pyc
  25. +1 −0  apps/django_ext/templatetags/__init__.py
  26. BIN  apps/django_ext/templatetags/__init__.pyc
  27. +98 −0 apps/django_ext/templatetags/fb.py
  28. BIN  apps/django_ext/templatetags/fb.pyc
  29. +104 −0 apps/django_ext/templatetags/listutil.py
  30. BIN  apps/django_ext/templatetags/listutil.pyc
  31. +333 −0 apps/django_ext/templatetags/smart_if.py
  32. BIN  apps/django_ext/templatetags/smart_if.pyc
  33. +14 −0 apps/django_ext/views.py
  34. BIN  apps/django_ext/views.pyc
  35. +28 −0 bin/ext-status.sh
  36. +32 −0 bin/install.sh
  37. +28 −0 bin/pull-ext.sh
  38. +28 −0 bin/push-ext.sh
  39. +8 −0 bin/upgrade.sh
  40. +18 −0 conf/EffervescentCollective.wsgi
  41. +35 −0 conf/apache2-EffervescentCollective
  42. +23 −0 conf/nginx-EffervescentCollective
  43. +13 −0 conf/proxy.conf
  44. BIN  dev.db
  45. +18 −0 local_settings.py
  46. BIN  local_settings.pyc
  47. +18 −0 manage.py
  48. BIN  media/.DS_Store
  49. BIN  media/Nautica05b/Thumbs.db
  50. +263 −0 media/Nautica05b/contact.html
  51. +203 −0 media/Nautica05b/css/html.css
  52. +551 −0 media/Nautica05b/css/layout.css
  53. BIN  media/Nautica05b/images/Thumbs.db
  54. BIN  media/Nautica05b/images/bg/Thumbs.db
  55. BIN  media/Nautica05b/images/bg/blank.gif
  56. BIN  media/Nautica05b/images/bg/header.gif
  57. BIN  media/Nautica05b/images/bg/header_image.jpg
  58. BIN  media/Nautica05b/images/bg/header_image2.jpg
  59. BIN  media/Nautica05b/images/bg/light_body.gif
  60. BIN  media/Nautica05b/images/bg/menu.gif
  61. BIN  media/Nautica05b/images/bg/submenu1.gif
  62. BIN  media/Nautica05b/images/bg/submenu2.gif
  63. BIN  media/Nautica05b/images/firefox.jpg
  64. BIN  media/Nautica05b/images/icon_samples.gif
  65. BIN  media/Nautica05b/images/logo.gif
  66. BIN  media/Nautica05b/images/logo.jpg
  67. BIN  media/Nautica05b/images/thumbs/01.jpg
  68. BIN  media/Nautica05b/images/thumbs/Thumbs.db
  69. +322 −0 media/Nautica05b/index.html
  70. +245 −0 media/Nautica05b/onecol.html
  71. +10 −0 media/Nautica05b/readme.txt
  72. +278 −0 media/Nautica05b/twocol_a.html
  73. +304 −0 media/Nautica05b/twocol_b.html
  74. +746 −0 media/admin/css/base.css
  75. +255 −0 media/admin/css/changelists.css
  76. +24 −0 media/admin/css/dashboard.css
  77. +327 −0 media/admin/css/forms.css
  78. +51 −0 media/admin/css/ie.css
  79. +54 −0 media/admin/css/login.css
  80. +195 −0 media/admin/css/rtl.css
  81. +506 −0 media/admin/css/widgets.css
  82. BIN  media/admin/img/admin/arrow-down.gif
  83. BIN  media/admin/img/admin/arrow-up.gif
  84. BIN  media/admin/img/admin/changelist-bg.gif
  85. BIN  media/admin/img/admin/changelist-bg_rtl.gif
  86. BIN  media/admin/img/admin/chooser-bg.gif
  87. BIN  media/admin/img/admin/chooser_stacked-bg.gif
  88. BIN  media/admin/img/admin/default-bg-reverse.gif
  89. BIN  media/admin/img/admin/default-bg.gif
  90. BIN  media/admin/img/admin/deleted-overlay.gif
  91. BIN  media/admin/img/admin/icon-no.gif
  92. BIN  media/admin/img/admin/icon-unknown.gif
  93. BIN  media/admin/img/admin/icon-yes.gif
  94. BIN  media/admin/img/admin/icon_addlink.gif
  95. BIN  media/admin/img/admin/icon_alert.gif
  96. BIN  media/admin/img/admin/icon_calendar.gif
  97. BIN  media/admin/img/admin/icon_changelink.gif
  98. BIN  media/admin/img/admin/icon_clock.gif
  99. BIN  media/admin/img/admin/icon_deletelink.gif
  100. BIN  media/admin/img/admin/icon_error.gif
  101. BIN  media/admin/img/admin/icon_searchbox.png
  102. BIN  media/admin/img/admin/icon_success.gif
  103. BIN  media/admin/img/admin/inline-delete-8bit.png
  104. BIN  media/admin/img/admin/inline-delete.png
  105. BIN  media/admin/img/admin/inline-restore-8bit.png
  106. BIN  media/admin/img/admin/inline-restore.png
  107. BIN  media/admin/img/admin/inline-splitter-bg.gif
  108. BIN  media/admin/img/admin/nav-bg-grabber.gif
  109. BIN  media/admin/img/admin/nav-bg-reverse.gif
  110. BIN  media/admin/img/admin/nav-bg.gif
  111. BIN  media/admin/img/admin/selector-add.gif
  112. BIN  media/admin/img/admin/selector-addall.gif
  113. BIN  media/admin/img/admin/selector-remove.gif
  114. BIN  media/admin/img/admin/selector-removeall.gif
  115. BIN  media/admin/img/admin/selector-search.gif
  116. BIN  media/admin/img/admin/selector_stacked-add.gif
  117. BIN  media/admin/img/admin/selector_stacked-remove.gif
  118. BIN  media/admin/img/admin/tool-left.gif
  119. BIN  media/admin/img/admin/tool-left_over.gif
  120. BIN  media/admin/img/admin/tool-right.gif
  121. BIN  media/admin/img/admin/tool-right_over.gif
  122. BIN  media/admin/img/admin/tooltag-add.gif
  123. BIN  media/admin/img/admin/tooltag-add_over.gif
  124. BIN  media/admin/img/admin/tooltag-arrowright.gif
  125. BIN  media/admin/img/admin/tooltag-arrowright_over.gif
  126. BIN  media/admin/img/gis/move_vertex_off.png
  127. BIN  media/admin/img/gis/move_vertex_on.png
  128. +111 −0 media/admin/js/SelectBox.js
  129. +113 −0 media/admin/js/SelectFilter2.js
  130. +19 −0 media/admin/js/actions.js
  131. +85 −0 media/admin/js/admin/CollapsedFieldsets.js
  132. +255 −0 media/admin/js/admin/DateTimeShortcuts.js
  133. +92 −0 media/admin/js/admin/RelatedObjectLookups.js
  134. +137 −0 media/admin/js/admin/ordering.js
  135. +143 −0 media/admin/js/calendar.js
  136. +176 −0 media/admin/js/core.js
  137. +233 −0 media/admin/js/dateparse.js
  138. +167 −0 media/admin/js/getElementsBySelector.js
  139. +94 −0 media/admin/js/timeparse.js
  140. +140 −0 media/admin/js/urlify.js
  141. +203 −0 media/css/html.css
  142. +551 −0 media/css/layout.css
  143. +16 −0 media/css/screen.css
  144. BIN  media/images/Thumbs.db
  145. BIN  media/images/bg/.DS_Store
  146. BIN  media/images/bg/blank.gif
  147. BIN  media/images/bg/header.gif
  148. BIN  media/images/bg/header_image.jpg
  149. BIN  media/images/bg/header_image2.jpg
  150. BIN  media/images/bg/light_body.gif
  151. BIN  media/images/bg/menu.gif
  152. BIN  media/images/bg/submenu1.gif
  153. BIN  media/images/bg/submenu2.gif
  154. BIN  media/images/dsc_0041.jpg
  155. BIN  media/images/firefox.jpg
  156. BIN  media/images/icon_samples.gif
  157. BIN  media/images/logo.gif
  158. BIN  media/images/logo.jpg
  159. +1 −0  media/images/temporary.txt
  160. +1 −0  media/js/global.js
  161. +4,376 −0 media/js/jquery-1.3.2.js
  162. +141 −0 media/js/jquery.tag.editor.js
  163. BIN  media/js/tiny_mce/.DS_Store
  164. +154 −0 media/js/tiny_mce/langs/en.js
  165. +504 −0 media/js/tiny_mce/license.txt
  166. +5 −0 media/js/tiny_mce/plugins/advhr/css/advhr.css
  167. +1 −0  media/js/tiny_mce/plugins/advhr/editor_plugin.js
  168. +54 −0 media/js/tiny_mce/plugins/advhr/editor_plugin_src.js
  169. +43 −0 media/js/tiny_mce/plugins/advhr/js/rule.js
  170. +5 −0 media/js/tiny_mce/plugins/advhr/langs/en_dlg.js
  171. +62 −0 media/js/tiny_mce/plugins/advhr/rule.htm
  172. +13 −0 media/js/tiny_mce/plugins/advimage/css/advimage.css
  173. +1 −0  media/js/tiny_mce/plugins/advimage/editor_plugin.js
  174. +47 −0 media/js/tiny_mce/plugins/advimage/editor_plugin_src.js
  175. +237 −0 media/js/tiny_mce/plugins/advimage/image.htm
  176. BIN  media/js/tiny_mce/plugins/advimage/img/sample.gif
  177. +443 −0 media/js/tiny_mce/plugins/advimage/js/image.js
  178. +43 −0 media/js/tiny_mce/plugins/advimage/langs/en_dlg.js
  179. +8 −0 media/js/tiny_mce/plugins/advlink/css/advlink.css
  180. +1 −0  media/js/tiny_mce/plugins/advlink/editor_plugin.js
  181. +58 −0 media/js/tiny_mce/plugins/advlink/editor_plugin_src.js
  182. +528 −0 media/js/tiny_mce/plugins/advlink/js/advlink.js
  183. +52 −0 media/js/tiny_mce/plugins/advlink/langs/en_dlg.js
  184. +338 −0 media/js/tiny_mce/plugins/advlink/link.htm
  185. +1 −0  media/js/tiny_mce/plugins/autoresize/editor_plugin.js
  186. +114 −0 media/js/tiny_mce/plugins/autoresize/editor_plugin_src.js
  187. +1 −0  media/js/tiny_mce/plugins/autosave/editor_plugin.js
  188. +51 −0 media/js/tiny_mce/plugins/autosave/editor_plugin_src.js
  189. +1 −0  media/js/tiny_mce/plugins/bbcode/editor_plugin.js
  190. +117 −0 media/js/tiny_mce/plugins/bbcode/editor_plugin_src.js
  191. +1 −0  media/js/tiny_mce/plugins/contextmenu/editor_plugin.js
  192. +95 −0 media/js/tiny_mce/plugins/contextmenu/editor_plugin_src.js
  193. +1 −0  media/js/tiny_mce/plugins/directionality/editor_plugin.js
  194. +79 −0 media/js/tiny_mce/plugins/directionality/editor_plugin_src.js
  195. +1 −0  media/js/tiny_mce/plugins/emotions/editor_plugin.js
  196. +40 −0 media/js/tiny_mce/plugins/emotions/editor_plugin_src.js
  197. +40 −0 media/js/tiny_mce/plugins/emotions/emotions.htm
  198. BIN  media/js/tiny_mce/plugins/emotions/img/smiley-cool.gif
  199. BIN  media/js/tiny_mce/plugins/emotions/img/smiley-cry.gif
  200. BIN  media/js/tiny_mce/plugins/emotions/img/smiley-embarassed.gif
  201. BIN  media/js/tiny_mce/plugins/emotions/img/smiley-foot-in-mouth.gif
  202. BIN  media/js/tiny_mce/plugins/emotions/img/smiley-frown.gif
  203. BIN  media/js/tiny_mce/plugins/emotions/img/smiley-innocent.gif
  204. BIN  media/js/tiny_mce/plugins/emotions/img/smiley-kiss.gif
  205. BIN  media/js/tiny_mce/plugins/emotions/img/smiley-laughing.gif
  206. BIN  media/js/tiny_mce/plugins/emotions/img/smiley-money-mouth.gif
  207. BIN  media/js/tiny_mce/plugins/emotions/img/smiley-sealed.gif
  208. BIN  media/js/tiny_mce/plugins/emotions/img/smiley-smile.gif
  209. BIN  media/js/tiny_mce/plugins/emotions/img/smiley-surprised.gif
  210. BIN  media/js/tiny_mce/plugins/emotions/img/smiley-tongue-out.gif
  211. BIN  media/js/tiny_mce/plugins/emotions/img/smiley-undecided.gif
  212. BIN  media/js/tiny_mce/plugins/emotions/img/smiley-wink.gif
  213. BIN  media/js/tiny_mce/plugins/emotions/img/smiley-yell.gif
  214. +22 −0 media/js/tiny_mce/plugins/emotions/js/emotions.js
  215. +20 −0 media/js/tiny_mce/plugins/emotions/langs/en_dlg.js
  216. +27 −0 media/js/tiny_mce/plugins/example/dialog.htm
  217. +1 −0  media/js/tiny_mce/plugins/example/editor_plugin.js
  218. +81 −0 media/js/tiny_mce/plugins/example/editor_plugin_src.js
  219. BIN  media/js/tiny_mce/plugins/example/img/example.gif
  220. +19 −0 media/js/tiny_mce/plugins/example/js/dialog.js
  221. +3 −0  media/js/tiny_mce/plugins/example/langs/en.js
  222. +3 −0  media/js/tiny_mce/plugins/example/langs/en_dlg.js
  223. +182 −0 media/js/tiny_mce/plugins/fullpage/css/fullpage.css
  224. +1 −0  media/js/tiny_mce/plugins/fullpage/editor_plugin.js
  225. +146 −0 media/js/tiny_mce/plugins/fullpage/editor_plugin_src.js
  226. +576 −0 media/js/tiny_mce/plugins/fullpage/fullpage.htm
  227. +461 −0 media/js/tiny_mce/plugins/fullpage/js/fullpage.js
  228. +85 −0 media/js/tiny_mce/plugins/fullpage/langs/en_dlg.js
  229. +1 −0  media/js/tiny_mce/plugins/fullscreen/editor_plugin.js
  230. +145 −0 media/js/tiny_mce/plugins/fullscreen/editor_plugin_src.js
  231. +110 −0 media/js/tiny_mce/plugins/fullscreen/fullscreen.htm
  232. +1 −0  media/js/tiny_mce/plugins/iespell/editor_plugin.js
  233. +51 −0 media/js/tiny_mce/plugins/iespell/editor_plugin_src.js
  234. +1 −0  media/js/tiny_mce/plugins/inlinepopups/editor_plugin.js
  235. +632 −0 media/js/tiny_mce/plugins/inlinepopups/editor_plugin_src.js
  236. BIN  media/js/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/alert.gif
  237. BIN  media/js/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/button.gif
  238. BIN  media/js/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/buttons.gif
  239. BIN  media/js/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/confirm.gif
  240. BIN  media/js/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/corners.gif
  241. BIN  media/js/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/horizontal.gif
  242. BIN  media/js/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/vertical.gif
  243. +90 −0 media/js/tiny_mce/plugins/inlinepopups/skins/clearlooks2/window.css
  244. +387 −0 media/js/tiny_mce/plugins/inlinepopups/template.htm
  245. +1 −0  media/js/tiny_mce/plugins/insertdatetime/editor_plugin.js
  246. +80 −0 media/js/tiny_mce/plugins/insertdatetime/editor_plugin_src.js
  247. +1 −0  media/js/tiny_mce/plugins/layer/editor_plugin.js
  248. +209 −0 media/js/tiny_mce/plugins/layer/editor_plugin_src.js
  249. +6 −0 media/js/tiny_mce/plugins/media/css/content.css
  250. +16 −0 media/js/tiny_mce/plugins/media/css/media.css
  251. +1 −0  media/js/tiny_mce/plugins/media/editor_plugin.js
  252. +411 −0 media/js/tiny_mce/plugins/media/editor_plugin_src.js
  253. BIN  media/js/tiny_mce/plugins/media/img/flash.gif
  254. BIN  media/js/tiny_mce/plugins/media/img/flv_player.swf
  255. BIN  media/js/tiny_mce/plugins/media/img/quicktime.gif
  256. BIN  media/js/tiny_mce/plugins/media/img/realmedia.gif
  257. BIN  media/js/tiny_mce/plugins/media/img/shockwave.gif
  258. BIN  media/js/tiny_mce/plugins/media/img/trans.gif
  259. BIN  media/js/tiny_mce/plugins/media/img/windowsmedia.gif
  260. +73 −0 media/js/tiny_mce/plugins/media/js/embed.js
  261. +630 −0 media/js/tiny_mce/plugins/media/js/media.js
  262. +103 −0 media/js/tiny_mce/plugins/media/langs/en_dlg.js
  263. +822 −0 media/js/tiny_mce/plugins/media/media.htm
  264. +1 −0  media/js/tiny_mce/plugins/nonbreaking/editor_plugin.js
  265. +50 −0 media/js/tiny_mce/plugins/nonbreaking/editor_plugin_src.js
  266. +1 −0  media/js/tiny_mce/plugins/noneditable/editor_plugin.js
  267. +87 −0 media/js/tiny_mce/plugins/noneditable/editor_plugin_src.js
  268. +1 −0  media/js/tiny_mce/plugins/pagebreak/css/content.css
  269. +1 −0  media/js/tiny_mce/plugins/pagebreak/editor_plugin.js
  270. +74 −0 media/js/tiny_mce/plugins/pagebreak/editor_plugin_src.js
  271. BIN  media/js/tiny_mce/plugins/pagebreak/img/pagebreak.gif
  272. BIN  media/js/tiny_mce/plugins/pagebreak/img/trans.gif
  273. +1 −0  media/js/tiny_mce/plugins/paste/editor_plugin.js
  274. +531 −0 media/js/tiny_mce/plugins/paste/editor_plugin_src.js
  275. +36 −0 media/js/tiny_mce/plugins/paste/js/pastetext.js
  276. +51 −0 media/js/tiny_mce/plugins/paste/js/pasteword.js
  277. +5 −0 media/js/tiny_mce/plugins/paste/langs/en_dlg.js
  278. +33 −0 media/js/tiny_mce/plugins/paste/pastetext.htm
  279. +27 −0 media/js/tiny_mce/plugins/paste/pasteword.htm
  280. +1 −0  media/js/tiny_mce/plugins/preview/editor_plugin.js
  281. +50 −0 media/js/tiny_mce/plugins/preview/editor_plugin_src.js
  282. +28 −0 media/js/tiny_mce/plugins/preview/example.html
  283. +73 −0 media/js/tiny_mce/plugins/preview/jscripts/embed.js
  284. +17 −0 media/js/tiny_mce/plugins/preview/preview.html
  285. +1 −0  media/js/tiny_mce/plugins/print/editor_plugin.js
  286. +31 −0 media/js/tiny_mce/plugins/print/editor_plugin_src.js
  287. +1 −0  media/js/tiny_mce/plugins/safari/blank.htm
  288. +1 −0  media/js/tiny_mce/plugins/safari/editor_plugin.js
  289. +438 −0 media/js/tiny_mce/plugins/safari/editor_plugin_src.js
  290. +1 −0  media/js/tiny_mce/plugins/save/editor_plugin.js
  291. +98 −0 media/js/tiny_mce/plugins/save/editor_plugin_src.js
  292. +6 −0 media/js/tiny_mce/plugins/searchreplace/css/searchreplace.css
  293. +1 −0  media/js/tiny_mce/plugins/searchreplace/editor_plugin.js
  294. +54 −0 media/js/tiny_mce/plugins/searchreplace/editor_plugin_src.js
  295. +126 −0 media/js/tiny_mce/plugins/searchreplace/js/searchreplace.js
  296. +16 −0 media/js/tiny_mce/plugins/searchreplace/langs/en_dlg.js
  297. +104 −0 media/js/tiny_mce/plugins/searchreplace/searchreplace.htm
  298. +1 −0  media/js/tiny_mce/plugins/spellchecker/css/content.css
  299. +1 −0  media/js/tiny_mce/plugins/spellchecker/editor_plugin.js
  300. +338 −0 media/js/tiny_mce/plugins/spellchecker/editor_plugin_src.js
Sorry, we could not display the entire diff because too many files (440) changed.
58 README.txt
@@ -0,0 +1,58 @@
+GETTING SET UP FOR THE FIRST TIME
+---------------------------------
+
+1. Bootstrap your environment. This only needs to be done once:
+
+ ./setup/_bootstrap.sh
+
+
+2. Create a virtual environment (it doesn't need to be named EffervescentCollective,
+ but name it something you'll remember):
+
+ mkvirtualenv EffervescentCollective
+
+
+3. Install the "pip" Python package manager in the new virtual environment:
+
+ easy_install pip
+
+
+4. Upgrade to the latest version of the packages:
+
+ ./bin/upgrade.sh
+
+5. Link the source directory into the project folder for easier access
+
+ ln -s ~/.virtualenvs/EffervescentCollective/src/ externals
+
+
+WHAT YOU SHOULD DO PERIODICALLY
+-------------------------------
+
+1. Switch to the correct virtual environment:
+
+ workon EffervescentCollective
+
+
+2. Upgrade to the latest version of the packages:
+
+ ./bin/upgrade.sh
+
+
+
+WHAT YOU SHOULD DO EVERY DAY
+----------------------------
+
+1. Upgrade to the latest code:
+
+ git pull
+
+
+2. Switch to the correct virtual environment:
+
+ workon EffervescentCollective
+
+
+3. Start your local development server:
+
+ python manage.py runserver 0.0.0.0:8000
1  __init__.py
@@ -0,0 +1 @@
+
BIN  __init__.pyc
Binary file not shown
0  apps/api/__init__.py
No changes.
BIN  apps/api/__init__.pyc
Binary file not shown
31 apps/api/handlers.py
@@ -0,0 +1,31 @@
+from piston.handler import BaseHandler
+from tagging.models import Tag, TaggedItem
+from django.db.models import get_model
+from django.core.urlresolvers import reverse
+from pprint import pprint
+
+class TagHandler(BaseHandler):
+ allowed_methods = ('GET',)
+ model = Tag
+
+ def read(self, request):
+ if 'referer' in request.GET:
+ bits = filter(None, request.GET['referer'].replace('/admin/','').split('/'))
+ model = get_model(*bits[:2])
+
+ if len(bits) == 2:
+ r = []
+ for x in Tag.objects.cloud_for_model(model):
+ r.append({'size':x.font_size,'name':x.name})
+ return r
+ elif len(bits) == 3:
+ if bits[2] == 'add':
+ return []
+ obj = model.objects.get(pk=bits[2])
+ tags = Tag.objects.get_for_object(obj)
+ if 'tags' in request.GET:
+ obj.tags = request.GET['tags']
+ else:
+ return tags
+
+
BIN  apps/api/handlers.pyc
Binary file not shown
9 apps/api/urls.py
@@ -0,0 +1,9 @@
+from django.conf.urls.defaults import *
+from piston.resource import Resource
+from handlers import TagHandler
+
+tag_handler = Resource(TagHandler)
+
+urlpatterns = patterns('',
+ url(r'^tags/?$', tag_handler),
+)
BIN  apps/api/urls.pyc
Binary file not shown
3  apps/django_ext/__init__.py
@@ -0,0 +1,3 @@
+from django.template import add_to_builtins
+
+add_to_builtins('django_ext.templatetags.smart_if')
BIN  apps/django_ext/__init__.pyc
Binary file not shown
0  apps/django_ext/admin.py
No changes.
BIN  apps/django_ext/admin.pyc
Binary file not shown
25 apps/django_ext/cache.py
@@ -0,0 +1,25 @@
+from django.core.cache import cache
+from django.utils.encoding import smart_str
+import inspect
+
+# Check if the cache backend supports min_compress_len. If so, add it.
+if cache._cache:
+ if 'min_compress_len' in inspect.getargspec(cache._cache.add)[0] and \
+ 'min_compress_len' in inspect.getargspec(cache._cache.set)[0]:
+ class CacheClass(cache.__class__):
+ def add(self, key, value, timeout=None, min_compress_len=150000):
+ if isinstance(value, unicode):
+ value = value.encode('utf-8')
+ # Allow infinite timeouts
+ if timeout is None:
+ timeout = self.default_timeout
+ return self._cache.add(smart_str(key), value, timeout, min_compress_len)
+
+ def set(self, key, value, timeout=None, min_compress_len=150000):
+ if isinstance(value, unicode):
+ value = value.encode('utf-8')
+ if timeout is None:
+ timeout = self.default_timeout
+ self._cache.set(smart_str(key), value, timeout, min_compress_len)
+
+ cache.__class__ = CacheClass
133 apps/django_ext/fields.py
@@ -0,0 +1,133 @@
+import functools
+from django.db.models.fields.related import ManyToManyField, ReverseManyRelatedObjectsDescriptor, ManyRelatedObjectsDescriptor
+from django.db.models.query import QuerySet
+from django.db.models import signals
+from django_ext.cache import cache
+from types import MethodType
+
+CACHE_DURATION = 60 * 30
+
+def invalidate_cache(obj, field):
+ cache.set(obj._get_cache_key(field=field), None, 5)
+
+def fix_where(where, modified=False):
+ def wrap_add(f):
+ @functools.wraps(f)
+ def add(self, *args, **kwargs):
+ """
+ Wraps django.db.models.sql.where.add to indicate that a new
+ 'where' condition has been added.
+ """
+ self.modified = True
+ return f(*args, **kwargs)
+ return add
+ where.modified = modified
+ where.add = MethodType(wrap_add(where.add), where, where.__class__)
+ return where
+
+
+def get_pk_list_query_set(superclass):
+ class PKListQuerySet(superclass):
+ """
+ QuerySet that, when unfiltered, fetches objects individually from
+ the datastore by pk.
+
+ The `pk_list` attribute is a list of primary keys for objects that
+ should be fetched.
+
+ """
+ def __init__(self, pk_list=[], from_cache=False, *args, **kwargs):
+ super(PKListQuerySet, self).__init__(*args, **kwargs)
+ self.pk_list = pk_list
+ self.from_cache = from_cache
+ self.query.where = fix_where(self.query.where)
+
+ def iterator(self):
+ if not self.query.where.modified:
+ for pk in self.pk_list:
+ yield self.model._default_manager.get(pk=pk)
+ else:
+ superiter = super(PKListQuerySet, self).iterator()
+ while True:
+ yield superiter.next()
+
+ def _clone(self, *args, **kwargs):
+ c = super(PKListQuerySet, self)._clone(*args, **kwargs)
+ c.query.where = fix_where(c.query.where, modified=self.query.where.modified)
+ c.pk_list = self.pk_list
+ c.from_cache = self.from_cache
+ return c
+ return PKListQuerySet
+
+
+def get_caching_related_manager(superclass, instance, field_name, related_name):
+ class CachingRelatedManager(superclass):
+ def all(self):
+ key = instance._get_cache_key(field=field_name)
+ qs = super(CachingRelatedManager, self).get_query_set()
+ PKListQuerySet = get_pk_list_query_set(qs.__class__)
+ qs = qs._clone(klass=PKListQuerySet)
+ pk_list = cache.get(key)
+ if pk_list is None:
+ pk_list = qs.values_list('pk', flat=True)
+ cache.add(key, pk_list, CACHE_DURATION)
+ else:
+ qs.from_cache = True
+ qs.pk_list = pk_list
+ return qs
+
+ def add(self, *objs):
+ super(CachingRelatedManager, self).add(*objs)
+ for obj in objs:
+ invalidate_cache(obj, related_name)
+ invalidate_cache(instance, field_name)
+
+ def remove(self, *objs):
+ super(CachingRelatedManager, self).remove(*objs)
+ for obj in objs:
+ invalidate_cache(obj, related_name)
+ invalidate_cache(instance, field_name)
+
+ def clear(self):
+ objs = list(self.all())
+ super(CachingRelatedManager, self).clear()
+ for obj in objs:
+ invalidate_cache(obj, related_name)
+ invalidate_cache(instance, field_name)
+ return CachingRelatedManager
+
+
+class CachingReverseManyRelatedObjectsDescriptor(ReverseManyRelatedObjectsDescriptor):
+ def __get__(self, instance, cls=None):
+ manager = super(CachingReverseManyRelatedObjectsDescriptor, self).__get__(instance, cls)
+
+ CachingRelatedManager = get_caching_related_manager(manager.__class__,
+ instance,
+ self.field.name,
+ self.field.rel.related_name)
+
+ manager.__class__ = CachingRelatedManager
+ return manager
+
+
+class CachingManyRelatedObjectsDescriptor(ManyRelatedObjectsDescriptor):
+ def __get__(self, instance, cls=None):
+ manager = super(CachingManyRelatedObjectsDescriptor, self).__get__(instance, cls)
+
+ CachingRelatedManager = get_caching_related_manager(manager.__class__,
+ instance,
+ self.related.get_accessor_name(),
+ self.related.field.name)
+
+ manager.__class__ = CachingRelatedManager
+ return manager
+
+
+class CachingManyToManyField(ManyToManyField):
+ def contribute_to_class(self, cls, name):
+ super(CachingManyToManyField, self).contribute_to_class(cls, name)
+ setattr(cls, self.name, CachingReverseManyRelatedObjectsDescriptor(self))
+
+ def contribute_to_related_class(self, cls, related):
+ super(CachingManyToManyField, self).contribute_to_related_class(cls, related)
+ setattr(cls, related.get_accessor_name(), CachingManyRelatedObjectsDescriptor(related))
1  apps/django_ext/management/__init__.py
@@ -0,0 +1 @@
+
BIN  apps/django_ext/management/__init__.pyc
Binary file not shown
0  apps/django_ext/management/commands/__init__.py
No changes.
20 apps/django_ext/management/commands/delete_contenttypes.py
@@ -0,0 +1,20 @@
+from django.core.management.base import NoArgsCommand
+from django.db import transaction
+
+class Command(NoArgsCommand):
+ help = "Delete contenttypes crapola"
+
+ def handle_noargs(self, **options):
+ from django.db import connection
+ print "Deleting content types and permissions"
+ transaction.commit_unless_managed()
+ transaction.enter_transaction_management()
+ transaction.managed(True)
+ cursor = connection.cursor()
+ cursor.execute("DELETE FROM django_content_type", [])
+ print cursor.fetchall()
+ cursor.execute("DELETE FROM auth_permission", [])
+ print cursor.fetchall()
+ transaction.commit()
+ transaction.leave_transaction_management()
+ print "Contenttypes deleted"
17 apps/django_ext/management/commands/flush_all_memcached.py
@@ -0,0 +1,17 @@
+from django.core.management.base import NoArgsCommand
+from django.db import transaction
+from django.conf import settings
+
+class Command(NoArgsCommand):
+ help = "Flushes memcached"
+
+ def handle_noargs(self, **options):
+ try:
+ import memcache
+ except ImportError:
+ return
+ if 'memcached' in settings.CACHE_BACKEND:
+ servers = settings.CACHE_BACKEND.replace('memcached://',
+ '').replace('/','').split(';')
+ mc = memcache.Client(servers, debug=0)
+ mc.flush_all()
87 apps/django_ext/managers.py
@@ -0,0 +1,87 @@
+from django.db import models
+from django.db.models import signals
+from django_ext.cache import cache
+from django.db.models.query import QuerySet
+
+CACHE_DURATION = 60 * 30
+
+def _cache_key(model, pk, field=None):
+ if field:
+ return "%s:%s.%s:%s" % (field, model._meta.app_label, model._meta.module_name, pk)
+ else:
+ return "%s.%s:%s" % (model._meta.app_label, model._meta.module_name, pk)
+
+def _get_cache_key(self, field=None):
+ return self._cache_key(self.pk, field)
+
+
+class CachingManager(models.Manager):
+ def __init__(self, use_for_related_fields=True, *args, **kwargs):
+ self.use_for_related_fields = use_for_related_fields
+ super(CachingManager, self).__init__(*args, **kwargs)
+
+ def get_query_set(self):
+ return CachingQuerySet(self.model)
+
+ def contribute_to_class(self, model, name):
+ signals.post_save.connect(self._post_save, sender=model)
+ signals.post_delete.connect(self._post_delete, sender=model)
+ setattr(model, '_cache_key', classmethod(_cache_key))
+ setattr(model, '_get_cache_key', _get_cache_key)
+ setattr(model, 'cache_key', property(_get_cache_key))
+ return super(CachingManager, self).contribute_to_class(model, name)
+
+ def _invalidate_cache(self, instance):
+ """
+ Explicitly set a None value instead of just deleting so we don't have any race
+ conditions where:
+ Thread 1 -> Cache miss, get object from DB
+ Thread 2 -> Object saved, deleted from cache
+ Thread 1 -> Store (stale) object fetched from DB in cache
+ Five second should be more than enough time to prevent this from happening for
+ a web app.
+ """
+ cache.set(instance.cache_key, None, 5)
+
+ def _post_save(self, instance, **kwargs):
+ self._invalidate_cache(instance)
+
+ def _post_delete(self, instance, **kwargs):
+ self._invalidate_cache(instance)
+
+
+class CachingQuerySet(QuerySet):
+ def iterator(self):
+ superiter = super(CachingQuerySet, self).iterator()
+ while True:
+ obj = superiter.next()
+ # Use cache.add instead of cache.set to prevent race conditions (see CachingManager)
+ cache.add(obj.cache_key, obj, CACHE_DURATION)
+ yield obj
+
+ def get(self, *args, **kwargs):
+ """
+ Checks the cache to see if there's a cached entry for this pk. If not, fetches
+ using super then stores the result in cache.
+
+ Most of the logic here was gathered from a careful reading of
+ ``django.db.models.sql.query.add_filter``
+ """
+ if self.query.where:
+ # If there is any other ``where`` filter on this QuerySet just call
+ # super. There will be a where clause if this QuerySet has already
+ # been filtered/cloned.
+ return super(CachingQuerySet, self).get(*args, **kwargs)
+
+ # Punt on anything more complicated than get by pk/id only...
+ if len(kwargs) == 1:
+ k = kwargs.keys()[0]
+ if k in ('pk', 'pk__exact', '%s' % self.model._meta.pk.attname,
+ '%s__exact' % self.model._meta.pk.attname):
+ obj = cache.get(self.model._cache_key(pk=kwargs.values()[0]))
+ if obj is not None:
+ obj.from_cache = True
+ return obj
+
+ # Calls self.iterator to fetch objects, storing object in cache.
+ return super(CachingQuerySet, self).get(*args, **kwargs)
48 apps/django_ext/middleware.py
@@ -0,0 +1,48 @@
+from django.db import connection
+from django.conf import settings
+import os
+
+def terminal_width():
+ """
+ Function to compute the terminal width.
+ WARNING: This is not my code, but I've been using it forever and
+ I don't remember where it came from.
+ """
+ width = 0
+ try:
+ import struct, fcntl, termios
+ s = struct.pack('HHHH', 0, 0, 0, 0)
+ x = fcntl.ioctl(1, termios.TIOCGWINSZ, s)
+ width = struct.unpack('HHHH', x)[1]
+ except:
+ pass
+ if width <= 0:
+ try:
+ width = int(os.environ['COLUMNS'])
+ except:
+ pass
+ if width <= 0:
+ width = 80
+ return width
+
+class SqlPrintingMiddleware(object):
+ """
+ Middleware which prints out a list of all SQL queries done
+ for each view that is processed. This is only useful for debugging.
+ """
+ def process_response(self, request, response):
+ indentation = 2
+ if len(connection.queries) > 0 and settings.DEBUG:
+ width = terminal_width()
+ total_time = 0.0
+ for query in connection.queries:
+ nice_sql = query['sql'].replace('"', '').replace(',',', ')
+ sql = "\033[1;31m[%s]\033[0m %s" % (query['time'], nice_sql)
+ total_time = total_time + float(query['time'])
+ while len(sql) > width-indentation:
+ print "%s%s" % (" "*indentation, sql[:width-indentation])
+ sql = sql[width-indentation:]
+ print "%s%s\n" % (" "*indentation, sql)
+ replace_tuple = (" "*indentation, str(total_time))
+ print "%s\033[1;32m[TOTAL TIME: %s seconds]\033[0m" % replace_tuple
+ return response
1  apps/django_ext/models.py
@@ -0,0 +1 @@
+
BIN  apps/django_ext/models.pyc
Binary file not shown
1  apps/django_ext/templatetags/__init__.py
@@ -0,0 +1 @@
+
BIN  apps/django_ext/templatetags/__init__.pyc
Binary file not shown
98 apps/django_ext/templatetags/fb.py
@@ -0,0 +1,98 @@
+from django import template
+from django.conf import settings
+
+from django.utils.encoding import smart_str
+
+register = template.Library()
+
+class URLNode(template.Node):
+ def __init__(self, view_name, args, kwargs, asvar):
+ self.view_name = view_name
+ self.args = args
+ self.kwargs = kwargs
+ self.asvar = asvar
+
+ def render(self, context):
+ from django.core.urlresolvers import reverse, NoReverseMatch
+ args = [arg.resolve(context) for arg in self.args]
+ kwargs = dict([(smart_str(k,'ascii'), v.resolve(context))
+ for k, v in self.kwargs.items()])
+
+ # Try to look up the URL twice: once given the view name, and again
+ # relative to what we guess is the "main" app. If they both fail,
+ # re-raise the NoReverseMatch unless we're using the
+ # {% url ... as var %} construct in which cause return nothing.
+ url = ''
+ try:
+ url = reverse(self.view_name, args=args, kwargs=kwargs)
+ except NoReverseMatch:
+ project_name = settings.SETTINGS_MODULE.split('.')[0]
+ try:
+ url = reverse(project_name + '.' + self.view_name,
+ args=args, kwargs=kwargs)
+ except NoReverseMatch:
+ if self.asvar is None:
+ raise
+
+ if self.asvar:
+ context[self.asvar] = settings.URL_PREFIX + url
+ return ''
+ else:
+ return settings.URL_PREFIX + url
+
+def fburl(parser, token):
+ """
+ Returns an absolute URL matching given view with its parameters.
+
+ This is a way to define links that aren't tied to a particular URL
+ configuration::
+
+ {% url path.to.some_view arg1,arg2,name1=value1 %}
+
+ The first argument is a path to a view. It can be an absolute python path
+ or just ``app_name.view_name`` without the project name if the view is
+ located inside the project. Other arguments are comma-separated values
+ that will be filled in place of positional and keyword arguments in the
+ URL. All arguments for the URL should be present.
+
+ For example if you have a view ``app_name.client`` taking client's id and
+ the corresponding line in a URLconf looks like this::
+
+ ('^client/(\d+)/$', 'app_name.client')
+
+ and this app's URLconf is included into the project's URLconf under some
+ path::
+
+ ('^clients/', include('project_name.app_name.urls'))
+
+ then in a template you can create a link for a certain client like this::
+
+ {% url app_name.client client.id %}
+
+ The URL will look like ``/clients/client/123/``.
+ """
+ bits = token.contents.split(' ')
+ if len(bits) < 2:
+ raise template.TemplateSyntaxError("'%s' takes at least one argument"
+ " (path to a view)" % bits[0])
+ viewname = bits[1]
+ args = []
+ kwargs = {}
+ asvar = None
+
+ if len(bits) > 2:
+ bits = iter(bits[2:])
+ for bit in bits:
+ if bit == 'as':
+ asvar = bits.next()
+ break
+ else:
+ for arg in bit.split(","):
+ if '=' in arg:
+ k, v = arg.split('=', 1)
+ k = k.strip()
+ kwargs[k] = parser.compile_filter(v)
+ elif arg:
+ args.append(parser.compile_filter(arg))
+ return URLNode(viewname, args, kwargs, asvar)
+fburl = register.tag(fburl)
BIN  apps/django_ext/templatetags/fb.pyc
Binary file not shown
104 apps/django_ext/templatetags/listutil.py
@@ -0,0 +1,104 @@
+"""
+Template tags for working with lists.
+
+You'll use these in templates thusly::
+
+ {% load listutil %}
+ {% for sublist in mylist|parition:"3" %}
+ {% for item in mylist %}
+ do something with {{ item }}
+ {% endfor %}
+ {% endfor %}
+"""
+
+from math import ceil
+
+from django import template
+
+register = template.Library()
+
+@register.filter
+def partition(thelist, n):
+ """
+ Break a list into ``n`` pieces. The last list may be larger than the rest if
+ the list doesn't break cleanly. That is::
+
+ >>> l = range(10)
+
+ >>> partition(l, 2)
+ [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]]
+
+ >>> partition(l, 3)
+ [[0, 1, 2], [3, 4, 5], [6, 7, 8, 9]]
+
+ >>> partition(l, 4)
+ [[0, 1], [2, 3], [4, 5], [6, 7, 8, 9]]
+
+ >>> partition(l, 5)
+ [[0, 1], [2, 3], [4, 5], [6, 7], [8, 9]]
+
+ """
+ try:
+ n = int(n)
+ thelist = list(thelist)
+ except (ValueError, TypeError):
+ return [thelist]
+ p = len(thelist) / n
+ return [thelist[p*i:p*(i+1)] for i in range(n - 1)] + [thelist[p*(i+1):]]
+register.filter(partition)
+
+
+@register.filter
+def partition_horizontal(thelist, n):
+ """
+ Break a list into ``n`` peices, but "horizontally." That is,
+ ``partition_horizontal(range(10), 3)`` gives::
+
+ [[1, 2, 3],
+ [4, 5, 6],
+ [7, 8, 9],
+ [10]]
+
+ Clear as mud?
+ """
+ try:
+ n = int(n)
+ thelist = list(thelist)
+ except (ValueError, TypeError):
+ return [thelist]
+ newlists = [list() for i in range(int(ceil(len(thelist) / float(n))))]
+ for i, val in enumerate(thelist):
+ newlists[i/n].append(val)
+ return newlists
+register.filter(partition_horizontal)
+
+
+@register.filter
+def partition_horizontal_twice(thelist, numbers):
+ """
+ numbers is split on a comma to n and n2.
+ Break a list into peices each peice alternating between n and n2 items long
+ ``partition_horizontal_twice(range(14), "3,4")`` gives::
+
+ [[0, 1, 2],
+ [3, 4, 5, 6],
+ [7, 8, 9],
+ [10, 11, 12, 13]]
+
+ Clear as mud?
+ """
+ n, n2 = numbers.split(',')
+ try:
+ n = int(n)
+ n2 = int(n2)
+ thelist = list(thelist)
+ except (ValueError, TypeError):
+ return [thelist]
+ newlists = []
+ while thelist:
+ newlists.append(thelist[:n])
+ thelist = thelist[n:]
+ newlists.append(thelist[:n2])
+ thelist = thelist[n2:]
+ return newlists
+register.filter(partition_horizontal_twice)
BIN  apps/django_ext/templatetags/listutil.pyc
Binary file not shown
333 apps/django_ext/templatetags/smart_if.py
@@ -0,0 +1,333 @@
+'''
+A smarter {% if %} tag for django templates.
+
+While retaining current Django functionality, it also handles equality,
+greater than and less than operators. Some common case examples::
+
+ {% if articles|length >= 5 %}...{% endif %}
+ {% if "ifnotequal tag" != "beautiful" %}...{% endif %}
+'''
+import unittest
+from django import template
+
+
+register = template.Library()
+
+
+#===============================================================================
+# Calculation objects
+#===============================================================================
+
+class BaseCalc(object):
+ def __init__(self, var1, var2=None, negate=False):
+ self.var1 = var1
+ self.var2 = var2
+ self.negate = negate
+
+ def resolve(self, context):
+ try:
+ var1, var2 = self.resolve_vars(context)
+ outcome = self.calculate(var1, var2)
+ except:
+ outcome = False
+ if self.negate:
+ return not outcome
+ return outcome
+
+ def resolve_vars(self, context):
+ var2 = self.var2 and self.var2.resolve(context)
+ return self.var1.resolve(context), var2
+
+ def calculate(self, var1, var2):
+ raise NotImplementedError()
+
+
+class Or(BaseCalc):
+ def calculate(self, var1, var2):
+ return var1 or var2
+
+
+class And(BaseCalc):
+ def calculate(self, var1, var2):
+ return var1 and var2
+
+
+class Equals(BaseCalc):
+ def calculate(self, var1, var2):
+ return var1 == var2
+
+
+class Greater(BaseCalc):
+ def calculate(self, var1, var2):
+ return var1 > var2
+
+
+class GreaterOrEqual(BaseCalc):
+ def calculate(self, var1, var2):
+ return var1 >= var2
+
+
+class In(BaseCalc):
+ def calculate(self, var1, var2):
+ return var1 in var2
+
+
+#===============================================================================
+# Tests
+#===============================================================================
+
+class TestVar(object):
+ """
+ A basic self-resolvable object similar to a Django template variable. Used
+ to assist with tests.
+ """
+ def __init__(self, value):
+ self.value = value
+
+ def resolve(self, context):
+ return self.value
+
+
+class SmartIfTests(unittest.TestCase):
+ def setUp(self):
+ self.true = TestVar(True)
+ self.false = TestVar(False)
+ self.high = TestVar(9000)
+ self.low = TestVar(1)
+
+ def assertCalc(self, calc, context=None):
+ """
+ Test a calculation is True, also checking the inverse "negate" case.
+ """
+ context = context or {}
+ self.assert_(calc.resolve(context))
+ calc.negate = not calc.negate
+ self.assertFalse(calc.resolve(context))
+
+ def assertCalcFalse(self, calc, context=None):
+ """
+ Test a calculation is False, also checking the inverse "negate" case.
+ """
+ context = context or {}
+ self.assertFalse(calc.resolve(context))
+ calc.negate = not calc.negate
+ self.assert_(calc.resolve(context))
+
+ def test_or(self):
+ self.assertCalc(Or(self.true))
+ self.assertCalcFalse(Or(self.false))
+ self.assertCalc(Or(self.true, self.true))
+ self.assertCalc(Or(self.true, self.false))
+ self.assertCalc(Or(self.false, self.true))
+ self.assertCalcFalse(Or(self.false, self.false))
+
+ def test_and(self):
+ self.assertCalc(And(self.true, self.true))
+ self.assertCalcFalse(And(self.true, self.false))
+ self.assertCalcFalse(And(self.false, self.true))
+ self.assertCalcFalse(And(self.false, self.false))
+
+ def test_equals(self):
+ self.assertCalc(Equals(self.low, self.low))
+ self.assertCalcFalse(Equals(self.low, self.high))
+
+ def test_greater(self):
+ self.assertCalc(Greater(self.high, self.low))
+ self.assertCalcFalse(Greater(self.low, self.low))
+ self.assertCalcFalse(Greater(self.low, self.high))
+
+ def test_greater_or_equal(self):
+ self.assertCalc(GreaterOrEqual(self.high, self.low))
+ self.assertCalc(GreaterOrEqual(self.low, self.low))
+ self.assertCalcFalse(GreaterOrEqual(self.low, self.high))
+
+ def test_in(self):
+ list_ = TestVar([1,2,3])
+ invalid_list = TestVar(None)
+ self.assertCalc(In(self.low, list_))
+ self.assertCalcFalse(In(self.low, invalid_list))
+
+ def test_parse_bits(self):
+ var = IfParser([True]).parse()
+ self.assert_(var.resolve({}))
+ var = IfParser([False]).parse()
+ self.assertFalse(var.resolve({}))
+
+ var = IfParser([False, 'or', True]).parse()
+ self.assert_(var.resolve({}))
+
+ var = IfParser([False, 'and', True]).parse()
+ self.assertFalse(var.resolve({}))
+
+ var = IfParser(['not', False, 'and', 'not', False]).parse()
+ self.assert_(var.resolve({}))
+
+ var = IfParser([1, '=', 1]).parse()
+ self.assert_(var.resolve({}))
+
+ var = IfParser([1, '!=', 1]).parse()
+ self.assertFalse(var.resolve({}))
+
+ var = IfParser([3, '>', 2]).parse()
+ self.assert_(var.resolve({}))
+
+ var = IfParser([1, '<', 2]).parse()
+ self.assert_(var.resolve({}))
+
+ var = IfParser([2, 'not', 'in', [2, 3]]).parse()
+ self.assertFalse(var.resolve({}))
+
+
+OPERATORS = {
+ '=': (Equals, True),
+ '==': (Equals, True),
+ '!=': (Equals, False),
+ '>': (Greater, True),
+ '>=': (GreaterOrEqual, True),
+ '<=': (Greater, False),
+ '<': (GreaterOrEqual, False),
+ 'or': (Or, True),
+ 'and': (And, True),
+ 'in': (In, True),
+}
+
+
+class IfParser(object):
+ error_class = ValueError
+
+ def __init__(self, tokens):
+ self.tokens = tokens
+
+ def _get_tokens(self):
+ return self._tokens
+
+ def _set_tokens(self, tokens):
+ self._tokens = tokens
+ self.len = len(tokens)
+ self.pos = 0
+
+ tokens = property(_get_tokens, _set_tokens)
+
+ def parse(self):
+ if self.at_end():
+ raise self.error_class('No variables provided.')
+ var1 = self.get_var()
+ while not self.at_end():
+ token = self.get_token()
+ if token == 'not':
+ if self.at_end():
+ raise self.error_class('No variable provided after "not".')
+ token = self.get_token()
+ negate = True
+ else:
+ negate = False
+ if token not in OPERATORS:
+ raise self.error_class('%s is not a valid operator.' % token)
+ if self.at_end():
+ raise self.error_class('No variable provided after "%s"' % token)
+ op, true = OPERATORS[token]
+ if not true:
+ negate = not negate
+ var2 = self.get_var()
+ var1 = op(var1, var2, negate=negate)
+ return var1
+
+ def get_token(self):
+ token = self.tokens[self.pos]
+ self.pos += 1
+ return token
+
+ def at_end(self):
+ return self.pos >= self.len
+
+ def create_var(self, value):
+ return TestVar(value)
+
+ def get_var(self):
+ token = self.get_token()
+ if token == 'not':
+ if self.at_end():
+ raise self.error_class('No variable provided after "not".')
+ token = self.get_token()
+ return Or(self.create_var(token), negate=True)
+ return self.create_var(token)
+
+
+#===============================================================================
+# Actual templatetag code.
+#===============================================================================
+
+class TemplateIfParser(IfParser):
+ error_class = template.TemplateSyntaxError
+
+ def __init__(self, parser, *args, **kwargs):
+ self.template_parser = parser
+ return super(TemplateIfParser, self).__init__(*args, **kwargs)
+
+ def create_var(self, value):
+ return self.template_parser.compile_filter(value)
+
+
+class SmartIfNode(template.Node):
+ def __init__(self, var, nodelist_true, nodelist_false=None):
+ self.nodelist_true, self.nodelist_false = nodelist_true, nodelist_false
+ self.var = var
+
+ def render(self, context):
+ if self.var.resolve(context):
+ return self.nodelist_true.render(context)
+ if self.nodelist_false:
+ return self.nodelist_false.render(context)
+ return ''
+
+ def __repr__(self):
+ return "<Smart If node>"
+
+ def __iter__(self):
+ for node in self.nodelist_true:
+ yield node
+ if self.nodelist_false:
+ for node in self.nodelist_false:
+ yield node
+
+ def get_nodes_by_type(self, nodetype):
+ nodes = []
+ if isinstance(self, nodetype):
+ nodes.append(self)
+ nodes.extend(self.nodelist_true.get_nodes_by_type(nodetype))
+ if self.nodelist_false:
+ nodes.extend(self.nodelist_false.get_nodes_by_type(nodetype))
+ return nodes
+
+
+@register.tag('if')
+def smart_if(parser, token):
+ '''
+ A smarter {% if %} tag for django templates.
+
+ While retaining current Django functionality, it also handles equality,
+ greater than and less than operators. Some common case examples::
+
+ {% if articles|length >= 5 %}...{% endif %}
+ {% if "ifnotequal tag" != "beautiful" %}...{% endif %}
+
+ Arguments and operators _must_ have a space between them, so
+ ``{% if 1>2 %}`` is not a valid smart if tag.
+
+ All supported operators are: ``or``, ``and``, ``in``, ``=`` (or ``==``),
+ ``!=``, ``>``, ``>=``, ``<`` and ``<=``.
+ '''
+ bits = token.split_contents()[1:]
+ var = TemplateIfParser(parser, bits).parse()
+ nodelist_true = parser.parse(('else', 'endif'))
+ token = parser.next_token()
+ if token.contents == 'else':
+ nodelist_false = parser.parse(('endif',))
+ parser.delete_first_token()
+ else:
+ nodelist_false = None
+ return SmartIfNode(var, nodelist_true, nodelist_false)
+
+
+if __name__ == '__main__':
+ unittest.main()
BIN  apps/django_ext/templatetags/smart_if.pyc
Binary file not shown
14 apps/django_ext/views.py
@@ -0,0 +1,14 @@
+from django.shortcuts import render_to_response
+from django.template import RequestContext
+
+clean = lambda i: '/'+'/'.join(i['location'].split('/')[3:])
+
+def sitemap(request, sitemaps):
+ maps = {}
+ for section, site in sitemaps.items():
+ if callable(site):
+ maps[section] = map(clean, site().get_urls())
+ else:
+ maps[section] = map(clean, site.get_urls())
+ return render_to_response('sitemap.html',{'maps':maps},
+ context_instance=RequestContext(request))
BIN  apps/django_ext/views.pyc
Binary file not shown
28 bin/ext-status.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+if [ "$VIRTUAL_ENV" = "" ]; then
+ echo "You must be in a virtualenv environment. Type workon for a list."
+ exit
+fi
+
+FILES=$VIRTUAL_ENV/src/*
+
+for f in $FILES
+do
+ if [ -d $f ]
+ then
+ cd $f
+ if [ -e .git ]
+ then
+ git status
+ elif [ -e .bzr ]
+ then
+ bzr status
+ elif [ -e .hg ]
+ then
+ hg status
+ elif [ -e .svn ]
+ then
+ svn status
+ fi
+ fi
+done
32 bin/install.sh
@@ -0,0 +1,32 @@
+#!/usr/bin/env bash
+
+if [ "$VIRTUAL_ENV" = "" ]; then
+ echo "You must be in a virtualenv environment. Type workon for a list."
+ exit
+fi
+
+PWD=`pwd`
+POSTACTIVATE=$VIRTUAL_ENV/bin/postactivate
+
+if [ -e externals ]; then
+ echo 'Externals link exists.'
+else
+ echo 'Creating link: externals.'
+ ln -s $VIRTUAL_ENV/src externals
+fi
+
+if [ -e $POSTACTIVATE ]; then
+ echo 'Postactivate script exists.'
+else
+ echo 'Creating postactivate script.'
+ cat > $POSTACTIVATE <<END
+ #!/bin/bash/
+ cd $PWD
+END
+ chmod +x $POSTACTIVATE
+fi
+
+pip install -U -r setup/requirements.txt
+rm -Rf src
+rm -Rf build
+rm -Rf pip-log.txt
28 bin/pull-ext.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+if [ "$VIRTUAL_ENV" = "" ]; then
+ echo "You must be in a virtualenv environment. Type workon for a list."
+ exit
+fi
+
+FILES=$VIRTUAL_ENV/src/*
+
+for f in $FILES
+do
+ if [ -d $f ]
+ then
+ cd $f
+ if [ -e .git ]
+ then
+ git pull origin master
+ elif [ -e .bzr ]
+ then
+ bzr merge
+ elif [ -e .hg ]
+ then
+ hg pull
+ elif [ -e .svn ]
+ then
+ svn up
+ fi
+ fi
+done
28 bin/push-ext.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+if [ "$VIRTUAL_ENV" = "" ]; then
+ echo "You must be in a virtualenv environment. Type workon for a list."
+ exit
+fi
+
+FILES=$VIRTUAL_ENV/src/*
+
+for f in $FILES
+do
+ if [ -d $f ]
+ then
+ cd $f
+ if [ -e .git ]
+ then
+ git push origin master
+ # elif [ -e .bzr ]
+ # then
+ # bzr merge
+ # elif [ -e .hg ]
+ # then
+ # hg pull
+ # elif [ -e .svn ]
+ # then
+ # svn up
+ fi
+ fi
+done
8 bin/upgrade.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+if [ "$VIRTUAL_ENV" = "" ]; then
+ echo "You must be in a virtualenv environment. Type workon for a list."
+ exit
+fi
+
+git pull origin master
+bin/pull-ext.sh
18 conf/EffervescentCollective.wsgi
@@ -0,0 +1,18 @@
+import os, sys, site
+
+site.addsitedir('/home/webdev/EffervescentCollective/.virtualenvs/EffervescentCollective/lib/python2.5/site-packages')
+
+PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
+sys.path.insert(0, os.path.join(PROJECT_ROOT,"apps"))
+sys.path.insert(0, os.path.join(PROJECT_ROOT,"lib"))
+sys.path.insert(0, PROJECT_ROOT)
+
+sys.stdout = sys.stderr
+
+if PROJECT_ROOT not in sys.path:
+ sys.path.append(PROJECT_ROOT)
+os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
+
+import django.core.handlers.wsgi
+
+application = django.core.handlers.wsgi.WSGIHandler()
35 conf/apache2-EffervescentCollective
@@ -0,0 +1,35 @@
+<VirtualHost *:80>
+ ServerAdmin webmaster@washingtontimes.com
+ ServerName EffervescentCollective
+ ServerAlias media-EffervescentCollective
+ DocumentRoot /var/code/EffervescentCollective/media
+
+ WSGIDaemonProcess EffervescentCollective user=webdev group=webdev processes=3 threads=1 maximum-requests=1000 python-path=/home/webdev/.virtualenvs/EffervescentCollective/lib/python2.5/site-packages
+ WSGIProcessGroup EffervescentCollective
+ WSGIScriptAlias / /var/code/EffervescentCollective/conf/EffervescentCollective.wsgi
+
+ Alias /media /var/code/EffervescentCollective/media
+ <Directory /var/code/EffervescentCollective/media>
+ SetHandler None
+ AddOutputFilterByType DEFLATE text/plain
+ AddOutputFilterByType DEFLATE text/xml
+ AddOutputFilterByType DEFLATE application/xhtml+xml
+ AddOutputFilterByType DEFLATE text/css
+ AddOutputFilterByType DEFLATE application/xml
+ AddOutputFilterByType DEFLATE image/svg+xml
+ AddOutputFilterByType DEFLATE application/rss+xml
+ AddOutputFilterByType DEFLATE application/atom_xml
+ AddOutputFilterByType DEFLATE application/x-javascript
+ AddOutputFilterByType DEFLATE application/x-httpd-php
+ AddOutputFilterByType DEFLATE application/x-httpd-fastphp
+ AddOutputFilterByType DEFLATE application/x-httpd-eruby
+ AddOutputFilterByType DEFLATE text/html
+ FileETag INode MTime Size
+ </Directory>
+
+ Alias /admin-media /home/webdev/.virtualenvs/EffervescentCollective/lib/python2.5/site-packages/django/contrib/admin/media
+ <Directory /home/webdev/.virtualenvs/EffervescentCollective/lib/python2.5/site-packages/django/contrib/admin/media>
+ SetHandler None
+ </Directory>
+
+</VirtualHost>
23 conf/nginx-EffervescentCollective
@@ -0,0 +1,23 @@
+#upstream webcluster {
+# server 127.0.0.1:8080;
+#}
+server {
+ listen 80;
+ server_name media-$$$$DEV_APP_HOST$$$$;
+ access_log /var/log/nginx/media-$$$$DEV_APP_HOST$$$$.access.log;
+ location / {
+ autoindex on;
+ index index.html;
+ root /var/code/EffervescentCollective/media;
+ expires max;
+ }
+}
+server {
+ listen 80;
+ server_name $$$$DEV_APP_HOST$$$$;
+ access_log /var/log/nginx/$$$$DEV_APP_HOST$$$$.access.log;
+ location / {
+ proxy_pass http://webcluster;
+ include /var/code/EffervescentCollective/conf/proxy.conf;
+ }
+}
13 conf/proxy.conf
@@ -0,0 +1,13 @@
+proxy_redirect off;
+proxy_set_header Host $host;
+proxy_set_header X-Real-IP $remote_addr;
+proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+client_max_body_size 10m;
+client_body_buffer_size 128k;
+proxy_connect_timeout 90;
+proxy_send_timeout 90;
+proxy_read_timeout 90;
+proxy_buffer_size 4k;
+proxy_buffers 4 32k;
+proxy_busy_buffers_size 64k;
+proxy_temp_file_write_size 64k;
BIN  dev.db
Binary file not shown
18 local_settings.py
@@ -0,0 +1,18 @@
+import os
+
+DEBUG = True
+TEMPLATE_DEBUG = DEBUG
+
+DATABASE_ENGINE = 'sqlite3'
+DATABASE_NAME = 'dev.db'
+DATABASE_USER = ''
+DATABASE_PASSWORD = ''
+DATABASE_HOST = ''
+DATABASE_PORT = ''
+
+MEDIA_URL = '/media/'
+MEDIA_ROOT = os.path.join(os.path.dirname(__file__),'media')
+ADMIN_MEDIA_PREFIX = '/admin-media/'
+
+
+CACHE_BACKEND = "dummy:///"
BIN  local_settings.pyc
Binary file not shown
18 manage.py
@@ -0,0 +1,18 @@
+#!/usr/bin/env python
+from django.core.management import execute_manager
+import os, sys
+
+PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))
+sys.path.insert(0, os.path.join(PROJECT_ROOT,"apps"))
+sys.path.insert(0, os.path.join(PROJECT_ROOT,"lib"))
+sys.path.insert(0, PROJECT_ROOT)
+
+try:
+ import settings # Assumed to be in the same directory.
+except ImportError:
+ import sys
+ sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
+ sys.exit(1)
+
+if __name__ == "__main__":
+ execute_manager(settings)
BIN  media/.DS_Store
Binary file not shown
BIN  media/Nautica05b/Thumbs.db
Binary file not shown
263 media/Nautica05b/contact.html
@@ -0,0 +1,263 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+
+<head>
+
+
+ <title>Nautica 05 Dark Contact Layout</title>
+
+ <meta http-equiv="content-type" content="application/xhtml+xml; charset=UTF-8" />
+ <meta name="author" content="fullahead.org - studio7designs.com" />
+ <meta name="description" content="Site Description Here" />
+ <meta name="keywords" content="keywords, here" />
+ <meta name="robots" content="index, follow, noarchive" />
+ <meta name="googlebot" content="noarchive" />
+
+ <link rel="stylesheet" type="text/css" href="css/layout.css" media="screen, projection, tv " />
+ <link rel="stylesheet" type="text/css" href="css/html.css" media="screen, projection, tv " />
+
+ <!-- CSS specific to current theme -->
+ <link rel="stylesheet" type="text/css" href="css/light.css" title="light" media="screen, projection, tv " />
+ <link rel="alternate stylesheet" type="text/css" href="css/dark.css" title="dark" media="screen, projection, tv " />
+
+</head>
+
+<body>
+
+<!-- #content: holds all except site footer - causes footer to stick to bottom -->
+<div id="content">
+
+ <!-- #header: holds the logo and top links -->
+ <div id="header" class="width">
+
+ <img src="images/logo.gif" alt="Your logo goes here"/>
+
+ <ul>
+ <li><a href="index.html">Back to Main page</a></li>
+ <li><a href="">About us</a></li>
+ <li><a href="">Streaming Video</a></li>
+ <li><a href="" class="last">RSS Feeds</a></li>
+ </ul>
+
+ </div>
+ <!-- #header end -->
+
+
+ <!-- #headerImg: holds the main header image or flash -->
+ <div id="headerImg" class="width"></div>
+
+
+
+
+ <!-- #menu: the main large box site menu -->
+ <div id="menu" class="width">
+
+ <ul>
+ <li>
+ <a href="onecol.html" onfocus="blur()">
+ <span class="title ">One Column Layout</span>
+ <span class="desc">View the included layout</span> </a> </li>
+ <li>
+ <a href="twocol_a.html" class="forum" onfocus="blur()">
+ <span class="title ">Two Column Layout A</span>
+ <span class="desc style3">View the included layout</span> </a> </li>
+ <li>
+ <a href="twocol_b.html" onfocus="blur()">
+ <span class="title ">Two Column Layout B</span>
+ <span class="desc">View the included layout</span>
+ </a>
+ </li>
+ <li>
+ <a href="contact.html" onfocus="blur()">
+ <span class="title ">Contact Us Layout</span>
+ <span class="desc">View the included layout</span>
+ </a>
+ </li>
+ </ul>
+
+ </div>
+ <!-- #menu end -->
+
+
+
+ <!-- #page: holds the page content -->
+ <div id="page">
+
+
+ <!-- #columns: holds the columns of the page -->
+ <div id="columns" class="widthPad">
+
+
+ <!-- Left column -->
+ <div class="floatLeft width25 lightBlueBg horzPad">
+
+ <h2>Details</h2>
+
+ <p>
+ Please make sure your info is correct, otherwise we can't get back to you.
+ </p>
+
+ <ul>
+ <li>613.555.5555</li>
+ <li><a href="">info@yourname.com</a></li>
+ </ul>
+
+ <p>
+ Nulla commodo. In nunc justo, mollis sed, gravida at, aliquam sit amet, urna. Nulla commodo. In pharetra justo eget turpis. Nulla commodo.
+ </p>
+
+
+
+ </div>
+ <!-- Left column end -->
+
+
+ <!-- Right column -->
+ <div class="floatRight width73">
+
+ <h1>Contact <span class="dark">Us</span></h1>
+
+ <p>
+ Nulla commodo. In nunc justo, mollis sed, gravida at, aliquam sit amet, urna. Nulla commodo. In pharetra justo eget turpis. Nulla commodo. In pharetra justo eget turpis. In nunc justo, mollis sed, gravida at, <a href="">aliquam sit</a> amet, urna.
+ </p>
+
+ <form id="contact" action="" method="post" onsubmit="return configForm(this);" style="position: relative; z-index: 1;">
+
+
+
+ <p>
+ <input type="text" name="name" value="Name" class="width75" onfocus="clearValue(this, 'Name');" onblur="fillValue(this, 'Name');"/>
+ </p>
+
+ <p>
+ <input type="text" name="email" value="E-mail" class="width75" onfocus="clearValue(this, 'E-mail');" onblur="fillValue(this, 'E-mail');"/>
+ </p>
+
+ <p>
+ <input type="text" name="subject" value="Subject" class="width75" onfocus="clearValue(this, 'Subject');" onblur="fillValue(this, 'Subject');"/>
+ </p>
+
+ <p>
+ <textarea name="message" rows="5" cols="80" onfocus="clearValue(this, 'Message');" onblur="fillValue(this, 'Message');">Message</textarea>
+ </p>
+
+ <p>
+ <input type="submit" value="SEND" class="button" />
+ <input type="reset" value="RESET" class="button" />
+ </p>
+
+ <p>&nbsp;
+
+ </p>
+
+
+
+ <h1>Example Form <span class="dark">Elements</span></h1>
+
+
+
+ <p>
+ <label>Input Heading</label>
+ <input type="text" name="input1" class="width50"/>
+ </p>
+
+ <p>
+ <label>Input Heading</label>
+ <input type="text" name="input2" class="width50"/>
+ </p>
+
+ <p>
+ <label>Textarea Heading</label>
+ <textarea name="textarea" rows="5" cols="60"></textarea>
+ </p>
+
+ <p>
+ <label>Select Heading</label>
+ <select name="select">
+ <option value="1">Value One</option>
+ <option value="2">Value Two</option>
+ </select>
+ </p>
+
+
+
+
+ <p>
+ <label>Radio Button Group</label>
+ <input type="radio" name="radioGroup" value="1" class="radio"/> One
+ <input type="radio" name="radioGroup" value="2" class="radio"/> Two
+ <input type="radio" name="radioGroup" value="3" class="radio"/> Three
+ <input type="radio" name="radioGroup" value="4" class="radio"/> Four
+ </p>
+
+
+ <p>
+ <label>Checkbox Group</label>
+ <input type="checkbox" name="checkGroup" value="1" class="radio"/> One
+ <input type="checkbox" name="checkGroup" value="2" class="radio"/> Two
+ <input type="checkbox" name="checkGroup" value="3" class="radio"/> Three
+ <input type="checkbox" name="checkGroup" value="4" class="radio"/> Four
+ </p>
+
+
+ <div class="lightBlueBg">
+
+ <h2>Different Style Checkbox Group</h2>
+ <p>
+ <input type="checkbox" name="checkGroup" value="1" class="radio"/> A Choice<br/>
+ <input type="checkbox" name="checkGroup" value="2" class="radio"/> Another Choice<br/>
+ <input type="checkbox" name="checkGroup" value="3" class="radio"/> Maybe this is a better choice<br/>
+ <input type="checkbox" name="checkGroup" value="4" class="radio"/> Other <input type="text" name="other" class="width33"/>
+ </p>
+
+ </div>
+
+
+
+ </form>
+
+
+
+
+ </div>
+ <!-- Right column end -->
+
+
+ </div>
+ <!-- #columns end -->
+
+ </div>
+ <!-- #page end -->
+
+</div>
+<!-- #content end -->
+
+
+
+
+<!-- #footer: holds the site footer (logo and links) -->
+<div id="footer">
+
+ <!-- #bg: applies the site width and footer background -->
+ <div id="bg" class="width">
+
+ <img src="images/logo.gif" alt="Your logo goes here"/>
+
+ <ul>
+ <li><a href="">Sitemap</a></li>
+ <li><a href="">Register</a></li>
+ <li><a href="http://www.opensourcetemplates.org">opensourcetemplates.org</a></li>
+ <li><a href="http://www.studio7designs.com" class="last">studio7designs.com</a></li>
+ </ul>
+
+ </div>
+ <!-- #bg end -->
+
+</div>
+<!-- #footer end -->
+
+</body>
+
+</html>
203 media/Nautica05b/css/html.css
@@ -0,0 +1,203 @@
+/**************************************************************
+ Visit studio7designs.com for more layouts and downloads for this template!
+ **************************************************************/
+
+/*********************************************************
+ HTML Elements
+ *********************************************************/
+
+html,
+body {
+ height: 100%;
+}
+
+body {
+ margin: 0;
+ padding: 0;
+ text-align: center;
+ background: url(../images/bg/light_body.gif) repeat-y top center;
+ font: 400 0.7em verdana, arial, sans-serif;
+ line-height: 170%;
+
+ color: #555;
+}
+
+
+/* Headers */
+h1, h2, h3, h4, h5, h6 {
+ margin: 0 0 10px 0;
+ padding: 0;
+}
+
+
+h1 {
+ padding-bottom: 0.2em;
+
+ font: 400 1.6em arial, sans-serif;
+ color: #536C71;
+ border-bottom: 12px solid #ddd;
+}
+
+h2 {
+ font-size: 1.2em;
+ color: #586B7A;
+}
+
+h3 {
+ text-transform: uppercase;
+ font-size: 0.9em;
+ color: #5D6F73;
+}
+
+h4 {
+ font-size: 0.85em;
+}
+
+h5 {
+ font-size: 0.8em;
+}
+
+
+/* Needed to horizontally pad in a coloured container */
+.horzPad h1,
+.horzPad h2,
+.horzPad h3,
+.horzPad h4,
+.horzPad h5,
+.horzPad p {
+ padding-left: 5px;
+ padding-right: 5px;
+}
+
+
+/* Links */
+a {
+ text-decoration: none;
+ color: #3B5D77;
+}
+
+a:hover {
+ color: #668FA3;
+}
+
+a img {
+ border: 0;
+}
+
+a img.border {
+ border: 1px solid #000;
+}
+
+a:hover img.border {
+ /* Fixes IE bug - IE doesn't correctly apply the style on a:hover so need to mask it */
+ border: 1px solid #668FA3 !important;
+ border: 1px solid #FC3307;
+}
+
+
+
+/* Images */
+img.floatRight {
+ margin: 5px 0 10px 10px;
+}
+
+img.floatLeft {
+ margin: 5px 10px 10px 0;
+}
+
+
+
+/* Lists */
+ul li {
+ list-style-image: url(../images/bg/submenu1.gif);
+}
+
+ol li {
+ font-weight: bold;
+ color: #668FA3;
+}
+
+ol li span {
+ font-weight: normal;
+ color: #444;
+}
+
+
+
+/* Blockquote */
+blockquote {
+ margin: 0;
+ padding: 0 20px;
+ background: #eee;
+ border-top: 1px solid #ccc;
+ border-bottom: 1px solid #ccc;
+}
+
+
+
+/**************************************************************
+ Form Elements
+ **************************************************************/
+
+form {
+ padding: 0;
+ margin: 0;
+}
+
+/* If you're finding the input elements get pushed down, increase the width */
+label {
+ float: left;
+ width: 25%;
+ vertical-align: top;
+}
+
+input,
+textarea,
+select {
+ padding: 1px;
+ font: 400 1em verdana, sans-serif;
+ color: #999;
+ background: #EEE;
+ border: 1px solid #CCC;
+}
+
+input:focus,
+input:hover,
+textarea:focus,
+textarea:hover,
+select:focus,
+select:hover {
+ color: #000;
+ background: #E7F1F3;
+ border: 1px solid #888;
+}
+
+input.noBorder,
+input:focus.noBorder,
+input:hover.noBorder {
+ padding: 0;
+ border: 0;
+}
+
+input.button {
+ padding: 2px 5px;
+
+ font: 400 0.9em verdana, serif;
+ cursor: pointer;
+
+ color: #fff;
+ background: #ccc;
+ border-width: 1px;
+ border-style: solid;
+ border-color: #888 #888 #8880 #888;
+}
+
+input.radio {
+ background: none;
+ border: 0px;
+}
+
+
+
+
+
551 media/Nautica05b/css/layout.css
@@ -0,0 +1,551 @@
+/**************************************************************
+ Visit studio7designs.com for more layouts and downloads for this template!
+ **************************************************************/
+
+/**************************************************************
+ All page content except for footer
+ **************************************************************/
+
+#content {
+ position: relative;
+ height: auto !important;
+ height: 100%;
+ min-height: 100%;
+}
+
+
+
+/**************************************************************
+ Topbar with newsletter form and theme change buttons
+ **************************************************************/
+
+#topbar {
+ float: left;
+ width: 100%;
+ padding: 0.6em 0;
+
+ font-size: 0.9em;
+ text-transform: uppercase;
+
+ color: #CFD9DB;
+ background: #FFF url(../images/bg/topbar.gif) repeat-x bottom left;
+}
+
+
+
+/**************************************************************
+ Top menu and logo
+ **************************************************************/
+
+#header {
+ clear: both;
+ position: relative;
+ height: 5em;
+ margin: 0 auto;
+ background: #48525B url(../images/bg/header.gif) repeat-x bottom left;
+ border-bottom: 2px solid #48525B;
+ background-color: #48525B;
+}
+
+
+#header img {
+ position: absolute;
+ top: 5%;
+ left: 10px;
+}
+
+#header ul {
+ margin: 3.5em 1em 0 0 !important;
+ margin: 3.5em 0.5em 0 0;
+ padding: 0;
+ float: right;
+}
+
+#header ul li {
+ display: inline;
+ list-style: none;
+}
+
+#header ul li a {
+ float: left;
+ padding: 0 1em;
+
+ font: 400 1.1em arial, sans-serif;
+ letter-spacing: 0.1em;
+ line-height: 0.8em !important;
+ line-height: 1em;
+
+ color: #cccccc;
+ border-right: 1px solid #4D5760;
+}
+
+#header ul li a.last {
+ padding-right: 0;
+ border-right: 0;
+}
+
+#header ul li a:hover {
+ color: #F26A92;
+}
+
+
+
+/**************************************************************
+ Header Image/Flash Movie
+ **************************************************************/
+
+#headerImg {
+ margin: 0 auto;
+ height: 250px;
+ background: url(../images/bg/header_image2.jpg) no-repeat top left;
+}
+
+
+
+
+
+/**************************************************************
+ Top Block Menu
+ **************************************************************/
+
+#menu {
+ margin: 0 auto;
+}
+
+#menu ul {
+ width: 100%;
+ float: left;
+ margin: 0;
+ padding: 0;
+
+ text-align: left;
+ background: #000 url(../images/bg/menu.gif) repeat-x top left;
+}
+
+#menu ul li {
+ display: inline;
+ margin: 0;
+ padding: 0;
+ list-style: none;
+}
+
+#menu ul li a {
+ float: left;
+ width: 25%;
+ height: 4.5em;
+
+ font: 400 1.2em arial, sans-serif;
+ letter-spacing: 0.1em;
+
+ color: #fff;
+
+ border-top: 7px solid #000;
+ border-bottom: 15px solid #FFF;
+}
+
+#menu ul li a span {
+ display: block;
+ padding: 2px 7px;
+}
+
+
+#menu ul li a span.desc {
+ font-size: 0.8em;
+ color: #8C8D94;
+}
+
+
+#menu ul li a:hover,
+#menu ul li a.here {
+ background: #000;
+ border-top: 7px solid #F06890;
+}
+
+#menu ul li a:hover span.desc,
+#menu ul li a.here span.desc {
+ color: #FFF;
+}
+
+
+/* Top menu icons */
+#menu ul li a span.speaker {
+ padding-left: 22px;
+ background: url(../images/icons/speaker.gif) no-repeat 5px 50%;
+}
+
+#menu ul li a:hover span.speaker {
+ background: url(../images/icons/speaker_on.gif) no-repeat 5px 50%;
+}
+
+#menu ul li a span.bubble {
+ padding-left: 24px;
+ background: url(../images/icons/bubble.gif) no-repeat 4px 4px;
+}
+
+#menu ul li a:hover span.bubble {
+ background: url(../images/icons/bubble_on.gif) no-repeat 4px 4px;
+}
+
+#menu ul li a span.heart {
+ padding-left: 20px;
+ background: url(../images/icons/heart.gif) no-repeat 3px 50%;
+}
+
+#menu ul li a:hover span.heart {
+ background: url(../images/icons/heart_on.gif) no-repeat 3px 50%;
+}
+
+
+#menu ul li a span.dollar {
+ padding-left: 20px;
+ background: url(../images/icons/dollar.gif) no-repeat 4px 50%;
+}
+
+#menu ul li a:hover span.dollar {
+ background: url(../images/icons/dollar_on.gif) no-repeat 4px 50%;
+}
+
+
+
+
+/**************************************************************
+ Page Content
+ **************************************************************/
+
+#page {
+ clear: both;
+ float: left;
+ width: 100%;
+ margin-bottom: 6em;
+ text-align: left;
+}
+
+#columns {
+ margin: 0 auto;
+}
+
+
+/* Column widths */
+.width {
+ width: 776px;
+}
+
+.widthPad {
+ width: 746px;
+}
+
+.width25 {
+ width: 24%;