Skip to content

Instantly share code, notes, and snippets.

@DaneTheory
Last active June 2, 2016 13:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DaneTheory/d8474af4cceada48baf6334894e800e5 to your computer and use it in GitHub Desktop.
Save DaneTheory/d8474af4cceada48baf6334894e800e5 to your computer and use it in GitHub Desktop.
Code snipz. Includes PHP, Python, BASH, and a few other goodies I've created.
<?php
/* This Snips file is all about showing some PHP love!
-------------------------------------------------------------
Unfortunately, due to previous contract stipulations I don't
have access to much of the PHP I've written over the years.
This file contains a few snips I was able to get a hold of and
are based around CMS devlopment */
?>
<?php
// MAGENTO SNIPPET
/* This piece of code renders a carousel
composed of product items and is reused quite
often throughout the site. You can see it working
here: https://www.baublebar.com/ directly below the
main Hero image.*/?>
<?php $productCollection = $this->getLoadedProductCollection();
// $productCollection gives this snippet access to the value of the getLoadedProductCollection() function?>
<?php if ($productCollection->count()):
// Condition that checks if $productCollection has existing values from which to populate the carousel ?>
<div class="product_viewMoreCarousel_container _JS_productCarousel __isFullWidth">
<svg class="_JS_viewMoreCarouselPrevious product_viewMoreCarousel__previous"
height="40px"
width="23px"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<path fill="rgb( 183, 183, 183 )" d="M0,19.999 C0,19.999 20.014,39.998 20.014,39.998 C20.014,39.998 22.002,38.013 22.002,38.013 C22.002,38.013 3.988,19.999 3.988,19.999 C3.988,19.999 22.002,1.985 22.002,1.985 C22.002,1.985 20.014,0 20.014,0 C20.014,0 0,19.999 0,19.999 Z "></path>
</svg>
<svg class="_JS_viewMoreCarouselNext product_viewMoreCarousel__next"
height="40px"
width="23px"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<path fill="rgb( 183, 183, 183 )" d="M0,19.999 C0,19.999 20.014,39.998 20.014,39.998 C20.014,39.998 22.002,38.013 22.002,38.013 C22.002,38.013 3.988,19.999 3.988,19.999 C3.988,19.999 22.002,1.985 22.002,1.985 C22.002,1.985 20.014,0 20.014,0 C20.014,0 0,19.999 0,19.999 Z "></path>
</svg>
<ul class="product_viewMoreCarousel">
<?php foreach ($productCollection as $product):
/* A simple foreach loop which, used here, behaves much like a .map() iteration method would in JavaScript.
We are applying keys/methods relative to each $product within the $productCollection to construct the view
of the $product. Foreach does this for every $product within $productCollection, which in turn generates the
multi-item carousel list.
*/ ?>
<li class="item text-center product_viewMoreCarousel_item">
<?php /* Using PHP to generate the anchor tag of each $product by using keys/methods of $product to generate the string
This works well within the confines of Magento, but I'd go a different route anywhere else. the static '?carousel'
could change, making debugging a pain. An alternative would be to provide the query string as a reference key within the $productCollection
model, then call it here like we are any other key/method of $productCollection */?>
<a href="<?php echo $product->getProductUrl() ?>?carousel=<?php echo $this->tracking_value; ?>" title="<?php echo $this->htmlEscape($product->getName()) ?>" class="product-image">
<?php // Same string generation technique, now used in creating the img src but without any static strings laying about. ?>
<img src="<?php echo $this->helper('catalog/image')->init($product, 'small_image')->getGalleryThumbnail(); ?>"
alt="<?php echo $this->htmlEscape($product->getName()) ?>"/>
</a>
<p class="product-name">
<a href="<?php echo $product->getProductUrl() ?>"><?php echo $this->htmlEscape($product->getName()) ?></a>
</p>
<?php echo $this->getPriceHtml($product, true, '-upsell') ?>
</li>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>
<?php
// DRUPAL SNIPPET
/*
This snippet is something I enjoyed crafting years ago (which explains why the rest of the site is broken).
The portfolio page found here: http://researchwins.com/governor-ann-richards-texas renders a node of a client via a
paginated list of clients. The client was dead set on wanting the individual client Node pages to contain a carousel with a
very specific behavior. The following code does just that.
*/?>
<?php
/* The magic trick came in building the carousel out directly as it existed in the database. The initial issue with this carousel
was that clients could technically exist as nodes, even if they had not been published within Drupal. A nice feature for content
admins. A pain for devs to figure out a way around quickly. The solution queries the database and builds out $nids, checking first
for a status of 1, aka 'published'. Looking at this code now, I could have altered some things. I don't think querying the database directly
is the greatest of ideas here, from a security standpoint. The variable naming is also not very accurate. Readability could be improved by abstracting out
the RAND() method and applying a filter or sort against the array that is generated for a more functional approach. */
$nids = db_query("SELECT n.nid FROM {node} n WHERE n.status = 1 AND n.type = :type AND n.nid <> :nid ORDER BY RAND() LIMIT 0,40", array(':type' => 'portfolio', ':nid' => $node->nid))->fetchCol();
$nodes = node_load_multiple($nids);
?>
<?php if (!empty($nodes)): // Conditionally check that their are clients to build the carousel. ?>
<div class="row">
<h2 class="title"><span><?php print t('clients'); ?></span></h2>
<div class="clear"></div>
<div class="half_padded_block carousel_section">
<div class='carousel_arrows_bgr'></div>
<ul id="portfolio_carousel">
<?php foreach ($nodes as $node) : ?>
<?php $field_image = field_get_items('node', $node, 'field_image'); ?>
<?php if (!empty($field_image)): // Conditionally check for a client Node image. If it doesn't exist, we return a defaultoverlay image ?>
<li class="four columns portfolio_item">
<a href="<?php print url('node/' . $node->nid); ?>" title="<?php print $node->title; ?>">
<span class="pic"><?php print theme('image_style', array('style_name' => 'portfolio_item', 'path' => $field_image[0]['uri'])); ?><div class="img_overlay"></div></span>
<h5><?php print $node->title; ?></h5>
</a>
</li>
<?php endif; ?>
<?php endforeach; ?>
</ul>
</div>
</div>
<?php endif; ?>
<?php
// DRUPAL SNIPPET
/*
This snippet solved an issue that existed within earlier versions of Drupal 7, but has since been patched.
The issue revolved around how "state" in taxonomy views was maintained upon window.location navigation.
The homepage (dev example) found here: http://dev-greg-olsen-art.pantheonsite.io/ displays a list of types
of art near the bottom of the page. The client wanted the user experience to be that when an art type was clicked,
the URL navigates to the main shop page, but with all the shop items prefiltered based on the art type the user
had previously clicked on. The solution came in the form of a custom Drupal module, part of which can be seen below.
*/?>
<?php
/**
* Implements hook_block_info().
*
* This connects the custom module into Drupal's native block hook.
*/
function greg_olsen_filter_block_info() {
$blocks['greg_olsen_filter'] = array(
'info' => t('Greg Olsen Filter'),
);
return $blocks;
}
/*
*
* Implements hook_block_view().
*
* A View instance (Drupal specific module) was in charge of rendering the visible blocks.
* With Drupal's block successfully hooked into, we now hook into the main View. This
* is where parameters controlling how blocks with relevant taxonomy data are rendered.
*
*/
function greg_olsen_filter_block_view($delta = '') { // '$delta' is Drupal's reference to an id
// Set relevant taxonomy to reference variable '$art_vocab'. This is essentially the parent data tree.
$art_vocab = taxonomy_vocabulary_machine_name_load("homepage_taxonomy");
// Sets reference and initial behavior of children to '$art_vocab' as '$art_terms'
$art_terms = taxonomy_get_tree($art_vocab->vid, 0, null, TRUE);
//dsm($art_terms);
// We define a new array to hold the relevant blocks.
$block = array();
//...then provide a switch case by which to determine if a prefiltered View is necessary on URL navigation.
switch ($delta) {
case 'greg_olsen_filter':
$block['content'] = "content";
$block['terms'] = $art_terms;
break;
case 'ad_banner2':
$block['content'] = 'shtuffenins2';
break;
}
return $block;
}
?>
<?php
// DRUPAL SNIPPET
/*
Engineering has its ups as well as its downs. One such negative experince gave rise
to the creation of the code snippet below, as well as a complimentary full on custom
Drupal distro (written in PHP ofcourse) shown here: https://github.com/DaneTheory/drupal-uberman
While working for an agency years ago, a client stole a finished copy of their website from our servers.
Database and all, without payment. 'Stole' might be too strong a word, more like our CEO had given them
root access for God only knows why, and they walked in and strolled out. New site and all. As such, my dev
team and I were given the task of human-error proofing anything and everything. The code below represents one
layer of that solution. This snippet serves to override the registration process for creating the first user in
a fresh Drupal installation, aka the 'Super User'. During development, the agency would have a garunteed backdoor
into all WIP's. What is not shown in this snippet is the piece of code that, upon client payment, resets the 'Super User'
Access rights back to default.
*/?>
<?php // Two seperate snippets make this magic happen. This is the first. ?>
<?php
/*
* Found in the .profile file
*
* Implements hook_form_FORM_ID_alter().
* Allows the profile to alter the site configuration form.
* IMPORTANT!: MAKE SURE TO EDIT THE FIELDS THAT BEGIN WITH 'ADD'.
*
*/
if (!function_exists("system_form_install_configure_form_alter")) {
function system_form_install_configure_form_alter(&$form, $form_state) {
$form['site_information']['site_name']['#default_value'] = 'ADD YOUR PREFERRED DEFAULT USER/ADMIN NAME HERE!!!!!! Ex: Clark Kent';
}
}
/**
* Implements hook_form_alter().
*
* Select the current install profile by default.
*/
if (!function_exists("system_form_install_select_profile_form_alter")) {
function system_form_install_select_profile_form_alter(&$form, $form_state) {
foreach ($form['profile'] as $key => $element) {
$form['profile'][$key]['#value'] = 'uberman_drupal';
}
}
}
?>
<?php
/*
I'm sure this method has been patched by now. It's pretty hacky, not to mention the potential
for serious abuse.
*/?>
<?php // Here is the second snippet that brings it all together. ?>
<?php
/*
* Found in .install file
*
* Implements hook_install().
* Perform actions to set up the site for this profile.
*/
function uberman_drupal_install() {
// Enable some Uberman Drupal blocks.
$default_theme = 'responsive_bartik';
$admin_theme = 'adminimal';
// disable all themes
db_update('system')
->fields(array('status' => 0))
->condition('type', 'theme')
->execute();
// enable $default_theme
db_update('system')
->fields(array('status' => 1))
->condition('type', 'theme')
->condition('name', $default_theme)
->execute();
// enable $admin_theme
db_update('system')
->fields(array('status' => 1))
->condition('type', 'theme')
->condition('name', $admin_theme)
->execute();
variable_set('theme_default', $default_theme);
variable_set('admin_theme', $admin_theme);
// activate admin theme when editing a node
variable_set('node_admin_theme', '1');
$blocks = array(
array(
'module' => 'system',
'delta' => 'main',
'theme' => $default_theme,
'status' => 1,
'weight' => 0,
'region' => 'content',
'pages' => '',
'cache' => -1,
),
array(
'module' => 'user',
'delta' => 'login',
'theme' => $default_theme,
'status' => 1,
'weight' => 0,
'region' => 'sidebar_first',
'pages' => '',
'cache' => -1,
),
array(
'module' => 'system',
'delta' => 'help',
'theme' => $default_theme,
'status' => 1,
'weight' => -10,
'region' => 'content',
'pages' => '',
'cache' => -1,
),
array(
'module' => 'system',
'delta' => 'main',
'theme' => $admin_theme,
'status' => 1,
'weight' => 0,
'region' => 'content',
'pages' => '',
'cache' => -1,
),
array(
'module' => 'system',
'delta' => 'help',
'theme' => $admin_theme,
'status' => 1,
'weight' => 0,
'region' => 'help',
'pages' => '',
'cache' => -1,
),
);
// drop system / user blocks to ensure correct building
db_delete('block')->condition('module', 'system')->execute();
db_delete('block')->condition('module', 'user')->execute();
// add in our blocks defined above
$query = db_insert('block')->fields(array('module', 'delta', 'theme', 'status', 'weight', 'region', 'pages', 'cache'));
foreach ($blocks as $block) {
$query->values($block);
}
$query->execute();
// Create a default role for site administrators, with all available permissions assigned.
$admin_role = new stdClass();
$admin_role->name = 'administrator';
$admin_role->weight = 10;
user_role_save($admin_role);
user_role_grant_permissions($admin_role->rid, array_keys(module_invoke_all('permission')));
// Set this as the administrator role.
variable_set('user_admin_role', $admin_role->rid);
// Assign user 1 the "administrator" role.
db_insert('users_roles')
->fields(array('uid' => 1, 'rid' => $admin_role->rid))
->execute();
// Update the menu router information.
menu_rebuild();
// revert features to ensure they are all installed
$features = array(
'flexslider_example',
'video_presets'
);
features_revert($features);
// ignore any rebuild messages
node_access_needs_rebuild(FALSE);
// ignore any other install messages
drupal_get_messages();
}
?>
<?php
/* Looking back on it now, I would change some things, though it's nothing code related.
This is not to say my code is in anyway at all perfect. All and all this experience
cost the company thousands. More money was then spent on the time it took to create
a human-proof solution, when really what needed to be changed wasn't any code, but
rather internal processes within the company itself. That's as elegant a solution
as they come.
I hope you enjoyed this last snippet. It was more for a good story than serious code critique.
Cheers!
*/?>
# IMPORTANT: In order to adhere to NDA agreements, sensative information has been redacted.
# Refer to Vagrantfile first to better understand how the provision script works.
# Sync Nginx from remote to local VM
cp -R /www/configs/nginx/sites/* /etc/nginx/sites-available/
cp -R /www/configs/nginx/ssl/wildcard.REDACTED* /etc/nginx/ssl/
rm -f /etc/nginx/sites-enabled/*
ln -s -f /etc/nginx/sites-available/REDACTED.conf /etc/nginx/sites-enabled/
ln -s -f /etc/nginx/sites-available/REDACTED.conf /etc/nginx/sites-enabled/
ln -s -f /etc/nginx/sites-available/REDACTED.conf /etc/nginx/sites-enabled/
ln -s -f /etc/nginx/sites-available/REDACTED.conf /etc/nginx/sites-enabled/
# Sync PHP
cp -R /www/configs/php/conf.d/* /etc/php.d/
# Sync Redis
cp /www/configs/redis/redis.conf /etc/redis.conf
# Sync Magento
cp -R /www/sites/REDACTED/configs/magento/local/app/etc/* /www/sites/REDACTED/source/app/etc/
# Set Magento Permissions
MAGENTO_ROOT="/www/sites/REDACTED/source";
if [ -d "$MAGENTO_ROOT" ]; then
rm -rf $MAGENTO_ROOT/var/cache/*
rm -rf $MAGENTO_ROOT/var/session/*
chmod 755 -R $MAGENTO_ROOT/var
fi
# Syncdat and dis (tm)
cp /www/vagrant/scripts/syncdat /usr/bin/ # Script that calls down ALL images from remote to local. Not included.
chmod a+x /usr/bin/syncdat
cp /www/vagrant/scripts/syncwysiwyg /usr/bin/
chmod a+x /usr/bin/syncwysiwyg
REDACTED
REDACTED
REDACTED
# Let's do media assets
REDACTED
# Gulp
if [ ! -f '/usr/bin/npm' ]; then
yum install npm -y
fi
cd ~/
cp -R /www/sites/REDACTED/configs/gulp/* ~/
npm install -g gulp
npm install
if [ ! -f '/usr/bin/sass' ]; then
yum install rubygems -y
gem install sass
fi
killall gulp
sudo gulp >> /tmp/gulp.log &
# Restart services
service nginx start
service php-fpm start
service mysql start
service memcached start
service redis start
initctl stop api
initctl start api
# Looking back on this now, I'd remove the dependency on Ruby gems and use gulp-sass instead
"""
-------------
TASKS
-------------
Description:
*) The following code block is used to create various tasks meant to run on Quickframe's server.
(QuickFrame's stack is Python on the backend with Django for templating, and React/Nunjucks on the frontend)
Tasks Defined:
1) create_feed_events
args: user_profiles,
event_user_profile,
event_type,
object_type=None,
object_id=None,
title=None,
event_end_timestamp=None,
category=None,
text1=None,
text2=None,
thumbnail=None,
video=None,
url=None
2) create_html_email_body
args: body
3) send_email
args: email,
subject,
body,
from_label=None,
send_dup=True
4) create_stripe_account
args: username,
email,
ip
5) transcode_video
args: video,
downloadable_copy=True,
max_video_seconds=600
6) generate_welcome_email
args: username,
email
7) update_competition_embed_js_old
args: competitionID,
videoLimit=500
8) update_competition_embed_js
args: competitionID,
videoLimit=500
Note:
*) What I found most exciting was how close the syntax/logic was to
writting JavaScript in ES6. The learning curve was decisively easier, save for Python speciffic nuisances.
*) Python is admittedly one of my weaker languages. Looking at it again, I could have refactored this
significantly to scale better and for better organization overall.
"""
# DECLARE IMPORTS
from celery import Celery
import boto
conn = boto.connect_ses()
from boto.exception import BotoServerError
from django.db import models, connection
from quickframe.globals import pipeline_id, site, stripe, website_type
from quickframe.settings import STATIC_URL
from quickframe.utilities import get_ip_address2, ordinal
import json
import multiprocessing
from datetime import date, datetime
import time
import logging
import urllib
# DECLARE VARS
app = Celery('tasks', broker='amqp://guest@localhost//')
logger = logging.getLogger(__name__)
# TASK: create_feed_events
@app.task
def create_feed_events(user_profiles, event_user_profile, event_type, object_type=None, object_id=None, title=None, event_end_timestamp=None, category=None, text1=None, text2=None, thumbnail=None, video=None, url=None):
import django
django.setup()
from qf.models import Feed
# Check value comparison truthyness
"""
(This has a bit more logic to it than a simple condition check. Abstracting the cursor execution logic back to the original
model would clean this up).
"""
if user_profiles == "followers":
cursor = connection.cursor()
cursor.execute("select from_userprofile_id as id from user_profile_following where to_userprofile_id = {}".format(event_user_profile.id))
user_profiles = [id for (id,) in cursor]
cursor.close()
# Create Feed object via argz provided to the parent.
"""
(Importing the argz of 'Feed.objects.create' as a List refferenced elsewhere would help in scaling. The argz could then
simply be key value pairs from the List)
"""
Feed.objects.create(user_profiles = user_profiles,
event_user_profile = event_user_profile,
event_type = event_type,
object_type = object_type,
object_id = object_id,
title = title,
event_end_timestamp = event_end_timestamp,
category = category,
text1 = text1,
text2 = text2,
thumbnail = thumbnail,
video = video,
url = url
)
# TASK: create_html_email_body
"""
(Old school way of building HTML from a string, and boy is it UGLY. Perhaps a more clever idea would be to have
saved the HTML as an XML tree referenced within another file, then import it, and finally run a .fromstring() against the
import. Scaling this as it stands is just asking for headaches later on. Also, for organizational purposes it might be better
tto have this task live somewhere closer to similar templating functions.)
"""
@app.task
def create_html_email_body(body):
import django
django.setup()
H = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
H += '<html xmlns="http://www.w3.org/1999/xhtml" style="width:100%;padding:0;margin:0;">'
H += '<head>'
H += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />'
H += '<meta name="viewport" content="width=device-width, initial-scale=1.0"/>'
H += '</head>'
H += '<body style="background:#EDEDED;width:100%;padding:0;margin:0;">'
H += '<table bgcolor="#EDEDED" style="background:#EDEDED;" align="center" border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td>'
H += ' <div style="margin:20px auto;max-width:600px;font-size:17px;color:#3b3b3b;border:1px solid #cecece;background:white;padding:15px 20px;">'
H += ' <div style="text-align:center;"><a href="' + site + '"><img src="https:' + STATIC_URL + 'img/QF_logotype_blue-250.png" alt="quickframe" style="width:250px;" /></a></div>'
H += body
H += " <div style='padding-top:30px;color:#B0B0B0;'>Happy filming,</div>"
H += " <div style='color:#B0B0B0;'>The Quickframe Team</div>"
H += " <div style='color:#B0B0B0;'>- New York City</div>"
H += ' <div style="text-align:center; padding-top:12px;">'
H += ' <a href="http://www.facebook.com/pages/QuickFrame/1413786062210479" style="text-align:right;padding:0 5px;"><img src="https:' + STATIC_URL + 'img/facebook-light-gray-hollow.png" alt="fb" height="30" width="30" /></a>'
H += ' <a href="http://www.twitter.com/quick_frame" style="text-align:right;padding:0 5px;"><img src="https:' + STATIC_URL + 'img/twitter-light-gray-hollow.png" alt="tw" height="30" width="30" /></a>'
H += ' <div style="padding-top:3px;"><a href="' + site + '/account_settings/" style="color:#B0B0B0;font-size:15px;">Email Preferences</a></div>'
H += ' <div style="padding-top:3px;color:#B0B0B0;font-size:13px;">Quickframe is an on-demand marketplace for original video</div>'
H += ' </div>'
H += ' </div>'
H += "</td></tr></tbody></table>"
H += '</body>'
H += '</html>'
return H
"""
^^^ Who doesn't love some old school css inlining and table classes when working with emails :)
"""
# TASK: send_email
@app.task
def send_email(email, subject, body, from_label=None, send_dup=True):
import django
django.setup()
"""
(Referencing these email addresses as an imported List would aid in scaling, rather than having to edit this line
everytime the company gets a new hire...)
"""
if "quickframe" in email and not email == "lucas@quickframe.com" and not email == "brett@quickframe.com" and not email == "daniel@quickframe.com" and not "branden@quickframe.com":
email = "contact@quickframe.com"
"""
(The use of 'and' in Python's conditionals, as oppossed to && in JS, is something I'm still wrapping my head around.
A ternary operator would work awesomely here in cleaning up the extra lines of code.)
"""
if from_label and from_label != "Quickframe":
source = from_label + " on Quickframe <contact@quickframe.com>"
else:
source = "Quickframe <contact@quickframe.com>"
body = create_html_email_body(body)
"""
(Using switch cases here instead would make this bit easier to read, and have no negative performance consequences.)
"""
if website_type == "prod":
response = conn.send_email( \
source = source,
subject = subject,
body = body,
format = "html",
to_addresses = [email]
)
if send_dup:
response = conn.send_email( \
source = "Quickframe <contact@quickframe.com>",
subject = subject,
body = email + "<br>" + body,
format = "html",
to_addresses = ["contact@quickframe.com"]
)
if "<Error>" in response:
send_email("contact@quickframe.com", "Error sending email", response)
elif website_type == "local":
pass
else:
response = conn.send_email( \
source = source,
subject = subject,
body = body,
format = "html",
to_addresses = ['brett.didonato@gmail.com']
#to_addresses = ["bounce@simulator.amazonses.com"]
)
# TASK: create_stripe_account
@app.task
def create_stripe_account(username, email, ip):
import django
django.setup()
from django.contrib.auth.models import User
from qf.models import UserProfile
# Create Stripe customer and managed account
"""
(Attempted to replicate the logic behind a JS Promise here with the try and catch, except as try and except.
Also, the last few involve handling emails and as such, could be better organized together elsewhere.)
"""
try:
customer_response = stripe.Customer.create(
description = username,
email = email
)
account_response = stripe.Account.create(
country = 'US',
email = email,
managed = True
)
account = stripe.Account.retrieve(account_response['id'])
account.tos_acceptance.date = datetime.now()
account.tos_acceptance.ip = ip
account.save()
user = User.objects.get(username=username)
userProfile = UserProfile.objects.get(user_id=user.id)
userProfile.stripe_customer_id = customer_response['id']
userProfile.stripe_managed_account_id = account_response['id']
userProfile.stripe_managed_account_secret_key = account_response['keys']['secret']
userProfile.stripe_managed_account_publishable_key = account_response['keys']['publishable']
userProfile.save()
except Exception as e:
subject = "Error creating stripe account - umhandled exception"
body = "username: " + username + "<br>"
body += "email: " + email + "<br>"
body += "ip: " + str(ip) + "<br>"
body += "Error: " + str(e)
send_email("contact@quickframe.com", subject, body, None, False)
return
# TASK: transcode_video
"""
(If I could do this over again, I would have written most of this logic as JavaScript, just for ease in how often this bit
gets reused through the server and client)
"""
@app.task
def transcode_video(video, downloadable_copy=True, max_video_seconds=600):
import django
django.setup()
from qf.models import UserProfile
boto.set_stream_logger('boto')
region = 'us-east-1'
input_object = {
'Key': 'video/temp/' + str(video.id),
'Container': 'auto',
'AspectRatio': 'auto',
'FrameRate': 'auto',
'Resolution': 'auto',
'Interlaced': 'auto'
}
if video.video_type == "QuickFrame":
input_key = video.quickframe.user_profile.image.name
elif video.video_type == "Video Request":
input_key = video.video_request.user_profile.image.name
elif video.video_type == "Video Pitch":
input_key = video.video_pitch.sponsor.image.name
else:
input_key = video.user_profile.image.name
minutes, seconds = divmod(max_video_seconds, 60)
duration = "00:%02d:%02d.000" % (minutes, seconds)
et = boto.connect_elastictranscoder()
"""
(Instead of hard coding these playback quality object settings into the file, importing them as Lists or objects
would have made better sense for sacling.)
"""
# Default 720P 13
preset_id = '1441766287320-ymhh4j'
output_objects = [{
'Key': 'video/video/' + str(video.id) + '.mp4',
'PresetId': preset_id,
'Rotate': 'auto',
'ThumbnailPattern': 'video/thumbnail/' + str(video.id) + '-{count}',
'Watermarks': [
{
'PresetWatermarkId': 'BottomRight',
'InputKey': input_key
},
{
'PresetWatermarkId': 'BottomLeft',
'InputKey': 'quickframe-watermark.png'
}
],
'Composition': [
{
'TimeSpan':
{
'Duration': duration
}
},
],
}]
logger.debug('creating Elastic Transcoder job for video')
et_create_job_response = et.create_job(pipeline_id, input_name=input_object, outputs=output_objects)
job_id = et_create_job_response['Job']['Id']
logger.debug('Elastic Transcoder job created with id' + str(job_id))
# Default 480P - 2
preset_id = '1447001162031-u52wb5'
output_objects = [{
'Key': 'low_video/video/' + str(video.id) + '.mp4',
'PresetId': preset_id,
'Rotate': 'auto',
'ThumbnailPattern': 'low_video/thumbnail/' + str(video.id) + '-{count}',
'Watermarks': [
{
'PresetWatermarkId': 'BottomRight',
'InputKey': input_key
},
{
'PresetWatermarkId': 'BottomLeft',
'InputKey': 'quickframe-watermark.png'
}
],
'Composition': [
{
'TimeSpan':
{
'Duration': duration
}
},
],
}]
logger.debug('creating Elastic Transcoder job for low video')
et_create_job_response = et.create_job(pipeline_id, input_name=input_object, outputs=output_objects)
job_id = et_create_job_response['Job']['Id']
logger.debug('Elastic Transcoder job created with id' + str(job_id))
# 1080P Downloadable Copy (No Watermarks)
if downloadable_copy:
preset_id = '1431775984263-rh6zz5'
output_objects = [{
'Key': 'downloadable_video/video/' + str(video.id) + '.mp4',
'PresetId': preset_id,
'Rotate': 'auto',
'ThumbnailPattern': 'downloadable_video/thumbnail/' + str(video.id) + '-{count}'
}]
logger.debug('creating Elastic Transcoder job for downloadable video')
et_create_job_response = et.create_job(pipeline_id, input_name=input_object, outputs=output_objects)
job_id = et_create_job_response['Job']['Id']
logger.debug('Elastic Transcoder job created with id' + str(job_id))
# TASK: generate_welcome_email
"""
(Another HTML string that could have been generated differently. Also, this is another task relevant to email.
Should have gone back and abstracted these tasks into a seperate email handler file.)
"""
@app.task
def generate_welcome_email(username, email):
import django
django.setup()
from quickframe.utilities import email_show_live_competitions
subject = "Get started on Quickframe, " + username
body = ""
body += "<p>Hi " + username + ",</p>"
body += "<p>Thanks for joining Quickframe! We are an on-demand marketplace for original video. Get paid to make video or just have fun with our 10,000+ member community - it's up to you!</p>"
body += "<p>Get started by submitting a video or voting on one of our live competitions...</p>"
body += email_show_live_competitions()
body += "<div style='padding:40px 0 5px;'>Or challenge the Quickframe community and start your own competition...</p>"
body += "<div style='text-align:center;margin:0 auto;width:100%;'><a href='" + site + "/start_video_competition/' style='display:block;background:#3fa5c3;width:100%;padding:12px 0;font-size:18px;color:white;text-decoration:none;margin:5px 0;'>Start A New Video Competition</a></div>"
send_email(email, subject, body, None, True)
# TASK: update_competition_embed_js_old
"""
(Had to leave this function here when writting this file to stay backwards compatible with existing codebase.)
"""
@app.task
def update_competition_embed_js_old(competitionID, videoLimit=500):
from qf.models import Quickframe
from quickframe.settings import MEDIA_URL
from quickframe.globals import s3_media_bucket_name
competition = Quickframe.objects.get(id=competitionID)
cursor = connection.cursor()
cursor.execute("""SELECT v.id AS video_id,
count(f.id) AS votes,
v.video AS video,
v.low_video,
v.thumbnail,
v.low_thumbnail,
v.low_video_status,
u.username
FROM video v
LEFT JOIN user_profile up
ON v.user_profile_id = up.id
LEFT JOIN auth_user u
ON up.user_id = u.id
LEFT OUTER JOIN favorite f
ON v.id = f.video_id
WHERE v.quickframe_id = {}
AND v.video_type = 'QuickFrame'
AND v.is_active
AND v.video_status = 'Ready'
AND v.video != ''
GROUP BY v.id, u.username
ORDER BY votes DESC, v.id ASC
LIMIT {}""".format(competitionID, videoLimit))
videoCount = cursor.rowcount
if videoCount == 0:
if competition.promotional_video:
format = "promo only"
else:
format = "empty"
else:
format = "playlist"
X = 'document.getElementById("quickframe-embed-wrapper-' + str(competition.id) + '").innerHTML = "';
X += "<style>"
#X += "#quickframe-embed ::-webkit-scrollbar {"
#X += "-webkit-appearance:none;"
#X += "width:3px;"
#X += "}"
#X += "#quickframe-embed ::-webkit-scrollbar-thumb {background-color:#" + competition.embed_primary_color + ";}"
X += "#quickframe-embed {font-family:" + competition.embed_font + " !important;color:" + competition.embed_text_color + ";background:" + competition.embed_background_color + ";margin:" + competition.embed_margin + ";padding:" + competition.embed_padding + ";}"
X += ".quickframe-thumbnail-wrapper > img {border:3px solid #bcbcbc;}"
X += "#current-quickframe-video-thumbnail {border:3px solid #" + competition.embed_primary_color + ";}"
X += "</style>"
X += "<div id='quickframe-embed'>"
if True: # don't show ad
if competition.embed_show_title:
X += "<div style='font-size:28px;font-weight:300;'>" + competition.title.upper() + "</div>"
if competition.embed_show_description:
X += "<div style='font-size:16px;font-weight:300;'>" + competition.text + "</div>";
else: # show ad
if competition.embed_show_title:
X += "<div style='font-size:28px;font-weight:300;'>" + competition.title.upper() + " VIDEO COMPETITION</div>"
X += "<div style='display:inline-table; width:80%;'>"
if competition.embed_show_description:
X += "<div style='font-size:16px;font-weight:300;'>" + competition.text + "</div>";
X += "</div>"
X += "<div style='display:inline-table; width:20%; vertical-align:bottom; text-align:center; color:white; background-color:lightgray;'>"
X += "<div style='padding: 35px 0;'>AD GOES HERE</div>"
X += "</div>"
if format == "promo only":
X += "<hr style='margin:15px 0;padding:0;height:0;border-style:solid none none none;border-top:1px solid #cecece;'>"
if competition.promotional_video.low_video_status == 'Ready':
X += "<video style='width:100%;max-height:450px;background-color:black;' controls poster='https:" + MEDIA_URL + str(competition.promotional_video.low_thumbnail) + "'>"
else:
X += "<video style='width:100%;max-height:450px;background-color:black;' controls poster='https:" + MEDIA_URL + str(competition.promotional_video.thumbnail) + "'>"
X += "<source src='https:" + MEDIA_URL + str(competition.promotional_video.video) + "' type='video/mp4'>"
X += "</video>"
elif format == "playlist":
X += "<hr style='margin:15px 0;padding:0;height:0;border-style:solid none none none;border-top:1px solid #cecece;'>"
if competition.promotional_video:
X += "<div id='quickframe-video-section-wrapper' style='vertical-align:top;'>"
X += "<div id='quickframe-video-wrapper'>"
if competition.promotional_video.low_video_status == 'Ready':
X += "<video style='margin:0;background-color:black;' controls poster='https:" + MEDIA_URL + str(competition.promotional_video.low_thumbnail) + "'>"
else:
X += "<video style='margin:0;background-color:black;' controls poster='https:" + MEDIA_URL + str(competition.promotional_video.thumbnail) + "'>"
X += "<source src='https:" + MEDIA_URL + str(competition.promotional_video.video) + "' type='video/mp4'>"
X += "</video>"
X += "<div id='quickframe-promo-label-wrapper' style='width:100%;display:inline-block;vertical-align:top;'><div style='font-size:17px;padding:0 15px;line-height:40px;font-weight:300;color:white;background-color:#bcbcbc;white-space:nowrap;overflow:hidden;text-align:center;display:block;'>PROMOTIONAL VIDEO</div></div>"
X += "</div>"
X += "</div>"
X += "<div id='quickframe-playlist'>"
if competition.promotional_video.low_video_status == 'Ready':
X += "<div id='quickframe-thumbnail-wrapper-promo' class='quickframe-thumbnail-wrapper' style='cursor:pointer;' onclick='changeQuickframeVideo(&quot;&quot;,&quot;&quot;,&quot;promo&quot;,&quot;&quot;,&quot;&quot;)'><img id='current-quickframe-video-thumbnail' src='https:" + MEDIA_URL + str(competition.promotional_video.low_thumbnail) + "' style='width:calc(100% - 7px);margin:0 0 4px 0;'/></div>"
else:
X += "<div id='quickframe-thumbnail-wrapper-promo' class='quickframe-thumbnail-wrapper' style='cursor:pointer;' onclick='changeQuickframeVideo(&quot;&quot;,&quot;&quot;,&quot;promo&quot;,&quot;&quot;,&quot;&quot;)'><img id='current-quickframe-video-thumbnail' src='https:" + MEDIA_URL + str(competition.promotional_video.thumbnail) + "' style='width:calc(100% - 7px);margin:0 0 4px 0;'/></div>"
X += "<div class='quickframe-thumbnail-label' style='position:relative;left:-3px;height:25px;color:white;font-size:14px;font-weight:600;pointer-events:none;text-align:center;overflow:hidden;'>PROMO VIDEO</div>"
rank = 1
for (video_id, votes, video, low_video, thumbnail, low_thumbnail, low_video_status, username) in cursor:
if rank == 1 and not competition.promotional_video:
X += "<div id='quickframe-video-section-wrapper' style='vertical-align:top;'>"
X += "<div id='quickframe-video-wrapper'>"
X += "<video style='margin:0;background-color:black;' controls poster='https:" + MEDIA_URL + str(thumbnail) + "'>"
if low_video_status == 'Ready':
X += "<source src='https:" + MEDIA_URL + low_video + "' type='video/mp4'>"
else:
X += "<source src='https:" + MEDIA_URL + video + "' type='video/mp4'>"
X += "</video>"
X += "<div id='quickframe-vote-div' onclick='quickframeVideoVote(" + str(video_id) + ")' style='display:inline-block;vertical-align:top;cursor:pointer;color:white;text-align:center;font-size:20px;background-color:#" + competition.embed_primary_color + ";'><div style='padding:0 8px;line-height:40px;'>VOTE</div></div>"
if competition.is_active:
X += "<div id='quickframe-video-desc-div' style='display:inline-block;vertical-align:top;'><div style='font-size:15px;font-weight:300;color:white;background-color:#bcbcbc;text-align:center;'>1ST PLACE VIDEO BY " + username.upper() + "</div></div>"
else:
X += "<div id='quickframe-video-desc-div' style='display:inline-block;vertical-align:top;'><div style='font-size:15px;font-weight:300;color:white;background-color:#bcbcbc;text-align:center;'>WINNING VIDEO BY " + username.upper() + "</div></div>"
X += "</div>"
X += "</div>"
X += "<div id='quickframe-playlist'>"
if low_video_status == 'Ready':
X += "<div id='quickframe-thumbnail-wrapper-" + str(video_id) + "' class='quickframe-thumbnail-wrapper' style='cursor:pointer;' onclick='changeQuickframeVideo(" + str(video_id) + ",&quot;" + username.upper() + "&quot;," + str(rank) + ",&quot;" + ordinal(rank).upper() + "&quot;,&quot;" + str(thumbnail) + "&quot;)'><img id='current-quickframe-video-thumbnail' src='https:" + MEDIA_URL + low_thumbnail + "' style='width:calc(100% - 7px);margin:0 0 4px 0;'/></div>"
else:
X += "<div id='quickframe-thumbnail-wrapper-" + str(video_id) + "' class='quickframe-thumbnail-wrapper' style='cursor:pointer;' onclick='changeQuickframeVideo(" + str(video_id) + ",&quot;" + username.upper() + "&quot;," + str(rank) + ",&quot;" + ordinal(rank).upper() + "&quot;,&quot;" + str(thumbnail) + "&quot;)'><img id='current-quickframe-video-thumbnail' src='https:" + MEDIA_URL + thumbnail + "' style='width:calc(100% - 7px);margin:0 0 4px 0;'/></div>"
else:
if low_video_status == 'Ready':
X += "<div id='quickframe-thumbnail-wrapper-" + str(video_id) + "' class='quickframe-thumbnail-wrapper' style='cursor:pointer;' onclick='changeQuickframeVideo(" + str(video_id) + ",&quot;" + username.upper() + "&quot;," + str(rank) + ",&quot;" + ordinal(rank).upper() + "&quot;,&quot;" + str(thumbnail) + "&quot;)'><img src='https:" + MEDIA_URL + low_thumbnail + "' style='width:calc(100% - 7px);margin:0 0 4px 0;'/></div>"
else:
X += "<div id='quickframe-thumbnail-wrapper-" + str(video_id) + "' class='quickframe-thumbnail-wrapper' style='cursor:pointer;' onclick='changeQuickframeVideo(" + str(video_id) + ",&quot;" + username.upper() + "&quot;," + str(rank) + ",&quot;" + ordinal(rank).upper() + "&quot;,&quot;" + str(thumbnail) + "&quot;)'><img src='https:" + MEDIA_URL + thumbnail + "' style='width:calc(100% - 7px);margin:0 0 4px 0;'/></div>"
X += "<div class='quickframe-thumbnail-label' style='position:relative;height:25px;color:white;font-size:14px;font-weight:600;pointer-events:none;'>#" + str(rank) + "</div>"
if rank == 1 and competition.embed_playlist_ad_image and competition.embed_playlist_ad_link:
X += "<a id='quickframe-playlist-ad' href='" + competition.embed_playlist_ad_link + "' target='_blank' style='border:0;'><img src='" + MEDIA_URL + str(competition.embed_playlist_ad_image) + "' style='border:' /></a>"
rank = rank + 1
X += "</div>";
# Award Display
awardDisplay = ""
if competition.award_type == "Cash":
awardDisplay = "$" + str(int(competition.award_amount))
elif competition.award_type == "Prize":
awardDisplay = competition.award_description
else:
awardDisplay = "Just for fun"
X += "<hr style='margin:15px 0;padding:0;height:0;border-style:solid none none none;border-top:1px solid #cecece;'>"
X += "<div id='quickframe-submit' style='cursor:pointer;text-align:center;'><div onclick='submitQuickframeVideo();' style='background-color:#" + competition.embed_primary_color + ";text-align:center;padding:0;line-height:50px;font-size:20px;border:0;color:" + competition.embed_primary_text_color + ";text-decoration:none;display:block;'>SUBMIT VIDEO</div></div>"
X += "<div id='quickframe-countdown-wrapper' style='vertical-align:top;text-align:center;color:white;font-size:15px;'><div style='text-align:center;padding:0;height:50px;line-height:50px;background-color:#bcbcbc;'><span>VOTING ENDS <span style='font-size:1.3em;line-height:50px;color:#" + competition.embed_primary_color + ";'>&raquo;</span> </span><span id='quickframe-countdown' data-date='" + competition.end_timestamp.strftime('%s') + "'>" + competition.end_timestamp.strftime('%x') + "</span></div></div>"
X += "<div style='display:inline-block;width:33.33%;text-align:center;line-height:50px;'><div onclick='window.location.href=&#39;http://www.facebook.com/sharer/sharer.php?u=&#39; + window.location.href;' style='color:#3b3b3b;cursor:pointer;'><img src='https://static.quickframe.com/img/facebook-100-gray.png' alt='facebook' style='vertical-align:middle;height:30px;width:30px;margin-right:5px;'><span class='quickframe-social-text'> FACEBOOK</span></div></div>"
X += "<div style='display:inline-block;width:33.33%;text-align:center;line-height:50px;'><div onclick='window.location.href=&#39;https://twitter.com/share?text=" + urllib.parse.quote_plus(competition.title) + ":%20&url=&#39; + window.location.href;' title='Tweet' style='color:#3b3b3b;cursor:pointer;'><img src='https://static.quickframe.com/img/twitter-100-gray.png' alt='twitter' style='vertical-align:middle;height:30px;width:30px;margin-right:5px;' target='_blank'><span class='quickframe-social-text'> TWITTER</span></div></div>"
X += "<div style='display:inline-block;width:33.33%;text-align:center;line-height:50px;'><div onclick='window.location.href=&#39;mailto:?subject=" + competition.title + "&body=Submit your video to " + competition.title + ": &#39; + window.location.href;' style='color:#3b3b3b;cursor:pointer;'><img src='https://static.quickframe.com/img/email-100-gray.png' alt='email' style='vertical-align:middle;height:30px;width:30px;margin-right:5px;'><span class='quickframe-social-text'> EMAIL</span></div></div>"
X += "</div>"
X += '";';
X += "var quickframeWidth = document.getElementById('quickframe-embed-wrapper-" + str(competitionID) + "').offsetWidth;"
X += "var quickframeS = '';"
X += "if (quickframeWidth >= 500) {"
X += "quickframeS += '<style>';"
X += "quickframeS += '#quickframe-video-section-wrapper{display:inline-block; width:80%;}';"
X += "quickframeS += '#quickframe-embed-wrapper-" + str(competitionID) + " video{width:calc(100% - 7px);height:346px;}';"
X += "quickframeS += '#quickframe-playlist{display:inline-block;width:20%;height:392px;overflow-y:scroll;}';"
X += "quickframeS += '.quickframe-thumbnail-wrapper{width:100%;height:83px;vertical-align:top;}';"
X += "quickframeS += '.quickframe-thumbnail-label{display:block !important;margin:-25px 5px 0;}';"
X += "quickframeS += '#quickframe-promo-label-wrapper>div {margin:0 7px 0 0;}';"
X += "quickframeS += '#quickframe-vote-div{width:25%;}';"
X += "quickframeS += '#quickframe-video-desc-div{width:75%;line-height:40px;white-space:nowrap;overflow:hidden;}';"
X += "quickframeS += '#quickframe-video-desc-div>div{margin:0 7px;padding:0 15px;display:block;}';"
X += "quickframeS += '#quickframe-submit{width:50%;display:inline-table;}';"
X += "quickframeS += '#quickframe-countdown-wrapper{width:50%;display:inline-table;}';"
X += "quickframeS += '#quickframe-countdown-wrapper>div{margin-left:8px;display:block;}';"
X += "quickframeS += '</style>';"
X += "}"
X += "else {"
X += "quickframeS += '<style>';"
X += "quickframeS += '#quickframe-embed-wrapper-" + str(competitionID) + " hr{display:none;}';"
X += "quickframeS += '#quickframe-video-section-wrapper{width:100%;margin-top:10px;}';"
X += "quickframeS += '#quickframe-embed-wrapper-" + str(competitionID) + " video{width:100%;height:250px;}';"
X += "quickframeS += '#quickframe-playlist{margin-top:5px;width:100%;height:95px;overflow-x:scroll;white-space:nowrap;}';"
X += "quickframeS += '.quickframe-thumbnail-wrapper{width:130px;display:inline-table !important;vertical-align:top;}';"
X += "quickframeS += '.quickframe-thumbnail-label{display:block !important;margin:54px 0 0 -125px; width:125px;display:inline-table !important;vertical-align:top;}';"
X += "quickframeS += '#quickframe-playlist-ad > img { height:80px; }';"
X += "quickframeS += '#quickframe-promo-label-wrapper>div {margin:0;}';"
X += "quickframeS += '#quickframe-vote-div{width:100%;}';"
X += "quickframeS += '#quickframe-video-desc-div{width:100%;margin-top:5px;}';"
X += "quickframeS += '#quickframe-video-desc-div>div{padding:7px 15px;display:block;}';"
X += "quickframeS += '#quickframe-submit{width:100%;}';"
X += "quickframeS += '#quickframe-countdown-wrapper{width:100%;margin:5px 0 10px;}';"
X += "quickframeS += '.quickframe-social-text{display:none;}';"
X += "quickframeS += '</style>';"
X += "}"
X += "var quickframeC = document.createElement('div');"
X += "quickframeC.innerHTML = quickframeS;"
X += "quickframeC = quickframeC.firstChild;"
X += "document.getElementById('quickframe-embed-wrapper-" + str(competition.id) + "').appendChild(quickframeC);"
X += "Number.prototype.pad = function(size) {"
X += "var s = String(this);"
X += "while (s.length < (size || 2)) {s = '0' + s;}"
X += "return s;"
X += "}; "
X += "var countdown = document.getElementById('quickframe-countdown');"
X += "var target_date = countdown.getAttribute('data-date');"
X += "var days, hours, minutes, seconds;"
X += "setInterval(function () {"
X += "var current_date = new Date().getTime();"
X += "var seconds_left = (target_date - current_date / 1000);"
X += "if (seconds_left < 1) {"
X += " countdown.innerHTML = 'ENDED';"
X += "}"
X += "else {"
X += " days = parseInt(seconds_left / 86400);"
X += " seconds_left = seconds_left % 86400;"
X += " hours = parseInt(seconds_left / 3600);"
X += " seconds_left = seconds_left % 3600;"
X += " minutes = parseInt(seconds_left / 60);"
X += " seconds = parseInt(seconds_left % 60);"
X += " countdown.innerHTML = \"<span class='countdown-number'>\" + days.pad(2) + \"</span>D <span class='countdown-number'>\" + hours.pad(2) + \"</span>H <span class='countdown-number'>\" + minutes.pad(2) + \"</span>M <span class='countdown-number'>\" + seconds.pad(2) + \"</span>S\";"
X += "}"
X += "}, 1000);"
X += "function submitQuickframeVideo() {"
X += " var updateCurrentURL = quickframeAddParam(window.location.href,'quickframe_action','upload');"
X += " updateCurrentURL = quickframeRemoveParam(updateCurrentURL, 'quickframe_vote');"
X += " updateCurrentURL = quickframeRemoveParam(updateCurrentURL, 'quickframe_video');"
X += " updateCurrentURL = updateCurrentURL.replace(/&/g, '%26');"
#X += " var next = '/embed/redirect/' + encodeURI(updateCurrentURL).replace('?', '%3F');"
X += " var next = 'embed/redirect/' + encodeURIComponent(updateCurrentURL);"
#X += " var next = '/embed/redirect/' + updateCurrentURL;"
X += " showOverlayWithURL('" + site + "/embed/competition/submit/?competition=" + str(competitionID) + "&primary_color=" + competition.embed_primary_color + "&next=' + next);"
X += "}"
X += "function quickframeVideoVote(video_id) {"
X += " var updateCurrentURL = quickframeAddParam(window.location.href,'quickframe_vote',video_id);"
X += " updateCurrentURL = quickframeRemoveParam(updateCurrentURL, 'quickframe_action');"
X += " updateCurrentURL = quickframeRemoveParam(updateCurrentURL, 'quickframe_video');"
X += " updateCurrentURL = updateCurrentURL.replace(/&/g, '%26');"
#X += " var next = '/embed/redirect/' + updateCurrentURL;"
X += " var next = 'embed/redirect/' + encodeURIComponent(updateCurrentURL);"
X += " showOverlayWithURL('" + site + "/embed/competition/vote/?object_type=Video&object_id=' + video_id + '&primary_color=" + competition.embed_primary_color + "&next=' + next);"
X += "}"
X += "function showOverlayWithURL(url) {"
X += " var overlayDiv = document.createElement('div');"
X += " overlayDiv.id = 'quickframe-overlay-div';"
X += " overlayDiv.innerHTML = \"<iframe id='quickframe-overlay' allowtransparency='true' frameborder='0' scrolling='no' tabindex='0' title='Quickframe' width='100%' src='\" + url + \"' style='width: 100% !important; border: none !important; overflow: hidden !important; height: 100% !important; position: fixed !important; top: 0px !important; right: 0px !important; left: auto !important; bottom: auto !important; z-index: 2147483647 !important;'></iframe>\";"
X += " document.body.appendChild(overlayDiv);"
X += "}"
X += "function quickframeAddParam(url, param, value) {"
X += " var a = document.createElement('a'), regex = /(?:\?|&amp;|&)+([^=]+)(?:=([^&]*))*/g;"
X += " var match, str = []; a.href = url; param = encodeURIComponent(param);"
X += " while (match = regex.exec(a.search))"
X += " if (param != match[1]) str.push(match[1]+(match[2]?'='+match[2]:''));"
X += " str.push(param+(value?'='+ encodeURIComponent(value):''));"
X += " a.search = str.join('&');"
X += " return a.href;"
X += "}"
X += "function quickframeRemoveParam(url, parameter) {"
X += " var urlparts= url.split('?');"
X += " if (urlparts.length>=2) {"
X += " var prefix= encodeURIComponent(parameter)+'=';"
X += " var pars= urlparts[1].split(/[&;]/g);"
X += " for (var i= pars.length; i-- > 0;) {"
X += " if (pars[i].lastIndexOf(prefix, 0) !== -1) {"
X += " pars.splice(i, 1);"
X += " }"
X += " }"
X += " url = urlparts[0]+'?'+pars.join('&');"
X += " return url;"
X += " } else {"
X += " return url;"
X += " }"
X += "}"
X += "function getParameterByName(name) {"
X += "name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');"
X += "var regex = new RegExp('[\\?&]' + name + '=([^&#]*)'),"
X += " results = regex.exec(location.search);"
X += "return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '));"
X += "}"
X += "function receiveMessage(event) {"
#X += " if (event.origin == 'https://www.quickframe.com' && event.data == 'close quickframe overlay') {"
#X += " console.log(event.data.substring(0,21));"
#X += " console.log(event.data.substring(21));"
X += " if (event.data == 'close quickframe overlay') {"
X += " var overlayDiv = document.getElementById('quickframe-overlay-div');"
X += " document.body.removeChild(overlayDiv);"
X += " }"
X += " else if (event.data.substring(0,21) == 'quickframe new video=') {"
X += " var video_id = event.data.substring(21);"
X += " var newURL = quickframeAddParam(window.location.href, 'quickframe_video', video_id);"
X += " newURL = quickframeRemoveParam(newURL, 'quickframe_action');"
X += " newURL = quickframeRemoveParam(newURL, 'quickframe_vote');"
X += " window.location.href = newURL;"
X += " }"
X += "}"
X += "addEventListener('message', receiveMessage, false);"
#X += "var quickframeVideoClicks = 0;"
X += "function changeQuickframeVideo(video_id, username, rank, rankDisplay, thumbnail) {"
X += "if (video_id < 1) { video_id = 'promo'; }";
X += "var newURL = quickframeAddParam(window.location.href, 'quickframe_video', video_id);"
X += "history.pushState('', '', newURL);"
#X += "if (quickframeVideoClicks>=3) {"
#X += " location.reload();"
#X += " return;"
#X += "}"
#X += "else {"
#X += " quickframeVideoClicks++;"
#X += "}"
if competition.promotional_video:
X += " if (rank == 'promo') {"
X += " var H = \"<video style='margin:0;background-color:black;' controls autoplay poster='https:" + MEDIA_URL + str(competition.promotional_video.thumbnail) + "'>\";"
if competition.promotional_video.low_video_status == 'Ready':
X += " H += \"<source src='https:" + MEDIA_URL + str(competition.promotional_video.low_video) + "' type='video/mp4'>\";"
else:
X += " H += \"<source src='https:" + MEDIA_URL + str(competition.promotional_video.video) + "' type='video/mp4'>\";"
X += " H += \"</video>\";"
X += " H += \"<div id='quickframe-promo-label-wrapper' style='width:100%;display:inline-block;vertical-align:top;'><div style='font-size:17px;padding:0 15px;line-height:40px;font-weight:300;color:white;background-color:#bcbcbc;white-space:nowrap;overflow:hidden;text-align:center;display:block;'>PROMOTIONAL VIDEO</div></div>\";"
X += " }"
else:
X += " if (0) {}"
X += " else {"
X += " var H = \"<video style='margin:0;background-color:black;' controls autoplay poster='https:" + MEDIA_URL + "\" + thumbnail + \"'><source src='https:" + MEDIA_URL + "low_video/video/\" + video_id + \".mp4' type='video/mp4'></video>\";"
X += " H += \"<div id='quickframe-vote-div' onclick='quickframeVideoVote(\" + video_id + \")' style='display:inline-block;cursor:pointer;vertical-align:top;color:white;text-align:center;font-size:20px;background-color:#" + competition.embed_primary_color + ";'><div style='padding:0 8px;line-height:40px;'>VOTE</div></div>\";"
X += " H += \"<div id='quickframe-video-desc-div' style='display:inline-block;vertical-align:top;'><div style='font-size:15px;font-weight:300;color:white;background-color:#bcbcbc;text-align:center;'>\" + rankDisplay + \" PLACE VIDEO BY \" + username + \"</div></div>\";"
X += " }"
X += " document.getElementById('quickframe-video-wrapper').innerHTML = H;"
X += " document.getElementById('current-quickframe-video-thumbnail').removeAttribute('id');"
X += " if (video_id > 0) {"
X += " document.getElementById('quickframe-thumbnail-wrapper-' + video_id).firstChild.setAttribute('id','current-quickframe-video-thumbnail');"
X += " var newURL = quickframeAddParam(window.location.href, 'quickframe_video', video_id);"
X += " }"
X += " else {"
X += " document.getElementById('quickframe-thumbnail-wrapper-promo').firstChild.setAttribute('id','current-quickframe-video-thumbnail');"
X += " var newURL = quickframeRemoveParam(window.location.href, 'quickframe_video');"
X += " }"
X += " history.pushState('', '', newURL);"
X += "}"
X += "var quickframeVideoID = getParameterByName('quickframe_video');"
X += "if (quickframeVideoID) {"
X += " var thumbnail = document.getElementById('quickframe-thumbnail-wrapper-' + quickframeVideoID);"
X += " if (thumbnail) {"
X += " thumbnail.click();"
X += " }"
X += " else {"
X += " var H = \"<video style='margin:0;background-color:black;' controls autoplay poster='https:" + MEDIA_URL + "quickframe-thumbnail.png'><source src='https:" + MEDIA_URL + "video/temp/\" + quickframeVideoID + \"' type='video/mp4'></video>\";"
X += " H += \"<div id='quickframe-vote-div' onclick='quickframeVideoVote(\" + quickframeVideoID + \")' style='display:inline-block;cursor:pointer;vertical-align:top;color:white;text-align:center;font-size:20px;background-color:#" + competition.embed_primary_color + ";'><div style='padding:0 8px;line-height:40px;'>VOTE</div></div>\";"
X += " H += \"<div id='quickframe-video-desc-div' style='display:inline-block;vertical-align:top;'><div style='font-size:15px;font-weight:300;color:white;background-color:#bcbcbc;text-align:center;'>YOUR " + ordinal(videoCount+1).upper() + " PLACE VIDEO</div></div>\";"
X += " document.getElementById('quickframe-video-wrapper').innerHTML = H;"
X += " document.getElementById('current-quickframe-video-thumbnail').removeAttribute('id');"
X += " }"
#X += " var topPos = thumbnail.offsetTop;"
#X += " console.log('topPos: ' + topPos);"
#X += " document.getElementById('quickframe-playlist').scrollTop = topPos;"
X += "}"
X += "var quickframeAction = getParameterByName('quickframe_action');"
X += "if (quickframeAction == 'upload') {"
X += " submitQuickframeVideo();"
X += "}"
X += "var quickframeVoteID = getParameterByName('quickframe_vote');"
X += "if (quickframeVoteID) {"
X += " quickframeVideoVote(quickframeVoteID)"
X += "}"
s3_conn = boto.connect_s3()
s3_bucket = s3_conn.get_bucket(s3_media_bucket_name)
from boto.s3.key import Key
s3_key = Key(s3_bucket)
s3_key.key = "quickframe/embed/" + str(competition.id) + "-2.js"
s3_key.set_contents_from_string(X)
# TASK: update_competition_embed_js
@app.task
def update_competition_embed_js(competitionID, videoLimit=500):
from qf.models import Quickframe
from quickframe.settings import MEDIA_URL
from quickframe.globals import s3_media_bucket_name
competition = Quickframe.objects.get(id=competitionID)
cursor = connection.cursor()
cursor.execute("""SELECT v.id AS video_id,
count(f.id) AS votes,
v.video AS video,
v.low_video,
v.thumbnail,
v.low_thumbnail,
v.low_video_status,
u.username
FROM video v
LEFT JOIN user_profile up
ON v.user_profile_id = up.id
LEFT JOIN auth_user u
ON up.user_id = u.id
LEFT OUTER JOIN favorite f
ON v.id = f.video_id
WHERE v.quickframe_id = {}
AND v.video_type = 'QuickFrame'
AND v.is_active
AND v.video_status = 'Ready'
AND v.video != ''
GROUP BY v.id, u.username
ORDER BY votes DESC, v.id ASC
LIMIT {}""".format(competitionID, videoLimit))
videoCount = cursor.rowcount
if videoCount == 0:
if competition.promotional_video:
format = "promo only"
else:
format = "empty"
else:
format = "playlist"
X = 'document.getElementById("quickframe-embed-wrapper-' + str(competition.id) + '").innerHTML = "';
X += "<style>"
X += "#quickframe-embed {font-family:" + competition.embed_font + " !important;color:" + competition.embed_text_color + ";background:" + competition.embed_background_color + ";margin:" + competition.embed_margin + ";padding:" + competition.embed_padding + ";}"
X += ".quickframe-thumbnail-wrapper > img {border:3px solid #bcbcbc;}"
X += "#current-quickframe-video-thumbnail {border:3px solid #" + competition.embed_primary_color + ";}"
X += "</style>"
X += "<div id='quickframe-embed'>"
if True: # don't show ad
if competition.embed_show_title:
X += "<div id='quickframe-title'>" + competition.title + "</div>"
if competition.embed_show_description:
X += "<div id='quickframe-desc'>" + competition.text + "</div>";
else: # show ad
if competition.embed_show_title:
X += "<div id='quickframe-title'>" + competition.title + "</div>"
X += "<div style='display:inline-table; width:80%;'>"
if competition.embed_show_description:
X += "<div id='quickframe-desc'>" + competition.text + "</div>";
X += "</div>"
X += "<div style='display:inline-table; width:20%; vertical-align:bottom; text-align:center; color:white; background-color:lightgray;'>"
X += "<div style='padding: 35px 0;'>AD GOES HERE</div>"
X += "</div>"
if format == "promo only":
if competition.promotional_video.low_video_status == 'Ready':
if competition.embed_video_autoplay:
X += "<video id='quickframe-promo-video' autoplay volume='0.5' style='width:100%;background-color:black;' controls poster='https:" + MEDIA_URL + str(competition.promotional_video.low_thumbnail) + "'>"
else:
X += "<video style='width:100%;background-color:black;' controls poster='https:" + MEDIA_URL + str(competition.promotional_video.low_thumbnail) + "'>"
else:
if competition.embed_video_autoplay:
X += "<video id='quickframe-promo-video' autoplay volume='0.5' style='width:100%;background-color:black;' controls poster='https:" + MEDIA_URL + str(competition.promotional_video.thumbnail) + "'>"
else:
X += "<video style='width:100%;background-color:black;' controls poster='https:" + MEDIA_URL + str(competition.promotional_video.thumbnail) + "'>"
X += "<source src='https:" + MEDIA_URL + str(competition.promotional_video.video) + "' type='video/mp4'>"
X += "</video>"
elif format == "playlist":
if competition.promotional_video:
X += "<div id='quickframe-video-section-wrapper' style='vertical-align:top;'>"
X += "<div id='quickframe-video-wrapper'>"
if competition.promotional_video.low_video_status == 'Ready':
if competition.embed_video_autoplay:
X += "<video id='quickframe-promo-video' autoplay style='margin:0;background-color:black;' controls poster='https:" + MEDIA_URL + str(competition.promotional_video.low_thumbnail) + "'>"
else:
X += "<video id='quickframe-promo-video' style='margin:0;background-color:black;' controls poster='https:" + MEDIA_URL + str(competition.promotional_video.low_thumbnail) + "'>"
else:
if competition.embed_video_autoplay:
X += "<video id='quickframe-promo-video' autoplay style='margin:0;background-color:black;' controls poster='https:" + MEDIA_URL + str(competition.promotional_video.thumbnail) + "'>"
else:
X += "<video id='quickframe-promo-video' style='margin:0;background-color:black;' controls poster='https:" + MEDIA_URL + str(competition.promotional_video.thumbnail) + "'>"
X += "<source src='https:" + MEDIA_URL + str(competition.promotional_video.video) + "' type='video/mp4'>"
X += "</video>"
X += "<div id='quickframe-promo-label-wrapper' style='width:100%;display:inline-block;vertical-align:top;'><div style='font-size:17px;padding:0 15px;line-height:40px;font-weight:300;color:white;background-color:#bcbcbc;white-space:nowrap;overflow:hidden;text-align:center;display:block;'>PROMOTIONAL VIDEO</div></div>"
X += "</div>"
X += "</div>"
X += "<div id='quickframe-playlist'>"
if competition.promotional_video.low_video_status == 'Ready':
X += "<div id='quickframe-thumbnail-wrapper-promo' class='quickframe-thumbnail-wrapper' style='cursor:pointer;' onclick='changeQuickframeVideo(&quot;&quot;,&quot;&quot;,&quot;promo&quot;,&quot;&quot;,&quot;&quot;)'><img id='current-quickframe-video-thumbnail' src='https:" + MEDIA_URL + str(competition.promotional_video.low_thumbnail) + "' style='width:calc(100% - 7px);margin:0 0 4px 0;'/></div>"
else:
X += "<div id='quickframe-thumbnail-wrapper-promo' class='quickframe-thumbnail-wrapper' style='cursor:pointer;' onclick='changeQuickframeVideo(&quot;&quot;,&quot;&quot;,&quot;promo&quot;,&quot;&quot;,&quot;&quot;)'><img id='current-quickframe-video-thumbnail' src='https:" + MEDIA_URL + str(competition.promotional_video.thumbnail) + "' style='width:calc(100% - 7px);margin:0 0 4px 0;'/></div>"
X += "<div class='quickframe-thumbnail-label' style='position:relative;left:-3px;height:25px;color:white;font-size:14px;font-weight:600;pointer-events:none;text-align:center;overflow:hidden;'>PROMO VIDEO</div>"
rank = 1
for (video_id, votes, video, low_video, thumbnail, low_thumbnail, low_video_status, username) in cursor:
if rank == 1 and not competition.promotional_video:
X += "<div id='quickframe-video-section-wrapper' style='vertical-align:top;'>"
X += "<div id='quickframe-video-wrapper'>"
X += "<video style='margin:0;background-color:black;' controls poster='https:" + MEDIA_URL + str(thumbnail) + "'>"
if low_video_status == 'Ready':
X += "<source src='https:" + MEDIA_URL + low_video + "' type='video/mp4'>"
else:
X += "<source src='https:" + MEDIA_URL + video + "' type='video/mp4'>"
X += "</video>"
X += "<div id='quickframe-vote-div' onclick='quickframeVideoVote(" + str(video_id) + ")' style='display:inline-block;vertical-align:top;cursor:pointer;color:white;text-align:center;font-size:20px;background-color:#" + competition.embed_primary_color + ";'><div style='padding:0 8px;line-height:40px;'>VOTE</div></div>"
if competition.is_active:
X += "<div id='quickframe-video-desc-div' style='display:inline-block;vertical-align:top;'><div style='font-size:15px;font-weight:300;color:white;background-color:#bcbcbc;text-align:center;'>1ST PLACE VIDEO BY " + username.upper() + "</div></div>"
else:
X += "<div id='quickframe-video-desc-div' style='display:inline-block;vertical-align:top;'><div style='font-size:15px;font-weight:300;color:white;background-color:#bcbcbc;text-align:center;'>WINNING VIDEO BY " + username.upper() + "</div></div>"
X += "</div>"
X += "</div>"
X += "<div id='quickframe-playlist'>"
if low_video_status == 'Ready':
X += "<div id='quickframe-thumbnail-wrapper-" + str(video_id) + "' class='quickframe-thumbnail-wrapper' style='cursor:pointer;' onclick='changeQuickframeVideo(" + str(video_id) + ",&quot;" + username.upper() + "&quot;," + str(rank) + ",&quot;" + ordinal(rank).upper() + "&quot;,&quot;" + str(thumbnail) + "&quot;)'><img id='current-quickframe-video-thumbnail' src='https:" + MEDIA_URL + low_thumbnail + "' style='width:calc(100% - 7px);margin:0 0 4px 0;'/></div>"
else:
X += "<div id='quickframe-thumbnail-wrapper-" + str(video_id) + "' class='quickframe-thumbnail-wrapper' style='cursor:pointer;' onclick='changeQuickframeVideo(" + str(video_id) + ",&quot;" + username.upper() + "&quot;," + str(rank) + ",&quot;" + ordinal(rank).upper() + "&quot;,&quot;" + str(thumbnail) + "&quot;)'><img id='current-quickframe-video-thumbnail' src='https:" + MEDIA_URL + thumbnail + "' style='width:calc(100% - 7px);margin:0 0 4px 0;'/></div>"
else:
if low_video_status == 'Ready':
X += "<div id='quickframe-thumbnail-wrapper-" + str(video_id) + "' class='quickframe-thumbnail-wrapper' style='cursor:pointer;' onclick='changeQuickframeVideo(" + str(video_id) + ",&quot;" + username.upper() + "&quot;," + str(rank) + ",&quot;" + ordinal(rank).upper() + "&quot;,&quot;" + str(thumbnail) + "&quot;)'><img src='https:" + MEDIA_URL + low_thumbnail + "' style='width:calc(100% - 7px);margin:0 0 4px 0;'/></div>"
else:
X += "<div id='quickframe-thumbnail-wrapper-" + str(video_id) + "' class='quickframe-thumbnail-wrapper' style='cursor:pointer;' onclick='changeQuickframeVideo(" + str(video_id) + ",&quot;" + username.upper() + "&quot;," + str(rank) + ",&quot;" + ordinal(rank).upper() + "&quot;,&quot;" + str(thumbnail) + "&quot;)'><img src='https:" + MEDIA_URL + thumbnail + "' style='width:calc(100% - 7px);margin:0 0 4px 0;'/></div>"
X += "<div class='quickframe-thumbnail-label' style='position:relative;height:25px;color:white;font-size:14px;font-weight:600;pointer-events:none;'>#" + str(rank) + "</div>"
if rank == 1 and competition.embed_playlist_ad_image and competition.embed_playlist_ad_link:
X += "<a id='quickframe-playlist-ad' href='" + competition.embed_playlist_ad_link + "' target='_blank' style='border:0;'><img src='" + MEDIA_URL + str(competition.embed_playlist_ad_image) + "' style='border:' /></a>"
rank = rank + 1
X += "</div>";
# Award Display
awardDisplay = ""
if competition.award_type == "Cash":
awardDisplay = "$" + str(int(competition.award_amount))
elif competition.award_type == "Prize":
awardDisplay = competition.award_description
else:
awardDisplay = "Just for fun"
#X += "<hr style='margin:15px 0;padding:0;height:0;border-style:solid none none none;border-top:1px solid #cecece;'>"
X += "<div id='quickframe-submit' style='margin-top:5px; cursor:pointer;text-align:center;'><div onclick='submitQuickframeVideo();' style='background-color:#" + competition.embed_primary_color + ";text-align:center;padding:0;line-height:40px;font-size:17px;border:0;color:" + competition.embed_primary_text_color + ";text-decoration:none;display:block;'>SUBMIT VIDEO</div></div>"
X += "<div id='quickframe-countdown-wrapper' style='margin-top:5px; vertical-align:top;text-align:center;color:white;font-size:14px;'><div style='text-align:center;padding:0;height:40px;line-height:40px;background-color:#bcbcbc;'><span>VOTING ENDS <span style='font-size:1.3em;line-height:40px;color:#" + competition.embed_primary_color + ";'>&raquo;</span> </span><span id='quickframe-countdown' data-date='" + competition.end_timestamp.strftime('%s') + "'>" + competition.end_timestamp.strftime('%x') + "</span></div></div>"
X += "<div style='color:#444444;display:inline-block;width:33.33%;text-align:center;line-height:34px;'><div onclick='window.location.href=&#39;http://www.facebook.com/sharer/sharer.php?u=&#39; + window.location.href;' style='color:#3b3b3b;cursor:pointer;'><img src='https://static.quickframe.com/img/facebook-100-gray.png' alt='facebook' style='vertical-align:middle;height:18px;width:18px;margin-right:2px;'><span class='quickframe-social-text'> facebook</span></div></div>"
X += "<div style='color:#444444;display:inline-block;width:33.33%;text-align:center;line-height:34px;'><div onclick='window.location.href=&#39;https://twitter.com/share?text=" + urllib.parse.quote_plus(competition.title) + ":%20&url=&#39; + window.location.href;' title='Tweet' style='color:#3b3b3b;cursor:pointer;'><img src='https://static.quickframe.com/img/twitter-100-gray.png' alt='twitter' style='vertical-align:middle;height:18px;width:18px;margin-right:2px;' target='_blank'><span class='quickframe-social-text'> twitter</span></div></div>"
X += "<div style='color:#444444;display:inline-block;width:33.33%;text-align:center;line-height:34px;'><div onclick='window.location.href=&#39;mailto:?subject=" + competition.title + "&body=Submit your video to " + competition.title + ": &#39; + window.location.href;' style='color:#3b3b3b;cursor:pointer;'><img src='https://static.quickframe.com/img/email-100-gray.png' alt='email' style='vertical-align:middle;height:18px;width:18px;margin-right:2px;'><span class='quickframe-social-text'> email</span></div></div>"
X += "</div>"
X += '";';
X += "var quickframeWidth = document.getElementById('quickframe-embed-wrapper-" + str(competitionID) + "').offsetWidth;"
X += "var quickframeS = '';"
X += "if (quickframeWidth >= 500) {"
X += "quickframeS += '<style>';"
X += "quickframeS += '#quickframe-video-section-wrapper{display:inline-block; width:80%;}';"
X += "quickframeS += '#quickframe-embed-wrapper-" + str(competitionID) + " #quickframe-title{font-size:18px;font-weight:600;}';"
X += "quickframeS += '#quickframe-embed-wrapper-" + str(competitionID) + " #quickframe-desc{font-size:15px;font-weight:300;padding-bottom:5px;}';"
X += "quickframeS += '#quickframe-embed-wrapper-" + str(competitionID) + " video{width:calc(100% - 7px);height:324px !important;max-height:324px !important;}';"
X += "quickframeS += '#quickframe-playlist{display:inline-block;width:20%;height:392px;overflow-y:scroll;}';"
X += "quickframeS += '.quickframe-thumbnail-wrapper{width:100%;height:83px;vertical-align:top;}';"
X += "quickframeS += '.quickframe-thumbnail-label{display:block !important;margin:-25px 5px 0;}';"
X += "quickframeS += '#quickframe-promo-label-wrapper>div {margin:0 7px 0 0;}';"
X += "quickframeS += '#quickframe-vote-div{width:25%;}';"
X += "quickframeS += '#quickframe-video-desc-div{width:75%;line-height:40px;white-space:nowrap;overflow:hidden;}';"
X += "quickframeS += '#quickframe-video-desc-div>div{margin:0 7px;padding:0 15px;display:block;}';"
X += "quickframeS += '#quickframe-submit{width:50%;display:inline-table;}';"
X += "quickframeS += '#quickframe-countdown-wrapper{width:50%;display:inline-table;}';"
X += "quickframeS += '#quickframe-countdown-wrapper>div{margin-left:8px;display:block;}';"
X += "quickframeS += '</style>';"
X += "}"
X += "else {"
X += "quickframeS += '<style>';"
X += "quickframeS += '#quickframe-embed-wrapper-" + str(competitionID) + " hr{display:none;}';"
X += "quickframeS += '#quickframe-video-section-wrapper{width:100%;margin-top:10px;}';"
X += "quickframeS += '#quickframe-embed-wrapper-" + str(competitionID) + " #quickframe-title{font-size:18px;font-weight:600;}';"
X += "quickframeS += '#quickframe-embed-wrapper-" + str(competitionID) + " #quickframe-desc{font-size:14px;font-weight:300;padding-bottom:5px;}';"
X += "quickframeS += '#quickframe-embed-wrapper-" + str(competitionID) + " video{width:100%;height:206px !important;max-height:206px !important;}';"
X += "quickframeS += '#quickframe-playlist{margin-top:5px;width:100%;height:95px;overflow-x:scroll;white-space:nowrap;}';"
X += "quickframeS += '.quickframe-thumbnail-wrapper{width:130px;display:inline-table !important;vertical-align:top;}';"
X += "quickframeS += '.quickframe-thumbnail-label{display:block !important;margin:54px 0 0 -125px; width:125px;display:inline-table !important;vertical-align:top;}';"
X += "quickframeS += '#quickframe-playlist-ad > img { height:80px; }';"
X += "quickframeS += '#quickframe-promo-label-wrapper>div {margin:0;}';"
X += "quickframeS += '#quickframe-vote-div{width:100%;}';"
X += "quickframeS += '#quickframe-video-desc-div{width:100%;margin-top:5px;}';"
X += "quickframeS += '#quickframe-video-desc-div>div{padding:7px 15px;display:block;}';"
X += "quickframeS += '#quickframe-submit{width:100%;}';"
X += "quickframeS += '#quickframe-countdown-wrapper{width:100%;margin:5px 0 0;}';"
#X += "quickframeS += '.quickframe-social-text{display:none;}';"
X += "quickframeS += '</style>';"
X += "}"
if competition.embed_video_autoplay:
X += "var promoVid = document.getElementById('quickframe-promo-video');"
X += "promoVid.volume = 0.2;"
X += "var quickframeC = document.createElement('div');"
X += "quickframeC.innerHTML = quickframeS;"
X += "quickframeC = quickframeC.firstChild;"
X += "document.getElementById('quickframe-embed-wrapper-" + str(competition.id) + "').appendChild(quickframeC);"
X += "Number.prototype.pad = function(size) {"
X += "var s = String(this);"
X += "while (s.length < (size || 2)) {s = '0' + s;}"
X += "return s;"
X += "}; "
X += "var countdown = document.getElementById('quickframe-countdown');"
X += "var target_date = countdown.getAttribute('data-date');"
X += "var days, hours, minutes, seconds;"
X += "setInterval(function () {"
X += "var current_date = new Date().getTime();"
X += "var seconds_left = (target_date - current_date / 1000);"
X += "if (seconds_left < 1) {"
X += " countdown.innerHTML = 'ENDED';"
X += "}"
X += "else {"
X += " days = parseInt(seconds_left / 86400);"
X += " seconds_left = seconds_left % 86400;"
X += " hours = parseInt(seconds_left / 3600);"
X += " seconds_left = seconds_left % 3600;"
X += " minutes = parseInt(seconds_left / 60);"
X += " seconds = parseInt(seconds_left % 60);"
X += " countdown.innerHTML = \"<span class='countdown-number'>\" + days.pad(2) + \"</span>D <span class='countdown-number'>\" + hours.pad(2) + \"</span>H <span class='countdown-number'>\" + minutes.pad(2) + \"</span>M <span class='countdown-number'>\" + seconds.pad(2) + \"</span>S\";"
X += "}"
X += "}, 1000);"
X += "function submitQuickframeVideo() {"
X += " var updateCurrentURL = quickframeAddParam(window.location.href,'quickframe_action','upload');"
X += " updateCurrentURL = quickframeRemoveParam(updateCurrentURL, 'quickframe_vote');"
X += " updateCurrentURL = quickframeRemoveParam(updateCurrentURL, 'quickframe_video');"
X += " updateCurrentURL = updateCurrentURL.replace(/&/g, '%26');"
#X += " var next = '/embed/redirect/' + encodeURI(updateCurrentURL).replace('?', '%3F');"
X += " var next = 'embed/redirect/' + encodeURIComponent(updateCurrentURL);"
#X += " var next = '/embed/redirect/' + updateCurrentURL;"
X += " showOverlayWithURL('" + site + "/embed/competition/submit/?competition=" + str(competitionID) + "&primary_color=" + competition.embed_primary_color + "&next=' + next);"
X += "}"
X += "function quickframeVideoVote(video_id) {"
X += " var updateCurrentURL = quickframeAddParam(window.location.href,'quickframe_vote',video_id);"
X += " updateCurrentURL = quickframeRemoveParam(updateCurrentURL, 'quickframe_action');"
X += " updateCurrentURL = quickframeRemoveParam(updateCurrentURL, 'quickframe_video');"
X += " updateCurrentURL = updateCurrentURL.replace(/&/g, '%26');"
#X += " var next = '/embed/redirect/' + updateCurrentURL;"
X += " var next = 'embed/redirect/' + encodeURIComponent(updateCurrentURL);"
X += " showOverlayWithURL('" + site + "/embed/competition/vote/?object_type=Video&object_id=' + video_id + '&primary_color=" + competition.embed_primary_color + "&next=' + next);"
X += "}"
X += "function showOverlayWithURL(url) {"
X += " var overlayDiv = document.createElement('div');"
X += " overlayDiv.id = 'quickframe-overlay-div';"
X += " overlayDiv.innerHTML = \"<iframe id='quickframe-overlay' allowtransparency='true' frameborder='0' scrolling='no' tabindex='0' title='Quickframe' width='100%' src='\" + url + \"' style='width: 100% !important; border: none !important; overflow: hidden !important; height: 100% !important; position: fixed !important; top: 0px !important; right: 0px !important; left: auto !important; bottom: auto !important; z-index: 2147483647 !important;'></iframe>\";"
X += " document.body.appendChild(overlayDiv);"
X += "}"
X += "function quickframeAddParam(url, param, value) {"
X += " var a = document.createElement('a'), regex = /(?:\?|&amp;|&)+([^=]+)(?:=([^&]*))*/g;"
X += " var match, str = []; a.href = url; param = encodeURIComponent(param);"
X += " while (match = regex.exec(a.search))"
X += " if (param != match[1]) str.push(match[1]+(match[2]?'='+match[2]:''));"
X += " str.push(param+(value?'='+ encodeURIComponent(value):''));"
X += " a.search = str.join('&');"
X += " return a.href;"
X += "}"
X += "function quickframeRemoveParam(url, parameter) {"
X += " var urlparts= url.split('?');"
X += " if (urlparts.length>=2) {"
X += " var prefix= encodeURIComponent(parameter)+'=';"
X += " var pars= urlparts[1].split(/[&;]/g);"
X += " for (var i= pars.length; i-- > 0;) {"
X += " if (pars[i].lastIndexOf(prefix, 0) !== -1) {"
X += " pars.splice(i, 1);"
X += " }"
X += " }"
X += " url = urlparts[0]+'?'+pars.join('&');"
X += " return url;"
X += " } else {"
X += " return url;"
X += " }"
X += "}"
X += "function getParameterByName(name) {"
X += "name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');"
X += "var regex = new RegExp('[\\?&]' + name + '=([^&#]*)'),"
X += " results = regex.exec(location.search);"
X += "return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '));"
X += "}"
X += "function receiveMessage(event) {"
#X += " if (event.origin == 'https://www.quickframe.com' && event.data == 'close quickframe overlay') {"
#X += " console.log(event.data.substring(0,21));"
#X += " console.log(event.data.substring(21));"
X += " if (event.data == 'close quickframe overlay') {"
X += " var overlayDiv = document.getElementById('quickframe-overlay-div');"
X += " document.body.removeChild(overlayDiv);"
X += " }"
X += " else if (event.data.substring(0,21) == 'quickframe new video=') {"
X += " var video_id = event.data.substring(21);"
X += " var newURL = quickframeAddParam(window.location.href, 'quickframe_video', video_id);"
X += " newURL = quickframeRemoveParam(newURL, 'quickframe_action');"
X += " newURL = quickframeRemoveParam(newURL, 'quickframe_vote');"
X += " window.location.href = newURL;"
X += " }"
X += "}"
X += "addEventListener('message', receiveMessage, false);"
#X += "var quickframeVideoClicks = 0;"
X += "function changeQuickframeVideo(video_id, username, rank, rankDisplay, thumbnail) {"
X += "if (video_id < 1) { video_id = 'promo'; }";
X += "var newURL = quickframeAddParam(window.location.href, 'quickframe_video', video_id);"
X += "history.pushState('', '', newURL);"
#X += "if (quickframeVideoClicks>=3) {"
#X += " location.reload();"
#X += " return;"
#X += "}"
#X += "else {"
#X += " quickframeVideoClicks++;"
#X += "}"
if competition.promotional_video:
X += " if (rank == 'promo') {"
X += " var H = \"<video style='margin:0;background-color:black;' controls autoplay poster='https:" + MEDIA_URL + str(competition.promotional_video.thumbnail) + "'>\";"
if competition.promotional_video.low_video_status == 'Ready':
X += " H += \"<source src='https:" + MEDIA_URL + str(competition.promotional_video.low_video) + "' type='video/mp4'>\";"
else:
X += " H += \"<source src='https:" + MEDIA_URL + str(competition.promotional_video.video) + "' type='video/mp4'>\";"
X += " H += \"</video>\";"
X += " H += \"<div id='quickframe-promo-label-wrapper' style='width:100%;display:inline-block;vertical-align:top;'><div style='font-size:17px;padding:0 15px;line-height:40px;font-weight:300;color:white;background-color:#bcbcbc;white-space:nowrap;overflow:hidden;text-align:center;display:block;'>PROMOTIONAL VIDEO</div></div>\";"
X += " }"
else:
X += " if (0) {}"
X += " else {"
X += " var H = \"<video style='margin:0;background-color:black;' controls autoplay poster='https:" + MEDIA_URL + "\" + thumbnail + \"'><source src='https:" + MEDIA_URL + "low_video/video/\" + video_id + \".mp4' type='video/mp4'></video>\";"
X += " H += \"<div id='quickframe-vote-div' onclick='quickframeVideoVote(\" + video_id + \")' style='display:inline-block;cursor:pointer;vertical-align:top;color:white;text-align:center;font-size:20px;background-color:#" + competition.embed_primary_color + ";'><div style='padding:0 8px;line-height:40px;'>VOTE</div></div>\";"
X += " H += \"<div id='quickframe-video-desc-div' style='display:inline-block;vertical-align:top;'><div style='font-size:15px;font-weight:300;color:white;background-color:#bcbcbc;text-align:center;'>\" + rankDisplay + \" PLACE VIDEO BY \" + username + \"</div></div>\";"
X += " }"
X += " document.getElementById('quickframe-video-wrapper').innerHTML = H;"
X += " document.getElementById('current-quickframe-video-thumbnail').removeAttribute('id');"
X += " if (video_id > 0) {"
X += " document.getElementById('quickframe-thumbnail-wrapper-' + video_id).firstChild.setAttribute('id','current-quickframe-video-thumbnail');"
X += " var newURL = quickframeAddParam(window.location.href, 'quickframe_video', video_id);"
X += " }"
X += " else {"
X += " document.getElementById('quickframe-thumbnail-wrapper-promo').firstChild.setAttribute('id','current-quickframe-video-thumbnail');"
X += " var newURL = quickframeRemoveParam(window.location.href, 'quickframe_video');"
X += " }"
X += " history.pushState('', '', newURL);"
X += "}"
X += "var quickframeVideoID = getParameterByName('quickframe_video');"
X += "if (quickframeVideoID) {"
X += " var thumbnail = document.getElementById('quickframe-thumbnail-wrapper-' + quickframeVideoID);"
X += " if (thumbnail) {"
X += " thumbnail.click();"
X += " }"
X += " else {"
X += " var H = \"<video style='margin:0;background-color:black;' controls autoplay poster='https:" + MEDIA_URL + "quickframe-thumbnail.png'><source src='https:" + MEDIA_URL + "video/temp/\" + quickframeVideoID + \"' type='video/mp4'></video>\";"
X += " H += \"<div id='quickframe-vote-div' onclick='quickframeVideoVote(\" + quickframeVideoID + \")' style='display:inline-block;cursor:pointer;vertical-align:top;color:white;text-align:center;font-size:20px;background-color:#" + competition.embed_primary_color + ";'><div style='padding:0 8px;line-height:40px;'>VOTE</div></div>\";"
X += " H += \"<div id='quickframe-video-desc-div' style='display:inline-block;vertical-align:top;'><div style='font-size:15px;font-weight:300;color:white;background-color:#bcbcbc;text-align:center;'>YOUR " + ordinal(videoCount+1).upper() + " PLACE VIDEO</div></div>\";"
X += " document.getElementById('quickframe-video-wrapper').innerHTML = H;"
X += " document.getElementById('current-quickframe-video-thumbnail').removeAttribute('id');"
X += " }"
#X += " var topPos = thumbnail.offsetTop;"
#X += " console.log('topPos: ' + topPos);"
#X += " document.getElementById('quickframe-playlist').scrollTop = topPos;"
X += "}"
X += "var quickframeAction = getParameterByName('quickframe_action');"
X += "if (quickframeAction == 'upload') {"
X += " submitQuickframeVideo();"
X += "}"
X += "var quickframeVoteID = getParameterByName('quickframe_vote');"
X += "if (quickframeVoteID) {"
X += " quickframeVideoVote(quickframeVoteID)"
X += "}"
s3_conn = boto.connect_s3()
s3_bucket = s3_conn.get_bucket(s3_media_bucket_name)
from boto.s3.key import Key
s3_key = Key(s3_bucket)
s3_key.key = "quickframe/embed/" + str(competition.id) + ".js"
s3_key.set_contents_from_string(X)
# Vagrant configuration file for local development environment
"""
VAGRANT FILE WITH CUSTOM PROVISIONING SCRIPT
Note: In order to work properly, two seperate snippets are required:
1) Vagrantfile
2) provision.sh
The provision.sh will be included in a seperate snippet. I did not personally write this Vagrantfile alone. However,
the provision.sh file is where I took up most of the work.
IMPORTANT: In order to adhere to NDA agreements, sensative information has been redacted.
"""
Vagrant.configure("2") do |config|
config.vm.box = "REDACTED"
config.vm.hostname = "REDACTED"
config.vm.network "private_network", ip: "REDACTED"
config.vm.network "private_network", ip: "REDACTED"
config.vm.provision "shell", path: "vagrant/provision.sh"
config.vm.synced_folder "sites", "/www/sites", nfs: true
config.vm.synced_folder "services", "/www/services/"
config.vm.synced_folder "configs", "/www/configs/"
config.vm.synced_folder "vagrant", "/www/vagrant/"
# VirtualBox
config.vm.provider :virtualbox do |vb|
vb.customize ["modifyvm", :id, "--memory", 4096, "--cpus", 4]
vb.customize ["setextradata", :id, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/v-services", "1"]
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment