Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Adding ability in the editor for a page to have multiple streams.

JS is getting fairly complex so:
* Integrated Juicer and RequireJS
* Re-organized code into widgets (html, css, and js files)
  • Loading branch information...
commit 73c818eb79e284bb5f56247813241c1465e203ce 1 parent c8227ec
@ozten authored
Showing with 12,517 additions and 580 deletions.
  1. +5 −1 apps/lifestream/models.py
  2. +19 −4 apps/patchouli_auth/preferences.py
  3. +2 −3 apps/patchouli_auth/templates/index.html
  4. +6 −6 apps/patchouli_auth/views.py
  5. +1 −3 apps/streamManager/templates/feed_editor.html
  6. +20 −18 apps/streamManager/templates/stream_editor.html
  7. +1 −1  apps/streamManager/templates/template.html
  8. +5 −0 apps/streamManager/templates/widgets/add_stream_button.html
  9. +1 −0  apps/streamManager/templates/widgets/delete_stream_panel.html
  10. +3 −1 apps/streamManager/urls.py
  11. +54 −14 apps/streamManager/views.py
  12. +5 −0 bin/dev_merge.sh
  13. +5 −0 bin/merge.sh
  14. +2 −0  bin/verify.sh
  15. +52 −0 docs/database/migrations/0.6-add-webpage-to-stream.py
  16. +143 −0 static/css/editor-stylo-kitchen-sink.css
  17. +6 −149 static/css/editor-stylo.css
  18. +229 −0 static/css/editor-stylo.min.css
  19. +145 −0 static/css/general-site-kitchen-sink.css
  20. +2 −200 static/css/general-site.css
  21. +204 −0 static/css/general-site.min.css
  22. +52 −0 static/css/lib/reset.css
  23. +8 −0 static/css/widgets/add_stream_button.css
  24. +10 −0 static/css/widgets/buttons.css
  25. +7 −0 static/css/widgets/delete_stream_panel.css
  26. +4 −0 static/css/widgets/footer.css
  27. +33 −0 static/js/README.markdown
  28. +20 −17 static/js/behavior.js
  29. +32 −0 static/js/effects/checkbox_disable_panel.js
  30. +20 −37 static/js/feed_editor.js
  31. +1,632 −0 static/js/feed_editor.min.js
  32. 0  static/js/{ → lib}/jquery-1.4.1.min.js
  33. +6,241 −0 static/js/lib/jquery-1.4.2.js
  34. 0  static/js/{ → lib}/jquery-1.4.min.js
  35. 0  static/js/{ → lib}/jquery.scrollTo-min.js
  36. 0  static/js/{ → lib}/jquery.serialScroll-min.js
  37. +1,307 −0 static/js/lib/require.js
  38. +93 −126 static/js/stream_editor.js
  39. +1,848 −0 static/js/stream_editor.min.js
  40. +30 −0 static/js/widgets/#stream_editor_stream_panel.js#
  41. +1 −0  static/js/widgets/.#stream_editor_stream_panel.js
  42. +56 −0 static/js/widgets/add_feed_panel.js
  43. +37 −0 static/js/widgets/add_stream_button.js
  44. +29 −0 static/js/widgets/delete_stream_panel.js
  45. +20 −0 static/js/widgets/feed_editor_delete_feed.js
  46. +30 −0 static/js/widgets/stream_editor_stream_panel.js
  47. +50 −0 static/js/widgets/stream_preview.js
  48. +47 −0 static/js/widgets/streams/show_hide.js
View
6 apps/lifestream/models.py
@@ -31,6 +31,7 @@ class Stream(models.Model):
""" A stream is composed of Feeds. """
user = models.ForeignKey(User)
name = models.CharField(max_length=140)
+ webpage = models.ForeignKey(Webpage) # Added in 0.6 migration
# StreamConfig
config = models.TextField()
# StreamEditList
@@ -146,7 +147,10 @@ def _recent_entries(user, stream, feed_id, count=150, only_visible=True):
query = (Entry.objects.order_by('-last_published_date')
.filter(feed__user=user,
feed__url_hash=a_feed_id,
- feed__streams__id = stream_id))
+# TODO .... Why constrain by Stream? We want to reuse feeds, right?
+# the cron somehow repairs the links betwee a feed and all the streams it lives in
+ feed__streams__id = stream_id
+))
# Visible is special, we want to see hidden items in the editor
if only_visible:
query = query.filter(streamentry__visible=True)
View
23 apps/patchouli_auth/preferences.py
@@ -3,6 +3,7 @@
import simplejson
import patchouli_auth.models
+import lifestream.models
def getPreferences(user):
# Put all known preferences here...
@@ -60,16 +61,30 @@ def getPageProperties(page):
'processing_js': '',
- 'stream_names': []
+ 'stream_ids': []
}
existingProps = simplejson.loads(page.config)
pageProps.update(existingProps)
- if 0 == len(pageProps['stream_names']):
- # This should be page.id instead
- pageProps['stream_names'] = [page.name]
+ if 0 == len(pageProps['stream_ids']):
+ # Repair and save
+ streams = (lifestream.models.Stream.objects.all()
+ .order_by('id')
+ .filter(webpage__id = page.id))
+ for stream in streams:
+ pageProps['stream_ids'].append(stream.id)
+ savePageOrStreamProperties(page, pageProps)
return pageProps
+def removeStreamFromPage(webpage, stream):
+ props = getPageProperties(webpage)
+ if stream.id in props['stream_ids']:
+ props['stream_ids'].remove(stream.id)
+ savePageOrStreamProperties(webpage, props)
+ stream.delete()
+ return True
+ return False
+
def savePageOrStreamProperties(model, properties):
""" Given a Page or Stream model, persists the
properties """
View
5 apps/patchouli_auth/templates/index.html
@@ -44,6 +44,5 @@ <h1 class="logo"><a href="/"><strong><code>sudo</code>Social</strong></a></h1>
{% endif %}
</div><!-- /#content -->
-<script src="/static/js/jquery-1.4.1.min.js" type="text/javascript"></script>
-<script src="/static/js/stream_editor.js" type="text/javascript"></script>
-{% endblock %}
+<script src="/static/js/stream_editor.min.js" type="text/javascript"></script>
+{% endblock %}
View
12 apps/patchouli_auth/views.py
@@ -22,8 +22,8 @@ def account_checkauth(request):
if request.user.is_authenticated():
manageUrl = "/manage/account/%s" % request.user.username.encode('utf-8')
try:
- stream = lifestream.models.Stream.objects.get(user__exact=request.user)
- encoded_url = django.utils.encoding.iri_to_uri(manageUrl)
+ _ = lifestream.models.Stream.objects.all().filter(user=request.user)
+ encoded_url = django.utils.encoding.iri_to_uri(manageUrl)
resp = django.http.HttpResponseRedirect(encoded_url)
except lifestream.models.Stream.DoesNotExist:
log.debug("Account didn't exist")
@@ -66,7 +66,7 @@ def profile(request, username):
return render_to_response('index.html',
{ 'show_delete': True,
- 'css_url': '/static/css/general-site.css',
+ 'css_url': '/static/css/general-site.min.css',
'username': request.user.username,
'email': request.user.email,
@@ -92,7 +92,7 @@ def delete_profile(request, username):
else:
return render_to_response('confirm_delete.html',
{
- 'css_url': '/static/css/general-site.css',
+ 'css_url': '/static/css/general-site.min.css',
'lang_dir': 'LTR',
'page_lang': 'en',
},
@@ -135,7 +135,7 @@ def confirm_profile(request):
avatar_url = "http://www.gravatar.com/avatar/%s.jpg?d=monsterid&s=80" % gravatarHash
return render_to_response('index.html',
- { 'css_url': '/static/css/general-site.css',
+ { 'css_url': '/static/css/general-site.min.css',
'username': request.user.username,
'email': request.user.email,
@@ -172,4 +172,4 @@ def session_status(request):
amstatus = "none;"
resp = django.http.HttpResponse("X-Account-Managment-Status will be %s" % amstatus)
resp['X-Account-Management-Status'] = amstatus
- return resp
+ return resp
View
4 apps/streamManager/templates/feed_editor.html
@@ -46,7 +46,5 @@
</div><!-- #feed_preview -->
</div><!-- #feed_panel -->
- <script type="text/javascript" src="/static/js/jquery-1.4.1.min.js"></script>
- <script src="/static/js/feed_editor.js" type="text/javascript"></script>
- <script src="/static/js/stream_editor.js" type="text/javascript"></script>
+ <script src="/static/js/feed_editor.min.js" type="text/javascript"></script>
{% endblock %}
View
38 apps/streamManager/templates/stream_editor.html
@@ -6,37 +6,41 @@
<li>New Page</li>
<li>All Pages</li>
</ul>
-
+ {% include 'widgets/add_stream_button.html' %}
{% endblock %}
{% block content %}
<h1>Stream Editor</h1>
<div id="stream-editor-panel" lang="{{page_props.page_lang}}" dir="{{page_props.page_lang_dir}}">
<ul class="tabs">
- <li id="edit-stream" class="tab editor"><a href="#">Edit </a>{% if first_stream %}<strong id="stream{{first_stream.id}}" class="stream-name">{{first_stream.name}}</strong> Stream Page{% endif %}</li>
+ <!-- TODO: Is stream1 used ? (first_stream.id). Change to page.id ? -->
+ <li id="edit-stream" class="tab editor"><a href="#">Edit </a>{% if first_stream %}<strong id="stream{{first_stream.id}}" class="page-name">{{page_name}}</strong> Stream Page{% endif %}</li>
<li id="design-stream" class="tab design xactive-tab"><a href="#">Design</a></li>
<li id="page-widgets" class="tab pagewidget active-tab"><a href="#">Page Widgets</a></li>
- {% if first_stream %}<li><a id="preview" href="/u/{{username}}/s/{{first_stream.name}}" target="_new" title="View your currenly published Stream in a new window">View</a></li>{% endif %}
+ {% if first_stream %}<li><a id="preview" href="/u/{{username}}/s/{{page_name}}" target="_new" title="View your currenly published Stream in a new window">View</a></li>{% endif %}
</ul>
<!--------------------- Edit Stream Panel ------------------------->
<div id="edit-stream-panel" class="panel">
+
+
{% for stream in streams %}
<div class="streams-panel"><!-- streams panel contains the metadata and preview -->
<div class="stream-metadata-panel">
<h2 class="new-feed">Add A Source</h2>
<p>Paste in the Url to a website or any Atom or RSS feed <img src="/static/img/feed-icon-14x14.png" width="14" height="14" alt="Feed Icon" />.</p>
- <form id="add-url-form" action="/manage/urls/{{request.user.username}}" method="post">
- <p><label for="id_url">Url:</label> <input id="id_url" type="text" name="url" maxlength="2048" /></p>
+ <form class="add-url-form" action="/manage/urls/{{request.user.username}}" method="post">
+ <p><label for="id_url">Url:</label> <input class="id_url" type="text" name="url" maxlength="2048" /></p>
<p>
<label for="id_streams">Streams:</label>
- <input type="hidden" name="streams" id="id_streams" value="{{stream.name}}" /></p>
+ <!-- TODO test add feed form -->
+ <input type="hidden" name="streams" class="id_streams" value="{{stream.id}}" /></p>
<input type="submit" value="Add Feed" />
</p>
</form>
<h2>Stream Sources</h2>
- <ul id="user_streams">
+ <ul class="user_streams">
{% for feed in stream.feeds %}
<li>
<a href="{{ feed.url }}" class="stream-feed-source"> {% if feed.title %}{{ feed.title }}{% else %} {{ feed.url }} {% endif %}</a>
@@ -44,23 +48,22 @@ <h2 class="new-feed">Add A Source</h2>
<a href="/manage/account/{{username}}/stream/{{stream.id}}/feed/{{feed.pk}}" class="button">Edit</a>
</li>
{% empty %}
- <li id="no-stream-feed-blurb"><a href="#" class="stream-feed-source"></a><a href="{{ feed.pk }}" class="feed-delete" title="Delete this feed."></a>You have no stream sources, add a new feed.</li>
+ <li class="no-stream-feed-blurb"><a href="#" class="stream-feed-source"></a>You have no stream sources, add a new feed.
+ <!-- Empty case we have to add the stream and feed ids... and show -->
+ <a href="/manage/account/{{username}}/stream/" class="button" style="display:none">Edit</a></li>
{% endfor %}
- <li id="base-stream-feed-link" style="display:none"><a href="{{ feed.url }}" class="stream-feed-source">sample</a>
- <div class="feed-entries-visible-default shown" title="New Items are shown automatically"></div>
- <a href="#" class="feed-edit" title="Edit this feed.">Edit</a></li>
+ <li class="base-stream-feed-link" style="display:none"><a href="{{ feed.url }}" class="stream-feed-source">sample</a>
+ <a href="#" class="feed-edit button" title="Edit this feed.">Edit</a></li>
</ul>
- <p>After 5 minutes, Feed entries should start appearing in <a href="/u/{{username}}/s/{{stream.name}}" target="_new" title="View your currenly published Stream in a new window">your stream.</a></p>
+ <p>After 5 minutes, Feed entries should start appearing in <a href="/u/{{username}}/s/{{page_name}}" target="_new" title="View your currenly published Stream in a new window">your stream.</a></p>
+ {% include 'widgets/delete_stream_panel.html' %}
</div><!-- /.stream-metadata-panel -->
<div class="stream-preview-panel">
{% include 'feed_editor_preview.html' %}
</div><!-- /.stream-preview-panel -->
</div><!-- /.streams-panel -->
{% endfor %}
- <!-- div class="add-stream-panel">
- <p class="callout">A page can have multiple streams. <a href="#todo" class="button">Add Another Stream</a>.</p>
- </div -->
</div><!-- /#edit-stream-panel -->
<!--------------------- Page Widgets Panel ------------------------->
@@ -132,7 +135,7 @@ <h2 class="new-feed">Add A Source</h2>
</div><!-- /optional-widget -->
<div class="stream-icon">
- <h3>Your {{stream.name}} Stream</h3>
+ <h3>Your {{page_name}} Stream</h3>
<img src="/static/img/StreamDiagram_25perc.jpg" width="76" height="95" />
</div>
@@ -212,6 +215,5 @@ <h2 class="new-feed">Add A Source</h2>
</div><!-- /design-stream -->
</div><!-- /stream-editor-panel -->
-<script src="/static/js/jquery-1.4.1.min.js" type="text/javascript"></script>
-<script src="/static/js/stream_editor.js" type="text/javascript"></script>
+<script src="/static/js/stream_editor.min.js" type="text/javascript"></script>
{% endblock %}
View
2  apps/streamManager/templates/template.html
@@ -4,7 +4,7 @@
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<title>{% block title %}SudoSocial{% endblock %}</title>
- <link href="/static/css/editor-stylo.css" type="text/css" rel="stylesheet">
+ <link href="/static/css/editor-stylo.min.css" type="text/css" rel="stylesheet">
{%block page_css_link %} {% endblock %}
<link rel="icon" href="/static/img/favicon.png" type="image/png">
</head>
View
5 apps/streamManager/templates/widgets/add_stream_button.html
@@ -0,0 +1,5 @@
+<div class="add-stream-panel">
+ <p class="callout">A page can have multiple streams.</p>
+ <p><a href="/manage/streams/{{username}}/p/{{page_name}}" class="add-stream button">Add Another Stream</a>.</p>
+ <p class="creating">Creating Stream</p>
+</div>
View
1  apps/streamManager/templates/widgets/delete_stream_panel.html
@@ -0,0 +1 @@
+<p class="stream-delete-panel"><a href="{{stream.id}}" class="stream-delete button">Delete</a></p>
View
4 apps/streamManager/urls.py
@@ -6,7 +6,9 @@
(r'^account/(?P<username>\w+)/stream/(?P<stream_id>\d+)/preview_feed/(?P<feed_id>\w+)$', 'views.preview_feed'),
(r'^stream/design$', 'views.manage_page_design'),
(r'^stream/(?P<username>\w+)/s/(?P<page_name>\w+)$', 'views.manage_page'),
-
+ (r'^stream/(?P<username>\w+)/sid/(?P<stream_id>\w+)$', 'views.stream'),
+ (r'^streams/(?P<username>\w+)/p/(?P<page_name>\w+)$', 'views.streams', {}, 'streams'),
+
(r'^page/(?P<page_name>\w+)$', 'views.manage_page_widgets'),
(r'^urls/(?P<username>\w+)$', 'views.urls'),
View
68 apps/streamManager/views.py
@@ -1,6 +1,7 @@
import logging
import datetime
import hashlib
+import time
import feedparser
from pyquery import PyQuery
@@ -39,11 +40,11 @@ def manage_profile(request):
@login_required
def manage(request, username):
if request.user.username == username:
- streams = lifestream.models.Stream.objects.filter(user=request.user).all()
- if len(streams) == 1:
- return manage_page(request, username, 'home')
+ pages = lifestream.models.Webpage.objects.filter(user=request.user).all()
+ if len(pages) == 1:
+ return manage_page(request, username, pages[0].name)
else:
- return manage_all_streams(request, username)
+ return manage_all_pages(request, username)
else:
return django.http.HttpResponse(HACKING_MESSAGE, status=400)
@@ -54,11 +55,12 @@ def entry_pair_for_entries(request, raw_entries, plugins):
@login_required
def manage_page(request, username, page_name):
if request.user.username == username:
+ log.info("Grabbing webpage")
webpage = get_object_or_404(lifestream.models.Webpage, user=request.user, name=page_name)
webpage_properties = patchouli_auth.preferences.getPageProperties(webpage)
streams = []
- for stream_name in webpage_properties['stream_names']:
- stream = get_object_or_404(lifestream.models.Stream, user=request.user, name=stream_name)
+ for stream_id in webpage_properties['stream_ids']:
+ stream = get_object_or_404(lifestream.models.Stream, user=request.user, id=stream_id)
streams.append(stream)
stream_config = StreamConfig(stream.config)
feed_rows = stream.feed_set.all()
@@ -127,7 +129,7 @@ def manage_page(request, username, page_name):
'page_langs': lang.HTML_LANG,
'page_lang_desc': lang.HTML_LANG[webpage_properties['page_lang']],
'page_lang_dirs': lang.DIR_CHOICES,
- 'page_name': stream.name,
+ 'page_name': page_name,
'request': request,
'streams': streams,
'stream_id': stream.id,
@@ -210,8 +212,11 @@ def append_if_dict(a_list, maybe_dict):
def save_feeds(request, username):
new_feeds_to_save = []
params = request.POST.copy()
- stream = get_object_or_404(lifestream.models.Stream, user=request.user,
- name=params['streams[]'])
+ log.info("Saving for stream with an id of")
+ log.info(params['streams[]'])
+ stream = get_object_or_404(lifestream.models.Stream,
+ user=request.user,
+ id=params['streams[]'])
feed_url = request.POST['url']
possible_feed = is_possible_feed(feed_url)
if possible_feed:
@@ -232,7 +237,7 @@ def save_feeds(request, username):
a_feed = lifestream.models.Feed(url_hash = feed_url_hash, title=new_feed_to_save['feed_title'],
url = new_feed_to_save['feed_url'],
etag='', last_modified=datetime.datetime(1975, 1, 10),
- enabled=True, disabled_reason='',
+ enabled=True, disabled_reason='',
user=request.user, created_date=datetime.datetime.today())
a_feed.streams.add(stream)
form = lifestream.models.FeedForm(params, instance=a_feed)
@@ -494,25 +499,60 @@ def preview_feed(request, username, stream_id, feed_id):
'stream_id': stream.id,
},
context_instance=django.template.RequestContext(request))
-
+@login_required
+def streams(request, username, page_name):
+ if request.user.username == username:
+ if 'POST' == request.method:
+ webpage = get_object_or_404(lifestream.models.Webpage, user=request.user, name=page_name)
+ webpage_props = patchouli_auth.preferences.getPageProperties(webpage)
+ new_stream_name = "Untitled %d" % int(time.mktime(datetime.datetime.now().timetuple()) * 1000)
+ new_stream = lifestream.models.Stream(user=request.user, name=new_stream_name, webpage=webpage)
+ new_stream.save()
+
+ webpage_props['stream_ids'].append(new_stream.id)
+ patchouli_auth.preferences.savePageOrStreamProperties(webpage, webpage_props)
+ payload = {'status': 'OK', 'new_stream_id': new_stream.id}
+ #TODO type in all these content-types.... WTF?
+ return django.http.HttpResponse(json.dumps(payload), mimetype='applicaiton/json')
+
+ else:
+ return django.http.HttpResponse('Hey')
+ else:
+ return django.http.HttpResponse('{"message":"' + HACKING_MESSAGE + '"}', mimetype='applicaiton/json', status=400)
+
+@login_required
+def stream(request, username, stream_id):
+ if request.user.username == username:
+ if 'DELETE' == request.method:
+ stream = get_object_or_404(lifestream.models.Stream, user=request.user, id=stream_id)
+ payload = {'status': 'ERROR', 'msg': 'Unabled to remove stream'}
+ log.info("Removing stream %d %s" % (stream.id, stream.name))
+ if patchouli_auth.preferences.removeStreamFromPage(stream.webpage, stream):
+ payload = {'status': 'OK', 'msg': 'Stream removed'}
+ return django.http.HttpResponse(json.dumps(payload), mimetype='applicaiton/json')
+ else:
+ return django.http.HttpResponse('Hey')
+ else:
+ return django.http.HttpResponse('{"message":"' + HACKING_MESSAGE + '"}', mimetype='applicaiton/json', status=400)
+
# ----------------- Sitewide Functions --------------#
def homepage(request):
return render_to_response('homepage.html',
- {'css_url': '/static/css/general-site.css',
+ {'css_url': '/static/css/general-site.min.css',
'lang_dir': 'LTR',
'page_lang': 'en',},
context_instance=django.template.RequestContext(request))
def page_not_found(request):
response = render_to_response('404.html',
- {'css_url': '/static/css/general-site.css'},
+ {'css_url': '/static/css/general-site.min.css'},
context_instance=django.template.RequestContext(request))
response.status_code = 404
return response
def server_error(request):
response = render_to_response('500.html',
- {'css_url': '/static/css/general-site.css'},
+ {'css_url': '/static/css/general-site.min.css'},
context_instance=django.template.RequestContext(request))
response.status_code = 500
return response
View
5 bin/dev_merge.sh
@@ -0,0 +1,5 @@
+juicer merge -s --force -m '' static/js/stream_editor.js
+juicer merge -s --force -m '' static/js/feed_editor.js
+
+juicer merge -d . -e data_uri -f -m '' static/css/editor-stylo.css
+juicer merge -d . -e data_uri -f -m '' static/css/general-site.css
View
5 bin/merge.sh
@@ -0,0 +1,5 @@
+juicer merge -s --force static/js/stream_editor.js
+juicer merge -s --force static/js/feed_editor.js
+
+juicer merge -d . -e data_uri -f static/css/editor-stylo.css
+juicer merge -d . -e data_uri -f static/css/general-site.css
View
2  bin/verify.sh
@@ -0,0 +1,2 @@
+find static/js/ -name '[a-zA-Z]*.js' | grep -v "/lib/" | grep -v "min.js" | xargs juicer verify
+
View
52 docs/database/migrations/0.6-add-webpage-to-stream.py
@@ -0,0 +1,52 @@
+"""
+ Run python manage.py dbsync
+ Then run this migration
+ Create a config.py based off of config.py.dist in this directory... then run as
+ python docs/database/migrations/0.5-split-entry.py
+"""
+import sys
+
+import config
+sys.path.append(config.path)
+
+from django.core.management import setup_environ
+import settings
+setup_environ(settings)
+
+import os
+import site
+
+ROOT = os.path.dirname(os.path.abspath(__file__))
+path = lambda *a: os.path.join(ROOT, *a)
+site.addsitedir(path('../../../apps'))
+
+import logging
+logging.basicConfig(level = config.log_level,
+ format = '%(asctime)s %(levelname)s %(process)d %(message)s', )
+log = logging.getLogger()
+
+log.info("Added %s" % path('../../../apps'))
+
+from django.db import connection, transaction
+cursor = connection.cursor()
+
+log.info("So far so good so what")
+log.info(sys.path)
+
+from lifestream.models import Webpage, Stream
+
+log.info("Adding webpage_id column")
+cursor.execute("ALTER TABLE lifestream_stream ADD COLUMN webpage_id integer NOT NULL")
+log.info("Adding foreign key constraint")
+cursor.execute("ALTER TABLE `lifestream_stream` ADD CONSTRAINT `webpage_id_refs_id_6804d8c3` FOREIGN KEY (`webpage_id`) REFERENCES `lifestream_webpage` (`id`)")
+
+transaction.commit_unless_managed()
+
+for stream in Stream.objects.all():
+ webpage = Webpage.objects.get(user__id = stream.user_id,
+ name='home')
+ stream.webpage_id = webpage.id
+ stream.save()
+
+#transaction.commit_unless_managed()
+log.info("Done success")
View
143 static/css/editor-stylo-kitchen-sink.css
@@ -0,0 +1,143 @@
+/* TODO break up into chunks and @import from editor-stylo.css */
+
+div.logo a {
+ padding-left: 67px;
+ background-image: url('/static/img/riverdam_logo_62x35.jpg?embed=true');
+ background-repeat: no-repeat;
+}
+div.logo {
+ font-size: 300%;
+ line-height: 1;
+}
+div.logo, div.logo a {
+ color: #1046b0;
+ font-weight: bold;
+ text-decoration: none;
+}
+.tagline {
+ font-size: 110%;
+ font-style: italic;
+ line-height: 1;
+ margin-top: 0px;
+ padding-top: 0px;
+ float: left;
+}
+.logo-panel { float: left; }
+.logo-panel .logo { font-size: 200%; float: left; }
+.logo-panel .tagline { font-size: 90%; line-height: 3.0; }
+
+#auth {
+
+ float: right;
+ padding: 0.3em;
+}
+#heading {
+
+ width: 100%;
+}
+#sidebar {
+ position: absolute;
+ width: 200px;
+}
+#content {
+ margin-left: 180px;
+}
+#content > h1:first {
+ padding-top: 0px;
+ margin-top: -30px;
+ clear: both;
+}
+#edit-stream-panel {
+ float: left;
+ width: 800px;
+}
+#feed_panel { width: 1030px; }
+.streams-panel { float: left; width: 815px; border: dotted 1px grey; } /* contains .stream-metadata-panel and .stream-preview-panel */
+
+.stream-metadata-panel { width: 300px; float: left; }
+.stream-preview-panel, #stream-preview { width: 500px; float: left; overflow: scroll; margin-left: 5px; padding-right: 10px;}
+
+.feed-entry hr { display: none; }
+.feed-entry {
+ border: solid 1px #666;
+ border-top: solid 3px #333;
+ border-right: solid 2px #333;
+
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ margin-bottom: 10px;
+ max-height: 400px;
+
+ overflow: auto;
+ padding: 5px;
+}
+
+ .tabs li {
+
+ float: left;
+ margin-right: 0.5em;
+ padding: 0.2em 0.5em;
+ list-style: none;
+
+ z-index: 2;
+ }
+ .tabs li.tab {
+ background-color: #EEE;
+ border: solid 1px #000;
+ }
+
+ .tabs li.active-tab {
+ border-bottom: none;
+ background-color: #FFF;
+ }
+ .panel { border: solid 1px #CCC; clear: left; position: relative; top: -1px; z-index: 1; padding: 0em 1em;}
+ h2 { clear: left;}
+#other-sources-panel {
+
+ width: 300px;
+ float: right;
+}
+#design-stream-panel .save, #page-widgets-panel .save { float: right; margin: 1em 1em 0em 0em }/* text-align: right; */
+
+#page-widgets-panel label { font-weight: bold; font-size: 115%; }
+#page-widgets-panel textarea { width: 600px; height: 300px; margin:10px}
+#page-widgets-panel strong { display: block; }
+.checkbox-label {font-weight: bold;}
+#page-widgets-panel label.checkbox {font-weight: normal; font-size: 100%;}
+br, .optional-widget { clear: both; }
+
+.display_entry {
+ float: right;
+}
+
+.feed-entries-visible-default {
+ width: 16px;
+ height: 16px;
+ border: 1px solid #333;
+ display: inline-table;
+}
+feed-entries-visible-default.hidden {
+ background-color: #666;
+}
+feed-entries-visible-default.shown {
+ background-color: #CCC;
+}
+div.entry-hidden {
+ background-color: #CCC;
+ color: #333;
+}
+fieldset, .field {
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ border: 1px solid #000;
+ margin: 10px auto 10px auto;
+ padding: 10px;
+ width: 650px;
+}
+#manage-page-widgets fieldset,
+.optional-text-widget { margin-left: 0px; margin-right: 0px; }
+input.url {
+ width: 600px;
+}
+
+.user_streams li { line-height: 2.2em; }
View
155 static/css/editor-stylo.css
@@ -1,154 +1,11 @@
+@import url("lib/reset.css")
-div.logo a {
- padding-left: 67px;
- background-image: url('/static/img/riverdam_logo_62x35.jpg');
- background-repeat: no-repeat;
-}
-div.logo {
- font-size: 300%;
- line-height: 1;
-}
-div.logo, div.logo a {
- color: #1046b0;
- font-weight: bold;
- text-decoration: none;
-}
-.tagline {
- font-size: 110%;
- font-style: italic;
- line-height: 1;
- margin-top: 0px;
- padding-top: 0px;
- float: left;
-}
-.logo-panel { float: left; }
-.logo-panel .logo { font-size: 200%; float: left; }
-.logo-panel .tagline { font-size: 90%; line-height: 3.0; }
+@import url("editor-stylo-kitchen-sink.css")
-#auth {
-
- float: right;
- padding: 0.3em;
-}
-#heading {
+@import url("widgets/buttons.css")
- width: 100%;
-}
-#sidebar {
- position: absolute;
- width: 200px;
-}
-#content {
- margin-left: 180px;
-}
-#content > h1:first {
- padding-top: 0px;
- margin-top: -30px;
- clear: both;
-}
-#edit-stream-panel {
- float: left;
- width: 800px;
-}
-#feed_panel { width: 1030px; }
-.streams-panel, .add-stream-panel { float: left; width: 815px; border: dotted 1px grey; } /* contains .stream-metadata-panel and .stream-preview-panel */
-.add-stream-panel { width: 300px; }
-.stream-metadata-panel { width: 300px; float: left; }
-.stream-preview-panel, #stream-preview { width: 500px; float: left; overflow: scroll; margin-left: 5px; padding-right: 10px;}
-.callout {
- line-height: 2.5;
- margin-left: 10px;
-}
-.feed-entry hr { display: none; }
-.feed-entry {
- border: solid 1px #666;
- border-top: solid 3px #333;
- border-right: solid 2px #333;
-
- -moz-border-radius: 3px;
- -webkit-border-radius: 3px;
- margin-bottom: 10px;
- max-height: 400px;
-
- overflow: auto;
- padding: 5px;
-}
+@import url("widgets/add_stream_button.css");
- .tabs li {
-
- float: left;
- margin-right: 0.5em;
- padding: 0.2em 0.5em;
- list-style: none;
-
- z-index: 2;
- }
- .tabs li.tab {
- background-color: #EEE;
- border: solid 1px #000;
- }
-
- .tabs li.active-tab {
- border-bottom: none;
- background-color: #FFF;
- }
- .panel { border: solid 1px #CCC; clear: left; position: relative; top: -1px; z-index: 1; padding: 0em 1em;}
- h2 { clear: left;}
-#other-sources-panel {
+@import url("widgets/delete_stream_panel.css");
- width: 300px;
- float: right;
-}
-#design-stream-panel .save, #page-widgets-panel .save { float: right; margin: 1em 1em 0em 0em }/* text-align: right; */
-
-#page-widgets-panel label { font-weight: bold; font-size: 115%; }
-#page-widgets-panel textarea { width: 600px; height: 300px; margin:10px}
-#page-widgets-panel strong { display: block; }
-.checkbox-label {font-weight: bold;}
-#page-widgets-panel label.checkbox {font-weight: normal; font-size: 100%;}
-br, .optional-widget { clear: both; }
-
-.display_entry {
- float: right;
-}
-
-.feed-entries-visible-default {
- width: 16px;
- height: 16px;
- border: 1px solid #333;
- display: inline-table;
-}
-feed-entries-visible-default.hidden {
- background-color: #666;
-}
-feed-entries-visible-default.shown {
- background-color: #CCC;
-}
-div.entry-hidden {
- background-color: #CCC;
- color: #333;
-}
-fieldset, .field {
- -moz-border-radius: 5px;
- -webkit-border-radius: 5px;
- border: 1px solid #000;
- margin: 10px auto 10px auto;
- padding: 10px;
- width: 650px;
-}
-#manage-page-widgets fieldset,
-.optional-text-widget { margin-left: 0px; margin-right: 0px; }
-input.url {
- width: 600px;
-}
-
-#user_streams li { line-height: 2.2em; }
-
-.button {
- background-color: #DDD;
- color: #000;
- border: solid 1px grey;
- padding: 5px 10px;
- -moz-border-radius: 15px;
- border-radius: 15px;
-}
+@import url("widgets/footer.css");
View
229 static/css/editor-stylo.min.css
@@ -0,0 +1,229 @@
+/* v1.0 | 20080212 */
+
+html, body, div, span, applet, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, big, cite, code,
+del, dfn, em, font, img, ins, kbd, q, s, samp,
+small, strike, strong, sub, sup, tt, var,
+b, u, i, center,
+dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ outline: 0;
+ font-size: 100%;
+ vertical-align: baseline;
+ background: transparent;
+}
+body {
+ line-height: 1;
+}
+ol, ul {
+ list-style: none;
+}
+blockquote, q {
+ quotes: none;
+}
+blockquote:before, blockquote:after,
+q:before, q:after {
+ content: '';
+ content: none;
+}
+
+/* remember to define focus styles! */
+:focus {
+ outline: 0;
+}
+
+/* remember to highlight inserts somehow! */
+ins {
+ text-decoration: none;
+}
+del {
+ text-decoration: line-through;
+}
+
+/* tables still need 'cellspacing="0"' in the markup */
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+/* TODO break up into chunks and @import from editor-stylo.css */
+
+div.logo a {
+ padding-left: 67px;
+ background-image: url('data:image/jpg;base64,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');
+ background-repeat: no-repeat;
+}
+div.logo {
+ font-size: 300%;
+ line-height: 1;
+}
+div.logo, div.logo a {
+ color: #1046b0;
+ font-weight: bold;
+ text-decoration: none;
+}
+.tagline {
+ font-size: 110%;
+ font-style: italic;
+ line-height: 1;
+ margin-top: 0px;
+ padding-top: 0px;
+ float: left;
+}
+.logo-panel { float: left; }
+.logo-panel .logo { font-size: 200%; float: left; }
+.logo-panel .tagline { font-size: 90%; line-height: 3.0; }
+
+#auth {
+
+ float: right;
+ padding: 0.3em;
+}
+#heading {
+
+ width: 100%;
+}
+#sidebar {
+ position: absolute;
+ width: 200px;
+}
+#content {
+ margin-left: 180px;
+}
+#content > h1:first {
+ padding-top: 0px;
+ margin-top: -30px;
+ clear: both;
+}
+#edit-stream-panel {
+ float: left;
+ width: 800px;
+}
+#feed_panel { width: 1030px; }
+.streams-panel { float: left; width: 815px; border: dotted 1px grey; } /* contains .stream-metadata-panel and .stream-preview-panel */
+
+.stream-metadata-panel { width: 300px; float: left; }
+.stream-preview-panel, #stream-preview { width: 500px; float: left; overflow: scroll; margin-left: 5px; padding-right: 10px;}
+
+.feed-entry hr { display: none; }
+.feed-entry {
+ border: solid 1px #666;
+ border-top: solid 3px #333;
+ border-right: solid 2px #333;
+
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ margin-bottom: 10px;
+ max-height: 400px;
+
+ overflow: auto;
+ padding: 5px;
+}
+
+ .tabs li {
+
+ float: left;
+ margin-right: 0.5em;
+ padding: 0.2em 0.5em;
+ list-style: none;
+
+ z-index: 2;
+ }
+ .tabs li.tab {
+ background-color: #EEE;
+ border: solid 1px #000;
+ }
+
+ .tabs li.active-tab {
+ border-bottom: none;
+ background-color: #FFF;
+ }
+ .panel { border: solid 1px #CCC; clear: left; position: relative; top: -1px; z-index: 1; padding: 0em 1em;}
+ h2 { clear: left;}
+#other-sources-panel {
+
+ width: 300px;
+ float: right;
+}
+#design-stream-panel .save, #page-widgets-panel .save { float: right; margin: 1em 1em 0em 0em }/* text-align: right; */
+
+#page-widgets-panel label { font-weight: bold; font-size: 115%; }
+#page-widgets-panel textarea { width: 600px; height: 300px; margin:10px}
+#page-widgets-panel strong { display: block; }
+.checkbox-label {font-weight: bold;}
+#page-widgets-panel label.checkbox {font-weight: normal; font-size: 100%;}
+br, .optional-widget { clear: both; }
+
+.display_entry {
+ float: right;
+}
+
+.feed-entries-visible-default {
+ width: 16px;
+ height: 16px;
+ border: 1px solid #333;
+ display: inline-table;
+}
+feed-entries-visible-default.hidden {
+ background-color: #666;
+}
+feed-entries-visible-default.shown {
+ background-color: #CCC;
+}
+div.entry-hidden {
+ background-color: #CCC;
+ color: #333;
+}
+fieldset, .field {
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ border: 1px solid #000;
+ margin: 10px auto 10px auto;
+ padding: 10px;
+ width: 650px;
+}
+#manage-page-widgets fieldset,
+.optional-text-widget { margin-left: 0px; margin-right: 0px; }
+input.url {
+ width: 600px;
+}
+
+.user_streams li { line-height: 2.2em; }
+
+.button {
+ background-color: #DDD;
+ color: #000;
+ border: solid 1px grey;
+ padding: 5px 10px;
+ -moz-border-radius: 15px;
+ border-radius: 15px;
+}
+
+
+
+
+.callout {
+ line-height: 1.2;
+ margin-left: 10px;
+}
+.add-stream-panel { width: 170px; }
+.creating { display: none; }
+.stream-delete-panel { margin-top: 2em; }
+a.stream-delete {
+ background-color:#E62020;
+ color:white;
+ float:right;
+ font-weight:bold;
+}
+#release-footer {
+ clear: both;
+ padding-left: 1em;
+}
+
+
+
+
View
145 static/css/general-site-kitchen-sink.css
@@ -0,0 +1,145 @@
+/* TODO break up into chunks and @import from general-site.css */
+code {
+ font-family: "Courier New", Courier, Arial, monospace;
+}
+body, p, div, span {
+ font-family: verdana;
+ font-size: 12pt;
+ line-height: 1.5;
+}
+h1.logo {
+ font-size: 300%;
+ line-height: 1;
+}
+h1.logo, h1.logo a {
+ color: #333;
+ text-decoration: none;
+}
+h1.logo code {
+ color: green;
+}
+.tagline {
+ font-size: 110%;
+ font-style: italic;
+ line-height: 1;
+ margin-top: 0px;
+ padding-top: 0px;
+}
+#content {
+ text-align: center;
+ min-height: 600px;
+ clear: both;
+}
+/* confirm profile */
+.copy, .login, #confirm_profile, #delete_profile {
+ margin: 0 auto;
+ width: 1090px;
+ padding-top: 1em;
+}
+.note {
+ font-size: 80%;
+}
+.cancel-link {
+ font-size: 120%;
+ font-weight: bold;
+ margin-top: 3em;
+}
+/* homepage */
+.homepage .logo {
+ padding-top: 1em;
+}
+.homepage .tagline {
+ margin-bottom: 1em;
+}
+#call-to-action {
+ float: left;
+ /* margin-left: 300px; */
+ text-align: left;
+ width: 400px;
+ background-color: #DDD;
+ border: solid 1px: #666;
+ -moz-border-radius: 15px;
+ -webkit-border-radius: 15px;
+ margin-bottom: 1em;
+ padding: 0.5em 1em;
+}
+#call-to-action li, #learn-more-sidebar li {
+ list-style: circle outside none;
+ margin-left: 2em;
+}
+#learn-more-sidebar {
+ border: solid 1px #333;
+ float: left;
+ text-align: left;
+ width: 640px; /* matches video */
+ margin-left: 1em;
+}
+
+/* admin and other app specific styles */
+.login {
+ text-align: left;
+}
+/* openid login */
+#fopenid {
+ width: 600px;
+ margin-bottom: 1em;
+}
+#fopenid fieldset {
+ border: solid 1px #333;
+ -moz-border-radius: 15px;
+ -webkit-border-radius: 15px;
+}
+#confirm_profile, #delete_profile {
+ width: 600px;
+ text-align: left;
+}
+label{
+ line-height: 1.5;
+}
+fieldset.required {
+ border: solid 3px #DDD;
+}
+fieldset {
+ padding: 1em;
+}
+legend {
+ font-weight: bold;
+ color: #333;
+}
+#profile-image {
+ float: right;
+ width: 200px;
+}
+
+div > label{
+ display: block;
+ float: left;
+ width: 6em;
+}
+#auth {
+ position: absolute;
+ top: 0.3em;
+ right: 0.3em
+
+}
+@import url("widgets/footer.css");
+
+.error-message {
+ color: red;
+}
+
+nav#global {
+ margin-bottom: 2em;
+}
+
+nav ul {
+ color: #000;
+}
+
+nav ul li {
+ float: left;
+ list-style: none;
+ margin-left: 1em;
+}
+
+
View
202 static/css/general-site.css
@@ -1,201 +1,3 @@
-/* v1.0 | 20080212 */
-
-html, body, div, span, applet, object, iframe,
-h1, h2, h3, h4, h5, h6, p, blockquote, pre,
-a, abbr, acronym, address, big, cite, code,
-del, dfn, em, font, img, ins, kbd, q, s, samp,
-small, strike, strong, sub, sup, tt, var,
-b, u, i, center,
-dl, dt, dd, ol, ul, li,
-fieldset, form, label, legend,
-table, caption, tbody, tfoot, thead, tr, th, td {
- margin: 0;
- padding: 0;
- border: 0;
- outline: 0;
- font-size: 100%;
- vertical-align: baseline;
- background: transparent;
-}
-body {
- line-height: 1;
-}
-ol, ul {
- list-style: none;
-}
-blockquote, q {
- quotes: none;
-}
-blockquote:before, blockquote:after,
-q:before, q:after {
- content: '';
- content: none;
-}
-
-/* remember to define focus styles! */
-:focus {
- outline: 0;
-}
-
-/* remember to highlight inserts somehow! */
-ins {
- text-decoration: none;
-}
-del {
- text-decoration: line-through;
-}
-
-/* tables still need 'cellspacing="0"' in the markup */
-table {
- border-collapse: collapse;
- border-spacing: 0;
-}
-
-/* END CSS RESET */
-code {
- font-family: "Courier New", Courier, Arial, monospace;
-}
-body, p, div, span {
- font-family: verdana;
- font-size: 12pt;
- line-height: 1.5;
-}
-h1.logo {
- font-size: 300%;
- line-height: 1;
-}
-h1.logo, h1.logo a {
- color: #333;
- text-decoration: none;
-}
-h1.logo code {
- color: green;
-}
-.tagline {
- font-size: 110%;
- font-style: italic;
- line-height: 1;
- margin-top: 0px;
- padding-top: 0px;
-}
-#content {
- text-align: center;
- min-height: 600px;
- clear: both;
-}
-/* confirm profile */
-.copy, .login, #confirm_profile, #delete_profile {
- margin: 0 auto;
- width: 1090px;
- padding-top: 1em;
-}
-.note {
- font-size: 80%;
-}
-.cancel-link {
- font-size: 120%;
- font-weight: bold;
- margin-top: 3em;
-}
-/* homepage */
-.homepage .logo {
- padding-top: 1em;
-}
-.homepage .tagline {
- margin-bottom: 1em;
-}
-#call-to-action {
- float: left;
- /* margin-left: 300px; */
- text-align: left;
- width: 400px;
- background-color: #DDD;
- border: solid 1px: #666;
- -moz-border-radius: 15px;
- -webkit-border-radius: 15px;
- margin-bottom: 1em;
- padding: 0.5em 1em;
-}
-#call-to-action li, #learn-more-sidebar li {
- list-style: circle outside none;
- margin-left: 2em;
-}
-#learn-more-sidebar {
- border: solid 1px #333;
- float: left;
- text-align: left;
- width: 640px; /* matches video */
- margin-left: 1em;
-}
-
-/* admin and other app specific styles */
-.login {
- text-align: left;
-}
-/* openid login */
-#fopenid {
- width: 600px;
- margin-bottom: 1em;
-}
-#fopenid fieldset {
- border: solid 1px #333;
- -moz-border-radius: 15px;
- -webkit-border-radius: 15px;
-}
-#confirm_profile, #delete_profile {
- width: 600px;
- text-align: left;
-}
-label{
- line-height: 1.5;
-}
-fieldset.required {
- border: solid 3px #DDD;
-}
-fieldset {
- padding: 1em;
-}
-legend {
- font-weight: bold;
- color: #333;
-}
-#profile-image {
- float: right;
- width: 200px;
-}
-
-div > label{
- display: block;
- float: left;
- width: 6em;
-}
-#auth {
- position: absolute;
- top: 0.3em;
- right: 0.3em
-
-}
-#release-footer {
- clear: both;
- padding-left: 1em;
-}
-
-.error-message {
- color: red;
-}
-
-nav#global {
- margin-bottom: 2em;
-}
-
-nav ul {
- color: #000;
-}
-
-nav ul li {
- float: left;
- list-style: none;
- margin-left: 1em;
-}
-
+@import url("lib/reset.css")
+@import url("general-site-kitchen-sink.css")
View
204 static/css/general-site.min.css
@@ -0,0 +1,204 @@
+/* v1.0 | 20080212 */
+
+html, body, div, span, applet, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, big, cite, code,
+del, dfn, em, font, img, ins, kbd, q, s, samp,
+small, strike, strong, sub, sup, tt, var,
+b, u, i, center,
+dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ outline: 0;
+ font-size: 100%;
+ vertical-align: baseline;
+ background: transparent;
+}
+body {
+ line-height: 1;
+}
+ol, ul {
+ list-style: none;
+}
+blockquote, q {
+ quotes: none;
+}
+blockquote:before, blockquote:after,
+q:before, q:after {
+ content: '';
+ content: none;
+}
+
+/* remember to define focus styles! */
+:focus {
+ outline: 0;
+}
+
+/* remember to highlight inserts somehow! */
+ins {
+ text-decoration: none;
+}
+del {
+ text-decoration: line-through;
+}
+
+/* tables still need 'cellspacing="0"' in the markup */
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+#release-footer {
+ clear: both;
+ padding-left: 1em;
+}
+
+/* TODO break up into chunks and @import from general-site.css */
+code {
+ font-family: "Courier New", Courier, Arial, monospace;
+}
+body, p, div, span {
+ font-family: verdana;
+ font-size: 12pt;
+ line-height: 1.5;
+}
+h1.logo {
+ font-size: 300%;
+ line-height: 1;
+}
+h1.logo, h1.logo a {
+ color: #333;
+ text-decoration: none;
+}
+h1.logo code {
+ color: green;
+}
+.tagline {
+ font-size: 110%;
+ font-style: italic;
+ line-height: 1;
+ margin-top: 0px;
+ padding-top: 0px;
+}
+#content {
+ text-align: center;
+ min-height: 600px;
+ clear: both;
+}
+/* confirm profile */
+.copy, .login, #confirm_profile, #delete_profile {
+ margin: 0 auto;
+ width: 1090px;
+ padding-top: 1em;
+}
+.note {
+ font-size: 80%;
+}
+.cancel-link {
+ font-size: 120%;
+ font-weight: bold;
+ margin-top: 3em;
+}
+/* homepage */
+.homepage .logo {
+ padding-top: 1em;
+}
+.homepage .tagline {
+ margin-bottom: 1em;
+}
+#call-to-action {
+ float: left;
+ /* margin-left: 300px; */
+ text-align: left;
+ width: 400px;
+ background-color: #DDD;
+ border: solid 1px: #666;
+ -moz-border-radius: 15px;
+ -webkit-border-radius: 15px;
+ margin-bottom: 1em;
+ padding: 0.5em 1em;
+}
+#call-to-action li, #learn-more-sidebar li {
+ list-style: circle outside none;
+ margin-left: 2em;
+}
+#learn-more-sidebar {
+ border: solid 1px #333;
+ float: left;
+ text-align: left;
+ width: 640px; /* matches video */
+ margin-left: 1em;
+}
+
+/* admin and other app specific styles */
+.login {
+ text-align: left;
+}
+/* openid login */
+#fopenid {
+ width: 600px;
+ margin-bottom: 1em;
+}
+#fopenid fieldset {
+ border: solid 1px #333;
+ -moz-border-radius: 15px;
+ -webkit-border-radius: 15px;
+}
+#confirm_profile, #delete_profile {
+ width: 600px;
+ text-align: left;
+}
+label{
+ line-height: 1.5;
+}
+fieldset.required {
+ border: solid 3px #DDD;
+}
+fieldset {
+ padding: 1em;
+}
+legend {
+ font-weight: bold;
+ color: #333;
+}
+#profile-image {
+ float: right;
+ width: 200px;
+}
+
+div > label{
+ display: block;
+ float: left;
+ width: 6em;
+}
+#auth {
+ position: absolute;
+ top: 0.3em;
+ right: 0.3em
+
+}
+
+
+.error-message {
+ color: red;
+}
+
+nav#global {
+ margin-bottom: 2em;
+}
+
+nav ul {
+ color: #000;
+}
+
+nav ul li {
+ float: left;
+ list-style: none;
+ margin-left: 1em;
+}
+
+
+
+
View
52 static/css/lib/reset.css
@@ -0,0 +1,52 @@
+/* v1.0 | 20080212 */
+
+html, body, div, span, applet, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, big, cite, code,
+del, dfn, em, font, img, ins, kbd, q, s, samp,
+small, strike, strong, sub, sup, tt, var,
+b, u, i, center,
+dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ outline: 0;
+ font-size: 100%;
+ vertical-align: baseline;
+ background: transparent;
+}
+body {
+ line-height: 1;
+}
+ol, ul {
+ list-style: none;
+}
+blockquote, q {
+ quotes: none;
+}
+blockquote:before, blockquote:after,
+q:before, q:after {
+ content: '';
+ content: none;
+}
+
+/* remember to define focus styles! */
+:focus {
+ outline: 0;
+}
+
+/* remember to highlight inserts somehow! */
+ins {
+ text-decoration: none;
+}
+del {
+ text-decoration: line-through;
+}
+
+/* tables still need 'cellspacing="0"' in the markup */
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
View
8 static/css/widgets/add_stream_button.css
@@ -0,0 +1,8 @@
+
+
+.callout {
+ line-height: 1.2;
+ margin-left: 10px;
+}
+.add-stream-panel { width: 170px; }
+.creating { display: none; }
View
10 static/css/widgets/buttons.css
@@ -0,0 +1,10 @@
+
+.button {
+ background-color: #DDD;
+ color: #000;
+ border: solid 1px grey;
+ padding: 5px 10px;
+ -moz-border-radius: 15px;
+ border-radius: 15px;
+}
+
View
7 static/css/widgets/delete_stream_panel.css
@@ -0,0 +1,7 @@
+.stream-delete-panel { margin-top: 2em; }
+a.stream-delete {
+ background-color:#E62020;
+ color:white;
+ float:right;
+ font-weight:bold;
+}
View
4 static/css/widgets/footer.css
@@ -0,0 +1,4 @@
+#release-footer {
+ clear: both;
+ padding-left: 1em;
+}
View
33 static/js/README.markdown
@@ -0,0 +1,33 @@
+
+Each screen 'foo' will have
+* one or more entries in urls.py
+* one Python function foo in views.py
+* one HTML template foo.html under templates
+* one JavaScript file joo.js that requires all of it's dependencies
+* one Minified JavaScript file foo.min.js for deployment
+* one CSS file that @import's other CSS files
+
+Any interesting sub-component should have
+* one HTML template for inclusion
+* one RequireJS style module
+* one CSS file
+
+Reusable JavaScript is broken into modules under the js/modules directory.
+
+# Dev versus Production #
+If you delete foo.min.js, then require.js will request each dependency one by one.
+Otherwise require.min.js will need to be refreshed by running the build commands in
+
+JS Lint
+~/.gem/ruby/1.8/bin/juicer verify static/js/modules/streams/show_hide.js
+Deploy code
+~/.gem/ruby/1.8/bin/juicer merge -i --force -m '' static/js/feed_editor.js
+
+For the least amount of pain use autocompile.py to re-build after a file is modified
+
+Note: Use of the require funciton and the @depend docstring are provided by RequireJS and Juicer.
+
+RequireJS - provides CommonJS compatible JavaScript modules
+Juicer - Used for "loading" source code (at compile time)
+
+RequireJS also *can* provide the code loading piece, but htis isn't used. Maybe we should use this for lazy loaded code... but this is confusing enough as it is. RequireJS has an optimization script that is like Juicer, but it only provides Google Closure compiler and can't do jsmin or YUI Compressor. Also RequireJS is written in Java, which means Oracle will sue your face off.
View
37 static/js/behavior.js
@@ -1,9 +1,12 @@
-$(document).ready(function(){
+/*jslint browser: true, plusplus: false, newcap: false */
+/*global window: false, require: false, $: false, Processing: false */
+$(document).ready(function () {
// Blow up Flickr by 200%
- $('.feed-flickr a img').each(function(i, img){
- var w = parseInt($(img).attr('width'));
+ $('.feed-flickr a img').each(function (i, img) {
+ var w = parseInt($(img).attr('width'), 10),
+ h;
if (w * 2 < 600) {
- var h = parseInt($(img).attr('height'));
+ h = parseInt($(img).attr('height'), 10);
$(img).attr('width', w * 2)
.attr('height', h * 2);
@@ -11,32 +14,32 @@ $(document).ready(function(){
});
// Tags shouldn't overlap content
- $('.feed-entry').each(function(i, div){
- var tagArea = $('.tag-area', div);
- var tagWidth = tagArea.width();
+ $('.feed-entry').each(function (i, div) {
+ var tagArea = $('.tag-area', div),
+ tagWidth = tagArea.width(),
+ tagHeight,
+ maxWidth;
if (tagWidth < 120) {
$(div).css('padding-right', tagWidth);
} else {
- var tagHeight = $('.tag-area', div).height;
- $(div).css('padding-bottom', tagHeight)
+ tagHeight = $('.tag-area', div).height;
+ $(div).css('padding-bottom', tagHeight);
}
- var maxWidth = 0;
- $('li', tagArea).each(function(i, li){
+ maxWidth = 0;
+ $('li', tagArea).each(function (i, li) {
if ($(li).outerWidth() > maxWidth) {
maxWidth = $(li).outerWidth();
}
- });
+ });
// TODO use geometry 30 degrees
tagArea.css('height', (maxWidth * 0.6) + 'px');
});
// Fixup Twitter html
- $('.feed-twitter').find('a:last').addClass('permalink');
-
+ $('.feed-twitter').find('a:last').addClass('permalink');
});
-$(document).ready(function(){
+$(document).ready(function () {
var processingScript = $('script[type=application/processing]').text();
- if (window.console) { console.info("Sending Processing", processingScript); }
- Processing( $('#processing-canvas').get(0), processingScript );
+ Processing($('#processing-canvas').get(0), processingScript);
});
View
32 static/js/effects/checkbox_disable_panel.js
@@ -0,0 +1,32 @@
+/*global window: false, self: false, require: false, $: false */
+
+/**
+ * @depend ../lib/jquery-1.4.1.min.js
+ * @depend ../lib/require.js
+ */
+require.def('effects/checkbox_disable_panel', [], function () {
+ var that = {
+ initialize: function () {
+ $('input[type=checkbox]').each(function (i, input) {
+ that.disableCheckboxPanels.call(input);
+ });
+ $('input[type=checkbox]').click(that.disableCheckboxPanels);
+ },
+ disableCheckboxPanels: function () {
+ var id = $(this).attr('id');
+ if ($(this).attr('checked')) {
+ $('.' + id + '_panel').removeClass('checkbox-disabled')
+ .find('input, textarea, select, button')
+ .removeAttr('disabled')
+ .focus();
+ } else {
+ $('.' + id + '_panel').addClass('checkbox-disabled')
+ .find('input, textarea, select, button')
+ .attr('disabled', 'true');
+ }
+ }
+ };
+ return that;
+});
+
+
View
57 static/js/feed_editor.js 100755 → 100644
@@ -1,38 +1,21 @@
-$(document).ready(function(){
- var reloadFeedPreview = function() {
- var url = $('#feed_preview_source').attr('href');
- $.ajax({url: url, dataType: 'html',
- success: function(data, status, xhr){
- $('#feed_preview').html(data);
- prepareShowHideEntries();
- }});
-
- }
- window.reloadFeedPreview = reloadFeedPreview;
- $('#feed_disabled_retry').click(function(){
- var oldText = $(this).text(),
- that = this;
- $(this).text('Loading');
- $.ajax({url:$(this).attr('href'),
- type: "GET",
- dataType: 'json',
- complete: function(xhr, status) {
+/*jslint browser: true*/
+/*global window: false, require: false, $: false */
+
+/**
+ * @depend lib/require.js
+ * @depend lib/jquery-1.4.1.min.js
+ * @depend widgets/stream_preview.js
+ * @depend widgets/feed_editor_delete_feed.js
+ * @depend effects/checkbox_disable_panel.js
+ */
+require.def('app',
+ ['widgets/stream_preview', 'widgets/feed_editor_delete_feed', 'effects/checkbox_disable_panel'],
+ function (stream_preview, delete_feed, checkbox_panel) {
+ stream_preview.registerRetryClickHandler();
+ stream_preview.reloadFeedPreview();
+ checkbox_panel.initialize();
+ return {};
+});
+
+
- },
- success: function(data, status, xhr) {
- window.data = data;
- if (Boolean(data.enabled)) {
- $('#feed-disabled_panel').hide();
- }
- reloadFeedPreview();
-
- $(that).text(oldText);
- },
- error: function(xhr, status, err) {
- $(that).text("Error, " + oldText);
- }
- });
- return false;
- });
- reloadFeedPreview();
-});
View
1,632 static/js/feed_editor.min.js
1,632 additions, 0 deletions not shown
View
0  static/js/jquery-1.4.1.min.js → static/js/lib/jquery-1.4.1.min.js 100755 → 100644
File renamed without changes
View
6,241 static/js/lib/jquery-1.4.2.js
6,241 additions, 0 deletions not shown
View
0  static/js/jquery-1.4.min.js → static/js/lib/jquery-1.4.min.js
File renamed without changes
View
0  static/js/jquery.scrollTo-min.js → static/js/lib/jquery.scrollTo-min.js
File renamed without changes
View
0  static/js/jquery.serialScroll-min.js → static/js/lib/jquery.serialScroll-min.js
File renamed without changes
View
1,307 static/js/lib/require.js
@@ -0,0 +1,1307 @@
+/**
+ * @license RequireJS Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
+ * Available via the MIT, GPL or new BSD license.
+ * see: http://github.com/jrburke/requirejs for details
+ */
+//laxbreak is true to allow build pragmas to change some statements.
+/*jslint plusplus: false, laxbreak: true */
+/*global window: false, document: false, navigator: false,
+setTimeout: false, traceDeps: true, clearInterval: false, self: false,
+setInterval: false, importScripts: false */
+
+
+var require;
+(function () {
+ //Change this version number for each release.
+ var version = "0.12.0",
+ empty = {}, s,
+ i, defContextName = "_", contextLoads = [],
+ scripts, script, rePkg, src, m, cfg, setReadyState,
+ readyRegExp = /^(complete|loaded)$/,
+ isBrowser = !!(typeof window !== "undefined" && navigator && document),
+ isWebWorker = !isBrowser && typeof importScripts !== "undefined",
+ ostring = Object.prototype.toString, scrollIntervalId, req, baseElement;
+
+ function isFunction(it) {
+ return ostring.call(it) === "[object Function]";
+ }
+
+ //Check for an existing version of require. If so, then exit out. Only allow
+ //one version of require to be active in a page. However, allow for a require
+ //config object, just exit quickly if require is an actual function.
+ if (typeof require !== "undefined") {
+ if (isFunction(require)) {
+ return;
+ } else {
+ //assume it is a config object.
+ cfg = require;
+ }
+ }
+
+ function makeContextFunc(name, contextName, force) {
+ return function () {
+ //A version of a require function that uses the current context.
+ //If last arg is a string, then it is a context.
+ //If last arg is not a string, then add context to it.
+ var args = [].concat(Array.prototype.slice.call(arguments, 0));
+ if (force || typeof arguments[arguments.length - 1] !== "string") {
+ args.push(contextName);
+ }
+ return (name ? require[name] : require).apply(null, args);
+ };
+ }
+
+ /**
+ * Calls a method on a plugin. The obj object should have two property,
+ * name: the name of the method to call on the plugin
+ * args: the arguments to pass to the plugin method.
+ */
+ function callPlugin(prefix, context, obj) {
+ //Call the plugin, or load it.
+ var plugin = s.plugins.defined[prefix], waiting;
+ if (plugin) {
+ plugin[obj.name].apply(null, obj.args);
+ } else {
+ //Put the call in the waiting call BEFORE requiring the module,
+ //since the require could be synchronous in some environments,
+ //like builds
+ waiting = s.plugins.waiting[prefix] || (s.plugins.waiting[prefix] = []);
+ waiting.push(obj);
+
+ //Load the module
+ context.defined.require(["require/" + prefix]);
+ }
+ }
+
+ /**
+ * Main entry point.
+ *
+ * If the only argument to require is a string, then the module that
+ * is represented by that string is fetched for the appropriate context.
+ *
+ * If the first argument is an array, then it will be treated as an array
+ * of dependency string names to fetch. An optional function callback can
+ * be specified to execute when all of those dependencies are available.
+ */
+ require = function (deps, callback, contextName) {
+ if (typeof deps === "string" && !isFunction(callback)) {
+ //Just return the module wanted. In this scenario, the
+ //second arg (if passed) is just the contextName.
+ return require.get(deps, callback);
+ }
+
+ //Do more work, either
+ return require.def.apply(require, arguments);
+ };
+
+ //Alias for caja compliance internally -
+ //specifically: "Dynamically computed names should use require.async()"
+ //even though this spec isn't really decided on.
+ req = require;
+
+ /**
+ * The function that handles definitions of modules. Differs from
+ * require() in that a string for the module should be the first argument,
+ * and the function to execute after dependencies are loaded should
+ * return a value to define the module corresponding to the first argument's
+ * name.
+ */
+ require.def = function (name, deps, callback, contextName) {
+ var config = null, context, newContext, contextRequire, loaded,
+ canSetContext, prop, newLength, outDeps,
+ mods, pluginPrefix, paths, index, i;
+
+ //Normalize the arguments.
+ if (typeof name === "string") {
+ //Defining a module. First, pull off any plugin prefix.
+ index = name.indexOf("!");
+ if (index !== -1) {
+ pluginPrefix = name.substring(0, index);
+ name = name.substring(index + 1, name.length);
+ }
+
+ //Check if there are no dependencies, and adjust args.
+ if (!require.isArray(deps)) {
+ contextName = callback;
+ callback = deps;
+ deps = [];
+ }
+
+ contextName = contextName || s.ctxName;
+
+ //If module already defined for context, or already waiting to be
+ //evaluated, leave.
+ context = s.contexts[contextName];
+ if (context && (context.defined[name] || context.waiting[name])) {
+ return require;
+ }
+ } else if (require.isArray(name)) {
+ //Just some code that has dependencies. Adjust args accordingly.
+ contextName = callback;
+ callback = deps;
+ deps = name;
+ name = null;
+ } else if (require.isFunction(name)) {
+ //Just a function that does not define a module and
+ //does not have dependencies. Useful if just want to wait
+ //for whatever modules are in flight and execute some code after
+ //those modules load.
+ callback = name;
+ contextName = deps;
+ name = null;
+ deps = [];
+ } else {
+ //name is a config object.
+ config = name;
+ name = null;
+ //Adjust args if no dependencies.
+ if (require.isFunction(deps)) {
+ contextName = callback;
+ callback = deps;
+ deps = [];
+ }
+
+ contextName = contextName || config.context;
+ }
+
+ contextName = contextName || s.ctxName;
+
+ if (contextName !== s.ctxName) {
+ //If nothing is waiting on being loaded in the current context,
+ //then switch s.ctxName to current contextName.
+ loaded = (s.contexts[s.ctxName] && s.contexts[s.ctxName].loaded);
+ canSetContext = true;
+ if (loaded) {
+ for (prop in loaded) {
+ if (!(prop in empty)) {
+ if (!loaded[prop]) {
+ canSetContext = false;
+ break;
+ }
+ }
+ }
+ }
+ if (canSetContext) {
+ s.ctxName = contextName;
+ }
+ }
+
+ //Grab the context, or create a new one for the given context name.
+ context = s.contexts[contextName];
+ if (!context) {
+ newContext = {
+ contextName: contextName,
+ config: {
+ waitSeconds: 7,
+ baseUrl: s.baseUrl || "./",
+ paths: {}
+ },
+ waiting: [],
+ specified: {
+ "require": true,
+ "exports": true,
+ "module": true
+ },
+ loaded: {
+ "require": true
+ },
+ urlFetched: {},
+ defined: {},
+ modifiers: {}
+ };
+
+ //Define require for this context.
+ newContext.defined.require = contextRequire = makeContextFunc(null, contextName);
+ require.mixin(contextRequire, {
+ modify: makeContextFunc("modify", contextName),
+ def: makeContextFunc("def", contextName),
+ get: makeContextFunc("get", contextName, true),
+ nameToUrl: makeContextFunc("nameToUrl", contextName, true),
+ ready: require.ready,