pull/1/head
eric 2012-05-06 22:31:52 -04:00
commit d489fc0730
19 changed files with 1021 additions and 402 deletions

View File

@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA41Tg+92k7xzXm27beIAHh4ekTRVoXBK8rhYa2SkxJ+yHcxhxLw78NckuCmNW0x/DJN/nZDAcgJfXRma2zVuZAPMdWpAFppksj4gLIAcrbHAnDw2Ef15476Oc+QhdZXQyEEBuvjrAK3tCZJ7iMHEykoR+whOR5PzCrPLgWAvL4560c0AkG9+EDwRPJA8VJrwyZUGE7a2j+eNVtAwZYvb+0rYvKwKWgwCgx585rHd5ooqwD3UfY91pjeFp2msEcp4h+4pJk99RdSo7Pjf4+olkrl1SHmEX6eWYLsaY0IkYKXPglNOiWcD2zxevdP4jlz5CFKO63o/K5LUndeF6Vc+/4Q== ehs@pobox.com

10
fabfile.py vendored
View File

@ -4,6 +4,8 @@ from regluit.sysadmin import aws
# allow us to use our ssh config files (e.g., ~/.ssh/config)
env.use_ssh_config = True
DATA_BACKUP_ACCOUNT = 'b235656@hanjin.dreamhost.com'
def rydev():
"""An example of using a function to define a host and use that definition in a command
to run:
@ -19,8 +21,12 @@ def update_prod():
with cd("/opt/regluit"):
run("./deploy/update-prod")
def backup_db(name='unglue.it'):
run("""TS=`date +"%Y-%m-%dT%H:%M:%S"`; /home/ubuntu/dump.sh | gzip > {0}.${{TS}}.sql.gz; scp ./{0}.${{TS}}.sql.gz b235656@hanjin.dreamhost.com: ; rm -f {0}.${{TS}}.sql.gz""".format(name))
def backup_db(name='unglue.it', server=DATA_BACKUP_ACCOUNT):
"""backup database on unglue.it or please with name to server"""
run("""TS=`date +"%Y-%m-%dT%H:%M:%S"`; /home/ubuntu/dump.sh | gzip > {0}.${{TS}}.sql.gz; scp ./{0}.${{TS}}.sql.gz {1}: ; rm -f {0}.${{TS}}.sql.gz""".format(name, server))
def list_backups(name='unglue.it', server=DATA_BACKUP_ACCOUNT):
local("""echo "ls -lt {0}.*" | sftp {1}""".format(name, server))
def get_dump():
"""Dump the current db on remote server and scp it over to local machine.

View File

@ -185,7 +185,7 @@ def getManageCampaignForm ( instance, data=None, *args, **kwargs ):
fields = 'description', 'details', 'license', 'target', 'deadline', 'paypal_receiver', 'edition'
widgets = {
'description': forms.Textarea(attrs={'cols': 80, 'rows': 20}),
'details': forms.Textarea(attrs={'cols': 80, 'rows': 20}),
'details': forms.Textarea(attrs={'cols': 80, 'rows': 5}),
'deadline': SelectDateWidget,
}

View File

@ -8,6 +8,9 @@ textarea {
width: 90%;
}
</style>
<link type="text/css" rel="stylesheet" href="/static/css/manage_campaign.css" />
<script type="text/javascript" src="/static/js/tabs.js"></script>
<script type="text/javascript">
var $j = jQuery.noConflict();
@ -21,12 +24,22 @@ $j(document).ready(function(){
);
});
</script>
<script>
var $j = jQuery.noConflict();
$j(document).ready(function(){
$j('#launchme').click(function() {
$j('#campaign_launcher').click();
});
});
</script>
{% endblock %}
{% block doccontent %}
{% block doccontent %}
{% if campaign.not_manager %}
<h2>You're not a manager for campaign: {{ campaign.name }}</h2>
{% else %}
<div id="locationhash">{{ activetab }}</div>
{% for alert in alerts %}
<h1 class="alert">{{ alert }}</h1>
{% empty %}
@ -41,116 +54,165 @@ Please fix the following before launching your campaign:
{% empty %}
{% endfor %}
Or, <a href="{% url rightsholders %}">go back</a> to rights holder tools page.<br />
<h2>The work</h2>
(Or, <a href="{% url rightsholders %}">go back</a> to rights holder tools page.)<br />
<div style="height:15px;"></div>
<div class="book-detail">
<div id="book-detail-img">
<a href="#"><img src="{{ work.cover_image_thumbnail }}" alt="{{ work.title }}" title="{{ work.title }}" width="131" height="192" /></a>
</div>
<div class="book-detail-info">
<h2 class="book-name">Title: <a href="{% url work campaign.work.id %}">{{ campaign.work.title }}</a></h2>
<h3 class="book-author">Authors: {{ campaign.work.author }}</h3>
<h3 class="book-year">Published: {{ campaign.work.publication_date }}</h3>
<h3 class="book-author">Language: {{ campaign.work.language }}</h3>
<p>Target Price: ${{ campaign.target }}</p>
<p>End Date: {{ campaign.deadline|date:"M d, Y" }}</p>
<p>Campaign status: {{ campaign.status }}</p>
<div class="layout">
<h2 class="book-name">{{ work.title }}</h2>
<div>
<div class="pubinfo">
<h3 class="book-author">{{ work.author }}</h3>
<h3 class="book-year">{{ pubdate }}</h3>
</div>
</div>
</div>
<div class="pledged-info">
<div class="pledged-group">
{{ work.last_campaign.supporters.count }} Ungluers have pledged ${{ work.last_campaign.current_total }}
</div>
<div class="status">
<img src="/static/images/images/icon-book-37by25-{{ work.percent_unglued }}.png" title="book list status" alt="book list status" />
</div>
</div>
</div>
<div>
<a href="{% url work_preview campaign.work.id %}" class="manage">Preview This Campaign</a>
</div>
<h3>Description of the work offered for ungluing</h3>
<form action="#" method="POST">
{% csrf_token %}
<p> Please choose the edition that most closely matches the edition to be unglued:
{{ form.edition.errors }}{{ form.edition }}
<p>This will be displayed in the Campaign tab for your work. It's your main pitch to supporters. It should include:</p>
<ul class="terms">
<li>A synopsis of the work.</li>
<li>Hyperlinks for the author(s), publisher making the offer, or for the work itself. <span class="rh_help" id="helpHyperlink">(How do I hyperlink?)</span>
<div class="rh_answer" id="helpHyperlink2">
<p>Format a hyperlink like this:</p>
<p>&lt;a href="http://your_link_here"&gt;your link title here&lt;/a&gt;</p>
<p>For example:</p>
<p>&lt;a href="http://www.archive.org"&gt;the Internet Archive&lt;/a&gt;</p>
<p>will display as <a href="http://www.archive.org">the Internet Archive</a>.</p>
<p>Copy-paste the code above and substitute your own values. You will find the link address in the location bar of your browser.</p>
</div></li>
<li>Anything especially appealing about the work or author: awards, embedded video (445px max), etc. <span class="rh_help" id="helpEmbed">(How do I embed video?)</span>
<div id="helpEmbed2" class="rh_answer">
<p>To embed a video from YouTube:</p>
<p>Go to the page where you watch the video. Under the video, click "Share".</p>
<p>A new set of options will open up. Click the "Embed" button.</p>
<p>This will generate some code for you to copy/paste into the box below. It will look something like this:</p>
<p>&lt;iframe width="444" height="301" src="<span style="color:red">http:</span>//www.youtube-nocookie.com/embed/adeDb0BRMZY?rel=0" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;</p>
<p>Copy/paste that text into the box below. Delete the part that says "http:" (shown in red in the example). You're done! We'll figure out the details.</p>
<p>Of course, if you want to include other text in addition to video, you can do that.</p>
<p>If you'd like to change the size of the video, feel free; just don't make it more than 445px wide. Leaving it the default size is fine, too.</p>
<p>If you'd like to embed a video from another source, please talk to us. You certainly can; we just want to make sure we've given you the right instructions.</p>
</div></li>
</ul>
<p>Make it concise and emotionally appealing. The point here is not to tell ungluers everything about your book; it's to remind them why they love it.</p>
{{ form.description.errors }}{{ form.description }}
<h3>Offer details</h3>
<p>This will be displayed on the Details tab for your work. It's the fine print for your offer. For example, if your unglued edition will exclude certain illustrations due to rights issues, or otherwise differ from existing editions, this is the place to disclose that. If your offer doesn't have any fine print, you can leave this blank.</p>
{{ form.details.errors }}{{ form.details }}
<h3>Target Price</h3>
<p> This is the target price for your campaign. Once you launch the campaign, you won't be able to increase it.</p>
{{ form.target.errors }}{{ form.target }}
<h3>License being offered</h3>
<p> This is the license you are offering to use once the campaign succeeds. For more info on the licenses you can use, see <a href="http://creativecommons.org/licenses">Creative Commons: About the Licenses</a>.</p>
{{ form.license.errors }}{{ form.license }}
<h3>Ending date</h3>
<p> This is the ending date of your campaign. Once you launch the campaign, you won't be able to change it.
The ending date can't be more than six months away- that's a practical limit for credit card authorizations.</p>
{{ form.deadline.errors }}{{ form.deadline }}
<div class="preview_campaign">
<a href="{% url work_preview campaign.work.id %}" class="manage" target="new">Preview This Campaign</a>
</div>
<h3>Paypal collection address</h3>
<p> If your campaign succeeds, the funds raised (less commission and fees) will be deposited in a paypal account bearing this email address.</p>
<p>{{ form.paypal_receiver.errors }}{{ form.paypal_receiver }}</p>
<p>We recommend that you save and then preview your campaign before launch. If it doesn't look exactly the way you like, we're happy to help; please email unglue.it support (<a href="mailto:support@gluejar.com">support@gluejar.com</a>).</p>
{% ifequal campaign.status 'ACTIVE' %}
<input type="submit" name="save" value="Modify Campaign" />
{% else %}
<input type="submit" name="save" value="Save Campaign" />
{% endifequal %}
{% ifequal campaign.status 'INITIALIZED' %}
<input type="submit" name="launch" value="Launch Campaign" />
{% endifequal %}
</form>
<h3>Premiums</h3>
<div class="jsmod-content">
<form action="#" method="POST">
{% csrf_token %}
<ul class="support menu">
{% for premium in premiums %}
<li class="{% if forloop.first %}first{% else %}{% if forloop.last %}last{% endif %}{% endif %}">
<a href="{% url pledge work_id=campaign.work.id %}?premium_id={{premium.id}}">
<span class="menu-item-price">${{ premium.amount }}</span>
<span class="menu-item-desc">{{ premium.description }}</span>
</a>
{% if premium.type %}<span class="custom-premium"> <br />Type: {{ premium.get_type_display }}</span>{% endif %}
{% ifnotequal premium.limit 0 %}<br />Limit: {{ premium.limit }}{% endifnotequal %}
{% ifequal premium.type 'CU' %}<br />Deactivate? <input type="checkbox" name="premium_id" value="{{ premium.id }}" />{% endifequal %}
</li>
{% endfor %}
</ul>
{% if campaign.custom_premiums.count %}
<input type="submit" name="inactivate" value="Inactivate Checked Premiums" />
{% endif %}
</form>
</div>
<h4>Add a custom premium for this campaign</h4>
<form action="#" method="POST">
{% csrf_token %}
Pledge Amount: {{ premium_form.amount.errors }}{{ premium_form.amount }}<br />
Premium Description: {{ premium_form.description.errors }}{{ premium_form.description }}<br />
Number Available (0 if no limit): {{ premium_form.limit.errors }}{{ premium_form.limit }}<br />
{{ premium_form.campaign }}
{{ premium_form.type.errors }}{{ premium_form.type }}
<br />
<input type="submit" name="add_premium" value="Add Premium" />
</form>
<div class="content-block-heading" id="tabs">
<ul class="tabs">
<li class="tabs1 {% if activetab == '1' %}active{% endif %}"><a href="#">Description</a></li>
<li class="tabs2 {% if activetab == '2' %}active{% endif %}"><a href="#">Premiums</a></li>
<li class="tabs3 {% if activetab == '3' %}active{% endif %}"><a href="#">Launch</a></li>
</ul>
</div>
<div class="clearfix"></div>
<div class="tabs-1">
<h3>Description of the work offered for ungluing</h3>
<form action="#" method="POST">
{% csrf_token %}
<p> Please choose the edition that most closely matches the edition to be unglued:
{{ form.edition.errors }}{{ form.edition }}
<p>This will be displayed in the Campaign tab for your work. It's your main pitch to supporters. It should include:</p>
<ul class="terms">
<li>A synopsis of the work.</li>
<li>Hyperlinks for the author(s), publisher making the offer, or for the work itself. <span class="rh_help" id="helpHyperlink">(How do I hyperlink?)</span>
<div class="rh_answer" id="helpHyperlink2">
<p>Format a hyperlink like this:</p>
<p>&lt;a href="http://your_link_here"&gt;your link title here&lt;/a&gt;</p>
<p>For example:</p>
<p>&lt;a href="http://www.archive.org"&gt;the Internet Archive&lt;/a&gt;</p>
<p>will display as <a href="http://www.archive.org">the Internet Archive</a>.</p>
<p>Copy-paste the code above and substitute your own values. You will find the link address in the location bar of your browser.</p>
</div></li>
<li>Anything especially appealing about the work or author: awards, embedded video (445px max), etc. <span class="rh_help" id="helpEmbed">(How do I embed video?)</span>
<div id="helpEmbed2" class="rh_answer">
<p>To embed a video from YouTube:</p>
<p>Go to the page where you watch the video. Under the video, click "Share".</p>
<p>A new set of options will open up. Click the "Embed" button.</p>
<p>This will generate some code for you to copy/paste into the box below. It will look something like this:</p>
<p>&lt;iframe width="444" height="301" src="<span style="color:red">http:</span>//www.youtube-nocookie.com/embed/adeDb0BRMZY?rel=0" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;</p>
<p>Copy/paste that text into the box below. Delete the part that says "http:" (shown in red in the example). You're done! We'll figure out the details.</p>
<p>Of course, if you want to include other text in addition to video, you can do that.</p>
<p>If you'd like to change the size of the video, feel free; just don't make it more than 445px wide. Leaving it the default size is fine, too.</p>
<p>If you'd like to embed a video from another source, please talk to us. You certainly can; we just want to make sure we've given you the right instructions.</p>
</div></li>
</ul>
<p>Make it concise and emotionally appealing. The point here is not to tell ungluers everything about your book; it's to remind them why they love it.</p>
{{ form.description.errors }}{{ form.description }}
<h3>Offer details</h3>
<p>This will be displayed on the Details tab for your work. It's the fine print for your offer. For example, if your unglued edition will exclude certain illustrations due to rights issues, or otherwise differ from existing editions, this is the place to disclose that. If your offer doesn't have any fine print, you can leave this blank.</p>
{{ form.details.errors }}{{ form.details }}
<h3>Target Price</h3>
<p> This is the target price for your campaign. Once you launch the campaign, you won't be able to increase it.</p>
{{ form.target.errors }}{{ form.target }}
<h3>License being offered</h3>
<p> This is the license you are offering to use once the campaign succeeds. For more info on the licenses you can use, see <a href="http://creativecommons.org/licenses">Creative Commons: About the Licenses</a>.</p>
{{ form.license.errors }}{{ form.license }}
<h3>Ending date</h3>
<p> This is the ending date of your campaign. Once you launch the campaign, you won't be able to change it.
The ending date can't be more than six months away- that's a practical limit for credit card authorizations.</p>
{{ form.deadline.errors }}{{ form.deadline }}
<h3>Paypal collection address</h3>
<p> If your campaign succeeds, the funds raised (less commission and fees) will be deposited in a paypal account bearing this email address.</p>
<p>{{ form.paypal_receiver.errors }}{{ form.paypal_receiver }}</p>
{% ifequal campaign.status 'ACTIVE' %}
<input type="submit" name="save" value="Modify Campaign" />
{% else %}
<input type="submit" name="save" value="Save Campaign" />
{% endifequal %}
{% ifequal campaign.status 'INITIALIZED' %}
<input id="campaign_launcher" type="submit" name="launch" value="Launch Campaign" />
{% endifequal %}
</form>
</div>
<div class="tabs-2">
<h3>Premiums</h3>
<div class="jsmod-content">
<form action="#" method="POST">
{% csrf_token %}
<ul class="support menu">
{% for premium in premiums %}
<li class="{% if forloop.first %}first{% else %}{% if forloop.last %}last{% endif %}{% endif %}">
<a href="{% url pledge work_id=campaign.work.id %}?premium_id={{premium.id}}">
<span class="menu-item-price">${{ premium.amount }}</span>
<span class="menu-item-desc">{{ premium.description }}</span>
</a>
{% if premium.type %}<span class="custom-premium"> <br />Type: {{ premium.get_type_display }}</span>{% endif %}
{% ifnotequal premium.limit 0 %}<br />Limit: {{ premium.limit }}{% endifnotequal %}
{% ifequal premium.type 'CU' %}<br />Deactivate? <input type="checkbox" name="premium_id" value="{{ premium.id }}" />{% endifequal %}
</li>
{% endfor %}
</ul>
{% if campaign.custom_premiums.count %}
<input type="submit" name="inactivate" value="Inactivate Checked Premiums" />
{% endif %}
</form>
</div>
<h4>Add a custom premium for this campaign</h4>
<form action="#" method="POST">
{% csrf_token %}
Pledge Amount: {{ premium_form.amount.errors }}{{ premium_form.amount }}<br />
Premium Description: {{ premium_form.description.errors }}{{ premium_form.description }}<br />
Number Available (0 if no limit): {{ premium_form.limit.errors }}{{ premium_form.limit }}<br />
{{ premium_form.campaign }}
{{ premium_form.type.errors }}{{ premium_form.type }}
<br />
<input type="submit" name="add_premium" value="Add Premium" />
</form>
</div>
<div class="tabs-3">
{% if campaign.description and campaign.target and campaign.deadline %}
<p>Before you hit launch:</p>
<ul>
<li>Have you proofread your campaign? (Make sure to spellcheck!)</li>
<li>Have you previewed your campaign? Does it look how you want it to?</li>
</ul>
<p>If it doesn't look exactly the way you like, or you're having any trouble with your description or premiums, we're happy to help; please email unglue.it support (<a href="mailto:support@gluejar.com">support@gluejar.com</a>).</p>
<p>If you're happy with your campaign, here's your moment of truth!</p>
<div id="launchme"><a href="#" class="manage">Launch Campaign</a></div>
{% else %}
<p>Please make sure you've entered your campaign's description, target, deadline, and premiums, and previewed your campaign, before launching.</p>
{% endif %}
</div>
{% endif %}
{% endblock %}

View File

@ -165,7 +165,8 @@ For more background, read our president Eric Hellman's thoughts on <a href="http
<a id="video"></a><h2>Video</h2>
<div class="pressvideos">
<div>
<object width="480" height="270"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="https://secure.vimeo.com/moogaloop.swf?clip_id=39352026&amp;server=secure.vimeo.com&amp;show_title=1&amp;show_byline=0&amp;show_portrait=0&amp;color=00adef&amp;fullscreen=1&amp;autoplay=0&amp;loop=0" /><embed src="https://secure.vimeo.com/moogaloop.swf?clip_id=39352026&amp;server=secure.vimeo.com&amp;show_title=1&amp;show_byline=0&amp;show_portrait=0&amp;color=00adef&amp;fullscreen=1&amp;autoplay=0&amp;loop=0" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="480" height="270"></embed></object><br />
<div class="mediaborder">
<object width="480" height="270"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="https://secure.vimeo.com/moogaloop.swf?clip_id=39352026&amp;server=secure.vimeo.com&amp;show_title=1&amp;show_byline=0&amp;show_portrait=0&amp;color=00adef&amp;fullscreen=1&amp;autoplay=0&amp;loop=0" /><embed src="https://secure.vimeo.com/moogaloop.swf?clip_id=39352026&amp;server=secure.vimeo.com&amp;show_title=1&amp;show_byline=0&amp;show_portrait=0&amp;color=00adef&amp;fullscreen=1&amp;autoplay=0&amp;loop=0" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="480" height="270"></embed></object></div><br />
<I>March 2012</I><br />
Andromeda Yelton; "The Future of Ebooks" panel at <a href="http://www.infotoday.com/cil2012/">Computers in Libraries</a>.
</div>

View File

@ -225,7 +225,9 @@ def manage_campaign(request, id):
if (not request.user.is_authenticated) or (not request.user in campaign.managers.all()):
campaign.not_manager=True
return render(request, 'manage_campaign.html', {'campaign': campaign})
alerts = []
alerts = []
activetab = '#1'
if request.method == 'POST' :
if request.POST.has_key('add_premium') :
postcopy=request.POST.copy()
@ -238,14 +240,17 @@ def manage_campaign(request, id):
else:
alerts.append(_('New premium has not been added'))
form = getManageCampaignForm(instance=campaign)
elif request.POST.has_key('save') or request.POST.has_key('launch') :
activetab = '#2'
elif request.POST.has_key('save') or request.POST.has_key('launch') :
form= getManageCampaignForm(instance=campaign, data=request.POST)
if form.is_valid():
form.save()
alerts.append(_('Campaign data has been saved'))
activetab = '#2'
else:
alerts.append(_('Campaign data has NOT been saved'))
if 'launch' in request.POST.keys():
activetab = '#3'
if campaign.launchable and form.is_valid() :
campaign.activate()
alerts.append(_('Campaign has been launched'))
@ -253,6 +258,7 @@ def manage_campaign(request, id):
alerts.append(_('Campaign has NOT been launched'))
new_premium_form = CustomPremiumForm(data={'campaign': campaign})
elif request.POST.has_key('inactivate') :
activetab = '#2'
if request.POST.has_key('premium_id'):
premiums_to_stop = request.POST['premium_id']
for premium_to_stop in premiums_to_stop:
@ -267,6 +273,13 @@ def manage_campaign(request, id):
form = getManageCampaignForm(instance=campaign)
new_premium_form = CustomPremiumForm(data={'campaign': campaign})
work = campaign.work
try:
pubdate = work.publication_date[:4]
except IndexError:
pubdate = 'unknown'
return render(request, 'manage_campaign.html', {
'campaign': campaign,
'form':form,
@ -274,6 +287,9 @@ def manage_campaign(request, id):
'alerts': alerts,
'premiums' : campaign.effective_premiums(),
'premium_form' : new_premium_form,
'pubdate': pubdate,
'work': work,
'activetab': activetab,
})
def googlebooks(request, googlebooks_id):

View File

@ -144,4 +144,9 @@ UNGLUEIT_TEST_PASSWORD = None
# decide which of the period tasks to add to the schedule
#CELERYBEAT_SCHEDULE['send_test_email'] = SEND_TEST_EMAIL_JOB
#CELERYBEAT_SCHEDULE['emit_notifications'] = EMIT_NOTIFICATIONS_JOB
CELERYBEAT_SCHEDULE['report_new_ebooks'] = EBOOK_NOTIFICATIONS_JOB
CELERYBEAT_SCHEDULE['report_new_ebooks'] = EBOOK_NOTIFICATIONS_JOB
try:
from regluit.settings.local import *
except ImportError:
pass

View File

@ -128,3 +128,9 @@ CELERYBEAT_SCHEDULE['emit_notifications'] = EMIT_NOTIFICATIONS_JOB
# Amazon credentials (for fps)
AWS_ACCESS_KEY = ''
AWS_SECRET_ACCESS_KEY = ''
# if settings/local.py exists, import those settings -- allows for dynamic generation of parameters such as DATABASES
try:
from regluit.settings.local import *
except ImportError:
pass

View File

@ -123,3 +123,9 @@ STATIC_ROOT = '/var/www/static'
#CELERYBEAT_SCHEDULE['send_test_email'] = SEND_TEST_EMAIL_JOB
#CELERYBEAT_SCHEDULE['emit_notifications'] = EMIT_NOTIFICATIONS_JOB
CELERYBEAT_SCHEDULE['report_new_ebooks'] = EBOOK_NOTIFICATIONS_JOB
# if settings/local.py exists, import those settings -- allows for dynamic generation of parameters such as DATABASES
try:
from regluit.settings.local import *
except ImportError:
pass

View File

@ -89,50 +89,73 @@
list-style: none;
border: none;
}
#js-page-wrap {
overflow: hidden;
}
#main-container {
margin-top: 20px;
}
#js-leftcol .jsmodule, .pledge.jsmodule {
margin-bottom: 10px;
}
#js-leftcol .jsmodule.rounded .jsmod-content, .pledge.jsmodule.rounded .jsmod-content {
-moz-border-radius: 20px;
-webkit-border-radius: 20px;
border-radius: 20px;
background: #edf3f4;
color: #3d4e53;
padding: 10px 20px;
font-weight: bold;
border: none;
margin: 0;
}
#js-leftcol .jsmodule.rounded .jsmod-content.ACTIVE, .pledge.jsmodule.rounded .jsmod-content.ACTIVE {
background: #8dc63f;
color: white;
font-size: 18px;
font-weight: normal;
}
#js-leftcol .jsmodule.rounded .jsmod-content.No.campaign.yet, .pledge.jsmodule.rounded .jsmod-content.No.campaign.yet {
background: #e18551;
color: white;
}
#js-leftcol .jsmodule.rounded .jsmod-content span, .pledge.jsmodule.rounded .jsmod-content span {
display: inline-block;
vertical-align: middle;
}
#js-leftcol .jsmodule.rounded .jsmod-content span.spacer, .pledge.jsmodule.rounded .jsmod-content span.spacer {
visibility: none;
}
#js-leftcol .jsmodule.rounded .jsmod-content span.findtheungluers, .pledge.jsmodule.rounded .jsmod-content span.findtheungluers {
cursor: pointer;
}
.jsmodule.pledge {
/* Campaign and manage_campaign use same tab styling, so it's factored out here */
#tabs {
border-bottom: 4px solid #6994a3;
clear: both;
float: left;
margin-left: 10px;
margin-top: 10px;
width: 100%;
}
#tabs ul.book-list-view {
margin-bottom: 4px !important;
}
#tabs-1,
#tabs-2,
#tabs-3,
#tabs-4 {
display: none;
}
#tabs-1.active,
#tabs-2.active,
#tabs-3.active,
#tabs-4.active {
display: inherit;
}
#tabs-2 textarea {
width: 95%;
}
ul.tabs {
float: left;
padding: 0;
margin: 0;
list-style: none;
width: 100%;
}
ul.tabs li {
float: left;
height: 46px;
line-height: 46px;
padding-right: 2px;
width: 116px;
background: none;
margin: 0;
padding: 0 2px 0 0;
}
ul.tabs li.tabs4 {
padding-right: 0px;
}
ul.tabs li a {
height: 46px;
line-height: 46px;
display: block;
text-align: center;
padding: 0 10px;
min-width: 80px;
-moz-border-radius: 7px 7px 0 0;
-webkit-border-radius: 7px 7px 0 0;
border-radius: 7px 7px 0 0;
background: #d6dde0;
color: #3d4e53;
}
ul.tabs li a:hover {
text-decoration: none;
}
ul.tabs li a:hover, ul.tabs li.active a {
background: #6994a3;
color: #fff;
}
/* needed for campaign, pledge, and manage_campaign */
.book-detail {
float: left;
width: 100%;
@ -239,67 +262,51 @@
height: 25px;
margin-top: -12px;
}
#tabs {
border-bottom: 4px solid #6994a3;
clear: both;
float: left;
margin-top: 10px;
width: 100%;
#js-page-wrap {
overflow: hidden;
}
#tabs ul.book-list-view {
margin-bottom: 4px !important;
#main-container {
margin-top: 20px;
}
#tabs-1,
#tabs-2,
#tabs-3,
#tabs-4 {
display: none;
#js-leftcol .jsmodule, .pledge.jsmodule {
margin-bottom: 10px;
}
#tabs-1.active,
#tabs-2.active,
#tabs-3.active,
#tabs-4.active {
display: inherit;
}
#tabs-2 textarea {
width: 95%;
}
ul.tabs {
float: left;
padding: 0;
margin: 0;
list-style: none;
width: 100%;
}
ul.tabs li {
float: left;
height: 46px;
line-height: 46px;
padding-right: 2px;
width: 116px;
}
ul.tabs li.tabs4 {
padding-right: 0px;
}
ul.tabs li a {
height: 46px;
line-height: 46px;
display: block;
text-align: center;
padding: 0 10px;
min-width: 80px;
-moz-border-radius: 7px 7px 0 0;
-webkit-border-radius: 7px 7px 0 0;
border-radius: 7px 7px 0 0;
background: #d6dde0;
#js-leftcol .jsmodule.rounded .jsmod-content, .pledge.jsmodule.rounded .jsmod-content {
-moz-border-radius: 20px;
-webkit-border-radius: 20px;
border-radius: 20px;
background: #edf3f4;
color: #3d4e53;
padding: 10px 20px;
font-weight: bold;
border: none;
margin: 0;
line-height: 16px;
}
ul.tabs li a:hover {
text-decoration: none;
#js-leftcol .jsmodule.rounded .jsmod-content.ACTIVE, .pledge.jsmodule.rounded .jsmod-content.ACTIVE {
background: #8dc63f;
color: white;
font-size: 18px;
font-weight: normal;
line-height: 20px;
}
ul.tabs li a:hover, ul.tabs li.active a {
background: #6994a3;
color: #fff;
#js-leftcol .jsmodule.rounded .jsmod-content.No.campaign.yet, .pledge.jsmodule.rounded .jsmod-content.No.campaign.yet {
background: #e18551;
color: white;
}
#js-leftcol .jsmodule.rounded .jsmod-content span, .pledge.jsmodule.rounded .jsmod-content span {
display: inline-block;
vertical-align: middle;
}
#js-leftcol .jsmodule.rounded .jsmod-content span.spacer, .pledge.jsmodule.rounded .jsmod-content span.spacer {
visibility: none;
}
#js-leftcol .jsmodule.rounded .jsmod-content span.findtheungluers, .pledge.jsmodule.rounded .jsmod-content span.findtheungluers {
cursor: pointer;
}
.jsmodule.pledge {
float: left;
margin-left: 10px;
}
#js-rightcol, #pledge-rightcol {
float: right;

View File

@ -0,0 +1,157 @@
/* Campaign and manage_campaign use same tab styling, so it's factored out here */
/* variables and mixins used in multiple less files go here */
.header-text {
height: 36px;
line-height: 36px;
display: block;
text-decoration: none;
font-weight: bold;
font-size: 13px;
letter-spacing: -0.05em;
}
.panelborders {
border-width: 1px 0px;
border-style: solid none;
border-color: #FFFFFF;
}
.roundedspan {
border: 1px solid #d4d4d4;
-moz-border-radius: 7px;
-webkit-border-radius: 7px;
border-radius: 7px;
padding: 1px;
color: #fff;
margin: 0 8px 0 0;
display: inline-block;
}
.roundedspan > span {
padding: 7px 7px;
min-width: 15px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
text-align: center;
display: inline-block;
}
.roundedspan > span .hovertext {
display: none;
}
.roundedspan > span:hover .hovertext {
display: inline;
}
.mediaborder {
padding: 5px;
border: solid 5px #EDF3F4;
}
.google_signup_div {
padding: 14px 0;
}
.google_signup_div div {
height: 24px;
line-height: 24px;
float: left;
padding-left: 5px;
}
.google_signup_div img {
float: left;
height: 24px;
width: 24px;
}
.actionbuttons {
width: auto;
height: 36px;
line-height: 36px;
background: #8dc63f;
-moz-border-radius: 32px;
-webkit-border-radius: 32px;
border-radius: 32px;
color: white;
cursor: pointer;
font-size: 13px;
font-weight: bold;
padding: 0 15px;
border: none;
margin: 5px 0;
}
.errors {
-moz-border-radius: 16px 16px 0 0;
-webkit-border-radius: 16px 16px 0 0;
border-radius: 16px 16px 0 0;
border: solid #e35351 3px;
clear: both;
width: 90%;
height: auto;
line-height: 16px;
padding: 7px 0;
font-weight: bold;
text-align: center;
}
.errors li {
list-style: none;
border: none;
}
#tabs {
border-bottom: 4px solid #6994a3;
clear: both;
float: left;
margin-top: 10px;
width: 100%;
}
#tabs ul.book-list-view {
margin-bottom: 4px !important;
}
#tabs-1,
#tabs-2,
#tabs-3,
#tabs-4 {
display: none;
}
#tabs-1.active,
#tabs-2.active,
#tabs-3.active,
#tabs-4.active {
display: inherit;
}
#tabs-2 textarea {
width: 95%;
}
ul.tabs {
float: left;
padding: 0;
margin: 0;
list-style: none;
width: 100%;
}
ul.tabs li {
float: left;
height: 46px;
line-height: 46px;
padding-right: 2px;
width: 116px;
background: none;
margin: 0;
padding: 0 2px 0 0;
}
ul.tabs li.tabs4 {
padding-right: 0px;
}
ul.tabs li a {
height: 46px;
line-height: 46px;
display: block;
text-align: center;
padding: 0 10px;
min-width: 80px;
-moz-border-radius: 7px 7px 0 0;
-webkit-border-radius: 7px 7px 0 0;
border-radius: 7px 7px 0 0;
background: #d6dde0;
color: #3d4e53;
}
ul.tabs li a:hover {
text-decoration: none;
}
ul.tabs li a:hover, ul.tabs li.active a {
background: #6994a3;
color: #fff;
}

View File

@ -485,7 +485,7 @@ dd {
border-bottom: solid 1px #3d4e53;
float: left;
}
.pressvideos iframe {
.pressvideos iframe, .pressvideos div.mediaborder {
padding: 5px;
border: solid 5px #EDF3F4;
padding: 5px;

View File

@ -0,0 +1,274 @@
/* variables and mixins used in multiple less files go here */
.header-text {
height: 36px;
line-height: 36px;
display: block;
text-decoration: none;
font-weight: bold;
font-size: 13px;
letter-spacing: -0.05em;
}
.panelborders {
border-width: 1px 0px;
border-style: solid none;
border-color: #FFFFFF;
}
.roundedspan {
border: 1px solid #d4d4d4;
-moz-border-radius: 7px;
-webkit-border-radius: 7px;
border-radius: 7px;
padding: 1px;
color: #fff;
margin: 0 8px 0 0;
display: inline-block;
}
.roundedspan > span {
padding: 7px 7px;
min-width: 15px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
text-align: center;
display: inline-block;
}
.roundedspan > span .hovertext {
display: none;
}
.roundedspan > span:hover .hovertext {
display: inline;
}
.mediaborder {
padding: 5px;
border: solid 5px #EDF3F4;
}
.google_signup_div {
padding: 14px 0;
}
.google_signup_div div {
height: 24px;
line-height: 24px;
float: left;
padding-left: 5px;
}
.google_signup_div img {
float: left;
height: 24px;
width: 24px;
}
.actionbuttons {
width: auto;
height: 36px;
line-height: 36px;
background: #8dc63f;
-moz-border-radius: 32px;
-webkit-border-radius: 32px;
border-radius: 32px;
color: white;
cursor: pointer;
font-size: 13px;
font-weight: bold;
padding: 0 15px;
border: none;
margin: 5px 0;
}
.errors {
-moz-border-radius: 16px 16px 0 0;
-webkit-border-radius: 16px 16px 0 0;
border-radius: 16px 16px 0 0;
border: solid #e35351 3px;
clear: both;
width: 90%;
height: auto;
line-height: 16px;
padding: 7px 0;
font-weight: bold;
text-align: center;
}
.errors li {
list-style: none;
border: none;
}
/* Campaign and manage_campaign use same tab styling, so it's factored out here */
#tabs {
border-bottom: 4px solid #6994a3;
clear: both;
float: left;
margin-top: 10px;
width: 100%;
}
#tabs ul.book-list-view {
margin-bottom: 4px !important;
}
#tabs-1,
#tabs-2,
#tabs-3,
#tabs-4 {
display: none;
}
#tabs-1.active,
#tabs-2.active,
#tabs-3.active,
#tabs-4.active {
display: inherit;
}
#tabs-2 textarea {
width: 95%;
}
ul.tabs {
float: left;
padding: 0;
margin: 0;
list-style: none;
width: 100%;
}
ul.tabs li {
float: left;
height: 46px;
line-height: 46px;
padding-right: 2px;
width: 116px;
background: none;
margin: 0;
padding: 0 2px 0 0;
}
ul.tabs li.tabs4 {
padding-right: 0px;
}
ul.tabs li a {
height: 46px;
line-height: 46px;
display: block;
text-align: center;
padding: 0 10px;
min-width: 80px;
-moz-border-radius: 7px 7px 0 0;
-webkit-border-radius: 7px 7px 0 0;
border-radius: 7px 7px 0 0;
background: #d6dde0;
color: #3d4e53;
}
ul.tabs li a:hover {
text-decoration: none;
}
ul.tabs li a:hover, ul.tabs li.active a {
background: #6994a3;
color: #fff;
}
/* needed for campaign, pledge, and manage_campaign */
.book-detail {
float: left;
width: 100%;
clear: both;
display: block;
}
#book-detail-img {
float: left;
margin-right: 10px;
width: 151px;
}
#book-detail-img img {
padding: 5px;
border: solid 5px #EDF3F4;
}
.book-detail-info {
float: left;
/* if we want to nix the explore bar, width should be 544ish */
width: 309px;
}
.book-detail-info h2.book-name, .book-detail-info h3.book-author, .book-detail-info h3.book-year {
padding: 0;
margin: 0;
line-height: normal;
}
.book-detail-info h2.book-name {
font-size: 18px;
text-transform: capitalize;
font-weight: bold;
color: #3d4e53;
}
.book-detail-info h3.book-author, .book-detail-info h3.book-year {
font-size: 12px;
font-weight: normal;
color: #6994a3;
}
.book-detail-info > div {
width: 100%;
clear: both;
display: block;
overflow: hidden;
border-top: 1px solid #edf3f4;
padding: 10px 0;
}
.book-detail-info > div.layout {
border: none;
padding: 0;
}
.book-detail-info > div.layout div.pubinfo {
float: left;
width: auto;
padding-bottom: 7px;
}
.book-detail-info > div.layout div.btn_support {
float: right;
}
.book-detail-info > div.layout div.btn_support input {
background: url("/static/images/btn_bg.png") 0 0 no-repeat;
width: 104px;
height: 41px;
display: block;
color: #fff;
font-weight: bold;
text-align: center;
border: none;
padding: 0;
cursor: pointer;
}
.book-detail-info > div.layout div.btn_support.modify input {
background: url("/static/images/btn_bg_grey.png") 0 0 no-repeat;
}
.book-detail-info .btn_wishlist span {
text-align: right;
}
.book-detail-info .find-book {
margin-top: 15px;
}
.book-detail-info .find-book label {
float: left;
line-height: 31px;
}
.book-detail-info .find-link {
float: right;
}
.book-detail-info .find-link img {
padding: 2px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
}
.book-detail-info .pledged-info {
padding: 0;
position: relative;
}
.book-detail-info .pledged-group {
padding: 10px 40px 10px 0;
float: left;
}
.book-detail-info .status {
position: absolute;
top: 50%;
right: 0%;
height: 25px;
margin-top: -12px;
}
.preview_campaign {
float: right;
margin-right: 10px;
}
input[name="launch"] {
display: none;
}
#launchme {
margin: 15px auto;
}

View File

@ -0,0 +1,125 @@
/* needed for campaign, pledge, and manage_campaign */
.book-detail {
float:left;
width:100%;
clear:both;
display:block;
}
#book-detail-img {
float: left;
margin-right:10px;
width:151px;
img {
.mediaborder;
}
}
.book-detail-info {
float:left;
/* if we want to nix the explore bar, width should be 544ish */
width:309px;
h2.book-name, h3.book-author, h3.book-year {
padding:0;
margin:0;
line-height:normal
}
h2.book-name {
font-size:18px;
text-transform:capitalize;
font-weight:bold;
color:@text-blue;
}
h3.book-author, h3.book-year {
font-size:12px;
font-weight:normal;
color:@medium-blue;
}
> div {
width:100%;
clear:both;
display:block;
overflow:hidden;
border-top:1px solid @pale-blue;
padding:10px 0;
}
> div.layout {
border: none;
padding: 0;
div.pubinfo {
float: left;
width: auto;
padding-bottom: 7px;
}
div.btn_support {
float: right;
input {
background:url("@{image-base}btn_bg.png") 0 0 no-repeat;
width:104px;
height:41px;
display:block;
color:#fff;
font-weight:bold;
text-align:center;
border:none;
padding:0;
cursor:pointer;
}
&.modify input {
background:url("@{image-base}btn_bg_grey.png") 0 0 no-repeat;
}
}
}
.btn_wishlist span {
text-align: right;
}
.find-book {
margin-top:15px;
label {
float:left;
line-height:31px;
}
}
.find-link {
float:right;
img {
padding: 2px;
.one-border-radius(5px);
}
}
.pledged-info {
padding:0;
position: relative;
}
.pledged-group {
padding:10px 40px 10px 0;
float:left;
}
.status {
position: absolute;
top:50%;
right:0%;
height: 25px;
margin-top: -12px;
}
}

View File

@ -1,4 +1,6 @@
@import "variables.less";
@import "campaign_tabs.less";
@import "book_detail.less";
.shareclass(@sharewhere) {
background:url("@{image-base}icons/@{sharewhere}.png") 10px center no-repeat;
@ -36,12 +38,14 @@
font-weight:bold;
border:none;
margin:0;
line-height: 16px;
&.ACTIVE {
background: @green;
color: white;
font-size: 18px;
font-weight: normal;
line-height: 20px;
}
&.No.campaign.yet {
@ -70,195 +74,6 @@
margin-left: 10px;
}
.book-detail {
float:left;
width:100%;
clear:both;
display:block;
}
#book-detail-img {
float: left;
margin-right:10px;
width:151px;
img {
.mediaborder;
}
}
.book-detail-info {
float:left;
/* if we want to nix the explore bar, width should be 544ish */
width:309px;
h2.book-name, h3.book-author, h3.book-year {
padding:0;
margin:0;
line-height:normal
}
h2.book-name {
font-size:18px;
text-transform:capitalize;
font-weight:bold;
color:@text-blue;
}
h3.book-author, h3.book-year {
font-size:12px;
font-weight:normal;
color:@medium-blue;
}
> div {
width:100%;
clear:both;
display:block;
overflow:hidden;
border-top:1px solid @pale-blue;
padding:10px 0;
}
> div.layout {
border: none;
padding: 0;
div.pubinfo {
float: left;
width: auto;
padding-bottom: 7px;
}
div.btn_support {
float: right;
input {
background:url("@{image-base}btn_bg.png") 0 0 no-repeat;
width:104px;
height:41px;
display:block;
color:#fff;
font-weight:bold;
text-align:center;
border:none;
padding:0;
cursor:pointer;
}
&.modify input {
background:url("@{image-base}btn_bg_grey.png") 0 0 no-repeat;
}
}
}
.btn_wishlist span {
text-align: right;
}
.find-book {
margin-top:15px;
label {
float:left;
line-height:31px;
}
}
.find-link {
float:right;
img {
padding: 2px;
.one-border-radius(5px);
}
}
.pledged-info {
padding:0;
position: relative;
}
.pledged-group {
padding:10px 40px 10px 0;
float:left;
}
.status {
position: absolute;
top:50%;
right:0%;
height: 25px;
margin-top: -12px;
}
}
#tabs{
border-bottom: 4px solid @medium-blue;
clear: both;
float: left;
margin-top: 10px;
width: 100%;
ul.book-list-view {
margin-bottom:4px !important;
}
}
#tabs-1, #tabs-2, #tabs-3, #tabs-4 {
display:none;
}
#tabs-1.active, #tabs-2.active, #tabs-3.active, #tabs-4.active {
display: inherit;
}
#tabs-2 textarea {
width: 95%;
}
ul.tabs {
float:left;
padding:0;
margin:0;
list-style:none;
width: 100%;
li {
float: left;
.height(46px);
padding-right:2px;
width: 116px;
&.tabs4 {
padding-right:0px;
}
a {
.height(46px);
display:block;
text-align:center;
padding:0 10px;
min-width:80px;
.border-radius(7px, 7px, 0, 0);
background:@blue-grey;
color:@text-blue;
&:hover {
text-decoration: none;
}
}
a:hover, &.active a {
background:@medium-blue;
color:#fff;
}
}
}
#js-rightcol, #pledge-rightcol {
float:right;
width:235px;

View File

@ -0,0 +1,68 @@
/* Campaign and manage_campaign use same tab styling, so it's factored out here */
#tabs{
border-bottom: 4px solid @medium-blue;
clear: both;
float: left;
margin-top: 10px;
width: 100%;
ul.book-list-view {
margin-bottom:4px !important;
}
}
#tabs-1, #tabs-2, #tabs-3, #tabs-4 {
display:none;
}
#tabs-1.active, #tabs-2.active, #tabs-3.active, #tabs-4.active {
display: inherit;
}
#tabs-2 textarea {
width: 95%;
}
ul.tabs {
float:left;
padding:0;
margin:0;
list-style:none;
width: 100%;
li {
float: left;
.height(46px);
padding-right:2px;
width: 116px;
background: none;
margin: 0;
padding: 0 2px 0 0;
&.tabs4 {
padding-right:0px;
}
a {
.height(46px);
display:block;
text-align:center;
padding:0 10px;
min-width:80px;
.border-radius(7px, 7px, 0, 0);
background:@blue-grey;
color:@text-blue;
&:hover {
text-decoration: none;
}
}
a:hover, &.active a {
background:@medium-blue;
color:#fff;
}
}
}

View File

@ -209,7 +209,7 @@ dd {
float: left;
}
iframe {
iframe, div.mediaborder {
.mediaborder;
}
}

View File

@ -0,0 +1,16 @@
@import "variables.less";
@import "campaign_tabs.less";
@import "book_detail.less";
.preview_campaign {
float: right;
margin-right: 10px;
}
input[name="launch"] {
display: none;
}
#launchme {
margin: 15px auto;
}

View File

@ -258,7 +258,61 @@ def launch_instance(ami='ami-a29943cb',
ssh_pwd=ssh_pwd)
return (instance, cmd)
def create_dbinstance(id, allocated_storage, instance_class, master_username, master_password,
port=3306, engine='MySQL5.1', db_name=None,
param_group=None, security_groups=None, availability_zone='us-east-1c', preferred_maintenance_window=None, backup_retention_period=None, preferred_backup_window=None, multi_az=False, engine_version=None, auto_minor_version_upgrade=True):
"""
create rds instance
"""
# rds-create-db-instance
return rds.create_dbinstance(id, allocated_storage, instance_class, master_username, master_password, port=port, engine=engine, db_name=db_name, param_group=param_group, security_groups=security_groups, availability_zone=availability_zone, preferred_maintenance_window=preferred_maintenance_window, backup_retention_period=backup_retention_period, preferred_backup_window=preferred_backup_window, multi_az=multi_az, engine_version=engine_version, auto_minor_version_upgrade=auto_minor_version_upgrade)
def ec2instance_info(e):
return(
{
'id': e.id,
'ip_address': e.ip_address,
}
)
def db_info(db, master_password=None):
"""given an rds instance db and master_password, return basic info"""
django_setting = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': db.id,
'USER': db.master_username,
'PASSWORD': master_password,
'HOST': db.endpoint[0],
'PORT': db.endpoint[1]
}
}
return({'id': db.id,
'allocated_storage': db.allocated_storage,
'availability_zone':db.availability_zone,
'instance_class': db.instance_class,
'multi_az': db.multi_az,
'master_username': db.master_username,
'engine': db.engine,
'preferred_backup_window': db.preferred_backup_window,
'preferred_maintenance_window': db.preferred_maintenance_window,
'backup_retention_period':db.backup_retention_period,
'parameter_group': db.parameter_group,
'security_group': db.security_group,
'endpoint':db.endpoint,
'status':db.status,
'create_time': db.create_time,
'latest_restorable_time':db.latest_restorable_time,
'django_setting': django_setting})
def test_ec2_user_data(ssh_pwd=None):
script = """#!/bin/sh
echo "Hello World. The time is now $(date -R)!" | tee /root/output.txt
"""
return launch_instance(user_data=script, ssh_pwd=ssh_pwd)
if __name__ == '__main__':
pprint (stats_for_instances(all_instances()))
web1 = instance('web1')