<commit_before>from django.conf import settings
from django.shortcuts import get_object_or_404, render_to_response
from django.template import RequestContext
from django.views.generic import date_based, list_detail
from tagging.models import Tag
from coltrane.models import Category, Entry, Link

paginate_by = (hasattr(settings, 'PAGINATE_BY') and settings.PAGINATE_BY) or 20

def category_detail(request, slug):
    """
    Detail view of a Category, listing Entries posted in it.

    This is a short wrapper around the generic
    ``list_detail.object_list`` view, so all context variables
    populated by that view will be available here. One extra variable
    is added::

        object
            The Category.

    Template::
        coltrane/category_detail.html

    """
    category = get_object_or_404(Category, slug__exact=slug)
    return list_detail.object_list(request,
                                   queryset=category.live_entry_set,
                                   extra_context={ 'object': category },
                                   template_name='coltrane/category_detail.html',
                                   paginate_by=paginate_by,
                                   allow_empty=True)

def entry_detail(request, year, month, day, slug):
    """
    Detail view of an Entry.

    Context::

        object
            The Entry.

        next_entry
            The next live Entry by ``pub_date``, if there is one.

        previous_entry
            The previous live Entry by ``pub_date``, if there is one.

    Template::
        coltrane/entry_detail.html

    """
    entry = get_object_or_404(Entry,
                              pub_date__year=year,
                              pub_date__month=month,
                              pub_date__day=day,
                              slug__exact=slug)
    try:
        next_entry = entry.get_next()
    except Entry.DoesNotExist:
        next_entry = None
    try:
        previous_entry = entry.get_previous()
    except:
        previous_entry = None
    return render_to_response('coltrane/entry_detail.html',
                              { 'object': entry,
                                'next_entry': entry.get_next(),
                                'previous_entry': entry.get_previous() },
                              context_instance=RequestContext(request))

<commit_msg>Add a bunch of generic-view wrappers for categories<commit_after>from django.conf import settings
from django.shortcuts import get_object_or_404, render_to_response
from django.views.generic import date_based, list_detail
from coltrane.models import Category

def _category_kwarg_helper(category, kwarg_dict):
    if 'extra_context' in kwarg_dict:
        kwarg_dict.update(object=category)
    else:
        kwarg_dict['extra_context'] = category
    for key in ('queryset', 'date_field', 'template_name'):
        if key in kwarg_dict:
            del kwarg_dict[key]
    return kwarg_dict

def category_detail(request, slug, **kwargs):
    """
    Detail view of a ``Category``, listing entries published in it.

    This is a short wrapper around the generic
    ``list_detail.object_list`` view, so all context variables
    populated by that view will be available here. One extra variable
    is added::

        object
            The ``Category``.

    Additionally, any keyword arguments which are valid for
    ``list_detail.object_list`` will be accepted and passed to it,
    with these exceptions:

    * ``queryset`` will always be the ``QuerySet`` of live entries in
      the ``Category``.
    * ``template_name`` will always be 'coltrane/category_detail.html'.

    Template::
        coltrane/category_detail.html

    """
    category = get_object_or_404(Category, slug__exact=slug)
    kwarg_dict = _category_kwarg_helper(category, kwargs)
    return list_detail.object_list(request,
                                   queryset=category.live_entry_set,
                                   template_name='coltrane/category_detail.html',
                                   **kwarg_dict)

def category_archive_index(request, slug, **kwargs):
    """
    View of the latest entries published in a ``Category``.

    This is a short wrapper around the generic
    ``date_based.archive_index`` view, so all context variables
    populated by that view will be available here. One extra variable
    is added::

        object
            The ``Category``.

    Additionally, any keyword arguments which are valid for
    ``date_based.archive_year`` will be accepted and passed to it,
    with these exceptions:

    * ``queryset`` will always be the ``QuerySet`` of live entries in
      the ``Category``.
    * ``date_field`` will always be 'pub_date'.
    * ``template_name`` will always be 'coltrane/category_archive.html'.

    Template::
        coltrane/category_archive.html

    """
    category = get_object_or_404(Category, slug__exact=slug)
    kwarg_dict = _category_kwarg_helper(category, kwargs)
    return date_based.archive_index(request,
                                    queryset=category.live_entry_set,
                                    template_name='coltrane/category_archive.html',
                                    **kwarg_dict)

def category_archive_year(request, slug, year, **kwargs):
    """
    View of entries published in a ``Category`` in a given year.

    This is a short wrapper around the generic
    ``date_based.archive_year`` view, so all context variables
    populated by that view will be available here. One extra variable
    is added::

        object
            The ``Category``.

    Additionally, any keyword arguments which are valid for
    ``date_based.archive_year`` will be accepted and passed to it,
    with these exceptions:

    * ``queryset`` will always be the ``QuerySet`` of live entries in
      the ``Category``.
    * ``date_field`` will always be 'pub_date'.
    * ``template_name`` will always be 'coltrane/category_archive_year.html'.

    Template::
        coltrane/category_archive_year.html

    """
    category = get_object_or_404(Category, slug__exact=slug)
    kwarg_dict = _category_kwarg_helper(category, kwargs)
    return date_based.archive_year(request,
                                   queryset=category.live_entry_set,
                                   date_field='pub_date',
                                   template_name='coltrane/category_archive_year.html',
                                   **kwarg_dict)

def category_archive_month(request, slug, year, month, **kwargs):
    """
    View of entries published in a ``Category`` in a given month.

    This is a short wrapper around the generic
    ``date_baed.archive_month`` view, so all context variables
    populated by that view will be available here. One extra variable
    is added::

        object
            The ``Category``.

    Additionally, any keyword arguments which are valid for
    ``date_based.archive_month`` will be accepted and passed to it,
    with these exceptions:

    * ``queryset`` will always be the ``QuerySet`` of live entries in
      the ``Category``.
    * ``date_field`` will always be 'pub_date'.
    * ``template_name`` will always be 'coltrane/category_archive_month.html'.

    Template::
        coltrane/category_archive_month.html

    """
    category = get_object_or_404(Category, slug__exact=slug)
    kwarg_dict = _category_kwarg_helper(category, kwargs)
    return date_based.archive_month(request,
                                    year=year,
                                    month=month
                                    queryset=category.live_entry_set,
                                    date_field='pub_date',
                                    template_name='coltrane/category_archive_month.html',
                                    **kwarg_dict)

def category_archive_day(request, slug, year, month, **kwargs):
    """
    View of entries published in a ``Category`` on a given day.

    This is a short wrapper around the generic
    ``date_based.archive_day`` view, so all context variables
    populated by that view will be available here. One extra variable
    is added::

        object
            The ``Category``.

    Additionally, any keyword arguments which are valid for
    ``date_based.archive_day`` will be accepted and passed to it, with
    these exceptions:

    * ``queryset`` will always be the ``QuerySet`` of live entries in
      the ``Category``.
    * ``date_field`` will always be 'pub_date'.
    * ``template_name`` will always be 'coltrane/category_archive_day.html'.

    Template::
        coltrane/entry_archive_day.html

    """
    category = get_object_or_404(Category, slug__exact=slug)
    kwarg_dict = _category_kwarg_helper(category, kwargs)
    return date_base.archive_day(request,
                                 year=year,
                                 month=month,
                                 day=day,
                                 queryset=category.live_entry_set,
                                 extra_context=extra_context,
                                 template_name='coltrane/category_archive_day.html',
                                 **kwarg_dict)
<|endoftext|>


<commit_before>import matplotlib.pyplot as plt
import csv
import sys

min_thresh = 250
label_length = 35

def read_pheno(filename):
    results = {}
    with open(filename) as f:
        r = csv.reader(f, delimiter=';')
        # header line holds the phenotype names
        names = next(r)
        for name in names:
            results[name] = []
        # now for the data
        for row in r:
            for (phenonum,name) in enumerate(names[1:],start=1):
                if row[phenonum] != "-":
                    results[name].append(row[phenonum].lower())
    # remove any that are too few
    to_remove = [k for k, v in results.items() if len(v) < min_thresh]
    for name in to_remove:
        del results[name]
    return results

def plot_bar(name, vals, outdir):
    d = {}
    # count how many of each value
    for p in vals:
        d[p] = d.get(p,0) + 1
    items = sorted(d.items(), reverse=True) # alphabetic by phenotype name
    num_items = len(items)
    yvals = [i[1] for i in items]
    labels = [i[0][:label_length] for i in items]
    nums = range(num_items)

    plt.barh(nums, yvals, align='center')
    plt.yticks(nums, labels)
    plt.ylim(-1, num_items)
    plt.tight_layout()
    plt.title(name)
    #plt.show()
    plt.savefig(outdir + name.replace(" ","_") + ".png", bbox_inches='tight')
    plt.close()

if __name__ == "__main__":
    data = read_pheno("../data/phenotypes/phenotypes_201604281702.csv.clean.csv")
    outdir = "../results/"
    for name, vals in data.items():
        plot_bar(name, vals, outdir)

<commit_msg>added UTF-8, added dir_* as in other scripts<commit_after>import matplotlib.pyplot as plt
import csv
import sys
import os.path

debug = True

min_thresh = 250
label_length = 35

def read_pheno(filename):
    results = {}
    with open(filename, encoding="utf-8") as f:
        r = csv.reader(f, delimiter=';')
        # header line holds the phenotype names
        names = next(r)
        for name in names:
            results[name] = []
        # now for the data
        for row in r:
            for (phenonum,name) in enumerate(names[1:],start=1):
                if row[phenonum] != "-":
                    results[name].append(row[phenonum].lower())
    # remove any that are too few
    to_remove = [k for k, v in results.items() if len(v) < min_thresh]
    for name in to_remove:
        del results[name]
    return results

def plot_bar(name, vals, outdir):
    d = {}
    # count how many of each value
    for p in vals:
        d[p] = d.get(p,0) + 1
    items = sorted(d.items(), reverse=True) # alphabetic by phenotype name
    num_items = len(items)
    yvals = [i[1] for i in items]
    labels = [i[0][:label_length] for i in items]
    nums = range(num_items)

    plt.barh(nums, yvals, align='center')
    plt.yticks(nums, labels)
    plt.ylim(-1, num_items)
    plt.tight_layout()
    plt.title(name)
    #plt.show()
    plt.savefig(outdir + name.replace(" ","_") + ".png", bbox_inches='tight')
    plt.close()

if __name__ == "__main__":
    data_dir            = '..'+os.path.sep+'..'+os.path.sep+'data'
    data_dir_genotype   = '%s%sgenotypes' % (data_dir,os.path.sep)
    data_dir_phenotype  = '%s%sphenotypes' % (data_dir,os.path.sep)
    data_dir_annotation = '%s%sannotation' % (data_dir,os.path.sep)
    data_file           = 'phenotypes_201604281702.csv.clean.csv'

    outdir = '..'+os.path.sep+'..'+os.path.sep+'results'+os.path.sep
    print ("%s%s%s" % (data_dir_phenotype,os.path.sep,data_file))
    data = read_pheno("%s%s%s" % (data_dir_phenotype,os.path.sep,data_file))
    for name, vals in data.items():
        if debug:
            print('Processing <<%s>>' % (name))
        plot_bar(name, vals, outdir)

<|endoftext|>


<commit_before><commit_msg>: python unit : update format.<commit_after><|endoftext|>


<commit_before>"""
Python EDA Package
"""

__version__ = "0.14.1"
<commit_msg>Release 0.14.2<commit_after>"""
Python EDA Package
"""

__version__ = "0.14.2"
<|endoftext|>


<commit_before>from django.template import loader
from django.http import HttpResponse
from django.core.mail import send_mail
from django.db import transaction
from django.db import IntegrityError
from django.core.exceptions import ObjectDoesNotExist
from WebStoreObjects import GameWithKeys
from models import Game
from models import Key
from models import Faq
from models import Email
from models import PushSubscriber
import stripe
# Below secret_data.py file is not provided, you must make this yourself.
# Put your secret and publishable Stripe keys in that file.
# secret_data.py is in the .gitignore file so you won't accidentally commit it.
import secret_data

# APACHE 2.0 LICENSE
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

# Create your views here.

# Front page, which displays a list of games.
# First page a user will see.
def index(request):
    email = request.GET.get('email', False)
    operation = request.GET.get('op', 'add')
    order = request.GET.get('order', False)

    if email:
        if operation == 'add':
            try:
                email_model = Email(email=email)
                email_model.save()
                email = True
            except IntegrityError:
                pass
        elif operation == 'remove':
            try:
                email_model = Email.objects.get(email=email)
                email_model.delete()
                email = True
            except ObjectDoesNotExist:
                pass

    template = loader.get_template('store/game_list.html')
    drm = request.GET.get('drm', None)
    query = request.GET.get('query', None)

    if order == 'new':
        games = sorted(get_games_with_keys(drm=drm, query=query, new=True))
    else:
        games = sorted(get_games_with_keys(drm=drm, query=query))

    context = {
        'game_list': games,
        'drm': drm,
        'query': query,
        'email_added': email,
        'email_op': operation
    }
    return HttpResponse(template.render(context, request))

# Page that shows details about the game and allows user to purchase the game.
# The second page in the key purchasing process.
def game_detail(request, game_id):
    template = loader.get_template('store/game_details.html')
    game = Game.objects.get(pk=game_id)
    context = {
        'game_title': game.name,
        'game_description': game.description,
        'game_image': game.img_name,
        'game_price': '${:.2f} USD'.format(get_adjusted_price(game.price)),
        'game_price_num': get_adjusted_price(game.price),
        'game_price_num_int': int(round(get_adjusted_price(game.price)*100)),
        'game_with_keys': get_game_with_keys_for_game(game),
        # Set this in a file called secret_data.py. secret_data.py is in the .gitignore so you won't accidentally commit it to a db.
        # STRIPE_KEY_PUBLISHABLE should be the test key on your machine, and the production key on your server
        'stripe_key': secret_data.STRIPE_KEY_PUBLISHABLE,
    }
    return HttpResponse(template.render(context, request))

# Page that displays after purchase and shows error or success.
# Last page the user will see before being prompted to go back home.
# game_id is the primary key of a Game object.
def checkout_page(request, game_id):
    template = loader.get_template('store/post_purchase.html')
    drm = request.POST["drm"]
    add_to_list = request.POST.get('email-list', False)
    email = 'no email'
    game = get_game_with_keys_for_game(Game.objects.get(pk=game_id))

    # Make sure nobody has taken the key while the user was looking at the
    # game detail page.
    key = get_first_unclaimed_key(game, drm)
    has_key = True
    if key == -1:
        has_key = False
    code = None

    if has_key:
        # Set your secret key: remember to change this to your live secret key in production
        # See your keys here https://dashboard.stripe.com/account/apikeys
        # Set this in a file called secret_data.py. secret_data.py is in the .gitignore so you won't accidentally commit it to a db.
        # STRIPE_KEY_SECRET should be the test key on your machine, and the production key on your server
        stripe.api_key = secret_data.STRIPE_KEY_SECRET
        # Get the token generated by stripe.js
        token = request.POST['stripeToken']

        # Try to create the charge on Stripe's servers - this will charge the user's card
        try:
            charge = stripe.Charge.create(
                amount=int(round(get_adjusted_price(game.price)*100)),  # amount in cents, again
                currency="usd",
                source=token,
                description=game.name
            )
            # User email is retrieved from Stripe.
            email = get_email_from_transaction(token)

            # Follow the instructions at:
            #
            # https://docs.djangoproject.com/en/1.9/topics/email/
            #
            # to properly set up Django's email capabilities.
            #
            # Email is required for users to get their keys, although it will display
            # in plain text if email fails for some reason.
            #
            # Replace email@example.com with your email after you've properly
            # gotten Django's email service set up. You might consider putting
            # this email in your secret_data.py file as well.
            #
            # Change fail_silently to False for debugging.
            email_succeeded = send_mail('Your game key', 'You ordered ' + game.name + ' for ' + drm + '. Your key is: ' + key.key_text,
                                        secret_data.EMAIL_ADDRESS, [email], fail_silently=True)

            # Remember who claimed a key. Useful if a user needs you to re-send keys.
            key.claimed_by = email
            key.save()

            # Fallback if email fails.
            if email_succeeded < 1:
                code = key.key_text
            status = True
            message = None
        except stripe.error.CardError, e:
            # The card has been declined
            status = False
            message = e.args
            email_succeeded = -1
            # IMPORTANT: This marks the key as available again.
            key.claimed = False
            key.save()
            pass
        except stripe.error.StripeError, e:
            # Some other Stripe error.
            status = False
            message = e.args
            email_succeeded = -1
            # IMPORTANT: This marks the key as available again.
            key.claimed = False
            key.save()
            pass
    else:
        # Somebody else got the key first, or something else unexpected happened.
        status = False
        email_succeeded = -1
        message = 'Sorry but the key seems to have been taken. You have not been charged.'

    # If user indicated that they'd like to be added to the emailing list, add them.
    if add_to_list and status and email_succeeded > -1:
        try:
            model_email = Email(email=email)
            model_email.save()
        except IntegrityError:
            pass

    context = {
        'errors': message,
        'transaction_status': status,
        'game_price_num': '{:.2f}'.format(get_adjusted_price(game.price)),
        'game_title': game.name,
        'game_description': game.description,
        'game_price': '${:.2f} USD'.format(get_adjusted_price(game.price)),
        'drm': drm,
        'email': email_succeeded,
        'attempted_email': email,
        'code': code,
        'list': add_to_list,
        # Below key should be "pk_test_xxxxxxxxxx" for test,
        # or "pk_live_xxxxxxxxx" for production. Save it in a
        # secret_data file to prevent accidental committing to
        # a repo.
        'stripe_key': secret_data.STRIPE_KEY_PUBLISHABLE,
    }
    return HttpResponse(template.render(context, request))

# Page that displays FAQs for the web store.
def faq(request):
    template = loader.get_template('store/faq.html')
    faqs = Faq.objects.all()
    context = {'faq_list': faqs}
    return HttpResponse(template.render(context, request))

def push_notifications(request, js):
    template = loader.get_template('store/push_notifications.js')
    html = template.render()
    return HttpResponse(html, content_type="application/x-javascript")

def add_subscriber(request):
    subscriberId = request.GET['subscriberId[]']
    newSubscriber = PushSubscriber(sub_id=subscriberId)
    newSubscriber.save()
    return HttpResponse('{"status": "success"}')

def remove_subscriber(request):
    subscriberId = request.GET['subscriberId[]']
    currentSubscriber = PushSubscriber.objects.get(sub_id=subscriberId)
    currentSubscriber.delete()
    return HttpResponse('{"status": "success"}')

# Gets keys from DB.
# drm filters by service (ex. "steam", "origin", "uplay")
# query filters by name (ex. query="co" could return "Counter-Strike: Global Offensive" but not "Far Cry 3")
def get_games_with_keys(drm=None, query=None, new=False):
    games_with_keys = list()

    if new:
        games = get_new_games_from_db()
    else:
        games = get_games_from_db()

    #TODO replace giant conditional tree with clever ORM line instead
    for game in games:
        game_with_key = get_game_with_keys_for_game(game)
        if game_with_key.has_steam or game_with_key.has_origin or game_with_key.has_uplay:
            if drm is None or drm == 'all':
                if query is None or query == '':
                    games_with_keys.append(game_with_key)
                elif query.lower() in game_with_key.name.lower():
                    games_with_keys.append(game_with_key)
            elif drm == 'steam' and game_with_key.has_steam:
                if query is None or query == '':
                    games_with_keys.append(game_with_key)
                elif query.lower() in game_with_key.name.lower():
                    games_with_keys.append(game_with_key)
            elif drm == 'origin' and game_with_key.has_origin:
                if query is None or query == '':
                    games_with_keys.append(game_with_key)
                elif query.lower() in game_with_key.name.lower():
                    games_with_keys.append(game_with_key)
            elif drm == 'uplay' and game_with_key.has_uplay:
                if query is None:
                    games_with_keys.append(game_with_key)
                elif query.lower() in game_with_key.name.lower():
                    games_with_keys.append(game_with_key)
    return games_with_keys

# Returns an object that tells you for what services you have unclaimed keys.
def get_game_with_keys_for_game(game):
    is_steam = False
    is_uplay = False
    is_origin = False
    keys = Key.objects.filter(game_id=game.pk, claimed=False, hidden=False)
    for key in keys:
        if key.service == 'steam':
            is_steam = True
        elif key.service == 'uplay':
            is_uplay = True
        elif key.service == 'origin':
            is_origin = True
    return GameWithKeys(game, is_steam, is_uplay, is_origin)

# Gets the customer email from the Stripe transaction.
# token is the transaction token from Stripe
def get_email_from_transaction(token):
    try:
        return stripe.Token.retrieve(token)['email']
    except stripe.error.InvalidRequestError, e:
        return stripe.BitcoinReceiver.retrieve(token)['email']

# Returns the first key unclaimed for the given service.
# game_with_keys is the game object that we want a key for.
# drm is the service we want the key for. (ex. "steam", "origin", "uplay")
def get_first_unclaimed_key(game_with_keys, drm):
    with transaction.atomic():
        keys = Key.objects.select_for_update().filter(game_id=game_with_keys.id, service=drm)
        for key in keys:
            if key.claimed is False:
                if key.service == drm:
                    key.claimed = True
                    key.save()
                    return key
        keys.update()
    return -1

# Quick convienience method that retuns list of all games from db.
def get_games_from_db():
    games = Game.objects.filter()
    return games

def get_new_games_from_db():
    game = Key.objects.latest('date_added')
    games = Key.objects.filter(date_added=game.date_added)
    return games

# Method to DRY out price conversions.
def get_adjusted_price(price):
    return price * 1.029 + .3
<commit_msg>made an oopsie<commit_after>from django.template import loader
from django.http import HttpResponse
from django.core.mail import send_mail
from django.db import transaction
from django.db import IntegrityError
from django.core.exceptions import ObjectDoesNotExist
from WebStoreObjects import GameWithKeys
from models import Game
from models import Key
from models import Faq
from models import Email
from models import PushSubscriber
import stripe
# Below secret_data.py file is not provided, you must make this yourself.
# Put your secret and publishable Stripe keys in that file.
# secret_data.py is in the .gitignore file so you won't accidentally commit it.
import secret_data

# APACHE 2.0 LICENSE
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

# Create your views here.

# Front page, which displays a list of games.
# First page a user will see.
def index(request):
    email = request.GET.get('email', False)
    operation = request.GET.get('op', 'add')
    order = request.GET.get('order', False)

    if email:
        if operation == 'add':
            try:
                email_model = Email(email=email)
                email_model.save()
                email = True
            except IntegrityError:
                pass
        elif operation == 'remove':
            try:
                email_model = Email.objects.get(email=email)
                email_model.delete()
                email = True
            except ObjectDoesNotExist:
                pass

    template = loader.get_template('store/game_list.html')
    drm = request.GET.get('drm', None)
    query = request.GET.get('query', None)

    if order == 'new':
        games = sorted(get_games_with_keys(drm=drm, query=query, new=True))
    else:
        games = sorted(get_games_with_keys(drm=drm, query=query))

    context = {
        'game_list': games,
        'drm': drm,
        'query': query,
        'email_added': email,
        'email_op': operation
    }
    return HttpResponse(template.render(context, request))

# Page that shows details about the game and allows user to purchase the game.
# The second page in the key purchasing process.
def game_detail(request, game_id):
    template = loader.get_template('store/game_details.html')
    game = Game.objects.get(pk=game_id)
    context = {
        'game_title': game.name,
        'game_description': game.description,
        'game_image': game.img_name,
        'game_price': '${:.2f} USD'.format(get_adjusted_price(game.price)),
        'game_price_num': get_adjusted_price(game.price),
        'game_price_num_int': int(round(get_adjusted_price(game.price)*100)),
        'game_with_keys': get_game_with_keys_for_game(game),
        # Set this in a file called secret_data.py. secret_data.py is in the .gitignore so you won't accidentally commit it to a db.
        # STRIPE_KEY_PUBLISHABLE should be the test key on your machine, and the production key on your server
        'stripe_key': secret_data.STRIPE_KEY_PUBLISHABLE,
    }
    return HttpResponse(template.render(context, request))

# Page that displays after purchase and shows error or success.
# Last page the user will see before being prompted to go back home.
# game_id is the primary key of a Game object.
def checkout_page(request, game_id):
    template = loader.get_template('store/post_purchase.html')
    drm = request.POST["drm"]
    add_to_list = request.POST.get('email-list', False)
    email = 'no email'
    game = get_game_with_keys_for_game(Game.objects.get(pk=game_id))

    # Make sure nobody has taken the key while the user was looking at the
    # game detail page.
    key = get_first_unclaimed_key(game, drm)
    has_key = True
    if key == -1:
        has_key = False
    code = None

    if has_key:
        # Set your secret key: remember to change this to your live secret key in production
        # See your keys here https://dashboard.stripe.com/account/apikeys
        # Set this in a file called secret_data.py. secret_data.py is in the .gitignore so you won't accidentally commit it to a db.
        # STRIPE_KEY_SECRET should be the test key on your machine, and the production key on your server
        stripe.api_key = secret_data.STRIPE_KEY_SECRET
        # Get the token generated by stripe.js
        token = request.POST['stripeToken']

        # Try to create the charge on Stripe's servers - this will charge the user's card
        try:
            charge = stripe.Charge.create(
                amount=int(round(get_adjusted_price(game.price)*100)),  # amount in cents, again
                currency="usd",
                source=token,
                description=game.name
            )
            # User email is retrieved from Stripe.
            email = get_email_from_transaction(token)

            # Follow the instructions at:
            #
            # https://docs.djangoproject.com/en/1.9/topics/email/
            #
            # to properly set up Django's email capabilities.
            #
            # Email is required for users to get their keys, although it will display
            # in plain text if email fails for some reason.
            #
            # Replace email@example.com with your email after you've properly
            # gotten Django's email service set up. You might consider putting
            # this email in your secret_data.py file as well.
            #
            # Change fail_silently to False for debugging.
            email_succeeded = send_mail('Your game key', 'You ordered ' + game.name + ' for ' + drm + '. Your key is: ' + key.key_text,
                                        secret_data.EMAIL_ADDRESS, [email], fail_silently=True)

            # Remember who claimed a key. Useful if a user needs you to re-send keys.
            key.claimed_by = email
            key.save()

            # Fallback if email fails.
            if email_succeeded < 1:
                code = key.key_text
            status = True
            message = None
        except stripe.error.CardError, e:
            # The card has been declined
            status = False
            message = e.args
            email_succeeded = -1
            # IMPORTANT: This marks the key as available again.
            key.claimed = False
            key.save()
            pass
        except stripe.error.StripeError, e:
            # Some other Stripe error.
            status = False
            message = e.args
            email_succeeded = -1
            # IMPORTANT: This marks the key as available again.
            key.claimed = False
            key.save()
            pass
    else:
        # Somebody else got the key first, or something else unexpected happened.
        status = False
        email_succeeded = -1
        message = 'Sorry but the key seems to have been taken. You have not been charged.'

    # If user indicated that they'd like to be added to the emailing list, add them.
    if add_to_list and status and email_succeeded > -1:
        try:
            model_email = Email(email=email)
            model_email.save()
        except IntegrityError:
            pass

    context = {
        'errors': message,
        'transaction_status': status,
        'game_price_num': '{:.2f}'.format(get_adjusted_price(game.price)),
        'game_title': game.name,
        'game_description': game.description,
        'game_price': '${:.2f} USD'.format(get_adjusted_price(game.price)),
        'drm': drm,
        'email': email_succeeded,
        'attempted_email': email,
        'code': code,
        'list': add_to_list,
        # Below key should be "pk_test_xxxxxxxxxx" for test,
        # or "pk_live_xxxxxxxxx" for production. Save it in a
        # secret_data file to prevent accidental committing to
        # a repo.
        'stripe_key': secret_data.STRIPE_KEY_PUBLISHABLE,
    }
    return HttpResponse(template.render(context, request))

# Page that displays FAQs for the web store.
def faq(request):
    template = loader.get_template('store/faq.html')
    faqs = Faq.objects.all()
    context = {'faq_list': faqs}
    return HttpResponse(template.render(context, request))

def push_notifications(request, js):
    template = loader.get_template('store/push_notifications.js')
    html = template.render()
    return HttpResponse(html, content_type="application/x-javascript")

def add_subscriber(request):
    subscriberId = request.GET['subscriberId[]']
    newSubscriber = PushSubscriber(sub_id=subscriberId)
    newSubscriber.save()
    return HttpResponse('{"status": "success"}')

def remove_subscriber(request):
    subscriberId = request.GET['subscriberId[]']
    currentSubscriber = PushSubscriber.objects.get(sub_id=subscriberId)
    currentSubscriber.delete()
    return HttpResponse('{"status": "success"}')

# Gets keys from DB.
# drm filters by service (ex. "steam", "origin", "uplay")
# query filters by name (ex. query="co" could return "Counter-Strike: Global Offensive" but not "Far Cry 3")
def get_games_with_keys(drm=None, query=None, new=False):
    games_with_keys = list()

    if new:
        games = get_new_games_from_db()
    else:
        games = get_games_from_db()

    #TODO replace giant conditional tree with clever ORM line instead
    for game in games:
        game_with_key = get_game_with_keys_for_game(game)
        if game_with_key.has_steam or game_with_key.has_origin or game_with_key.has_uplay:
            if drm is None or drm == 'all':
                if query is None or query == '':
                    games_with_keys.append(game_with_key)
                elif query.lower() in game_with_key.name.lower():
                    games_with_keys.append(game_with_key)
            elif drm == 'steam' and game_with_key.has_steam:
                if query is None or query == '':
                    games_with_keys.append(game_with_key)
                elif query.lower() in game_with_key.name.lower():
                    games_with_keys.append(game_with_key)
            elif drm == 'origin' and game_with_key.has_origin:
                if query is None or query == '':
                    games_with_keys.append(game_with_key)
                elif query.lower() in game_with_key.name.lower():
                    games_with_keys.append(game_with_key)
            elif drm == 'uplay' and game_with_key.has_uplay:
                if query is None:
                    games_with_keys.append(game_with_key)
                elif query.lower() in game_with_key.name.lower():
                    games_with_keys.append(game_with_key)
    return games_with_keys

# Returns an object that tells you for what services you have unclaimed keys.
def get_game_with_keys_for_game(game):
    is_steam = False
    is_uplay = False
    is_origin = False
    keys = Key.objects.filter(game_id=game.pk, claimed=False, hidden=False)
    for key in keys:
        if key.service == 'steam':
            is_steam = True
        elif key.service == 'uplay':
            is_uplay = True
        elif key.service == 'origin':
            is_origin = True
    return GameWithKeys(game, is_steam, is_uplay, is_origin)

# Gets the customer email from the Stripe transaction.
# token is the transaction token from Stripe
def get_email_from_transaction(token):
    try:
        return stripe.Token.retrieve(token)['email']
    except stripe.error.InvalidRequestError, e:
        return stripe.BitcoinReceiver.retrieve(token)['email']

# Returns the first key unclaimed for the given service.
# game_with_keys is the game object that we want a key for.
# drm is the service we want the key for. (ex. "steam", "origin", "uplay")
def get_first_unclaimed_key(game_with_keys, drm):
    with transaction.atomic():
        keys = Key.objects.select_for_update().filter(game_id=game_with_keys.id, service=drm)
        for key in keys:
            if key.claimed is False:
                if key.service == drm:
                    key.claimed = True
                    key.save()
                    return key
        keys.update()
    return -1

# Quick convienience method that retuns list of all games from db.
def get_games_from_db():
    games = Game.objects.filter()
    return games

def get_new_games_from_db():
    ref_key = Key.objects.latest('date_added')
    keys = Key.objects.filter(date_added=ref_key.date_added)
    games = list()

    for key in keys:
        games.append(key.game)

    return games

# Method to DRY out price conversions.
def get_adjusted_price(price):
    return price * 1.029 + .3
<|endoftext|>


<commit_before> # -*- coding: utf-8 -*-

try:
    import urlparse as parse  # Py2
except ImportError:
    from urllib import parse  # Py3
try:
    import __builtin__ as builtins  # Py2
except ImportError:
    import builtins  # Py3

import example1
<commit_msg>fixes a single pep8 warning in example2.py under imports_example<commit_after># -*- coding: utf-8 -*-

try:
    import urlparse as parse  # Py2
except ImportError:
    from urllib import parse  # Py3
try:
    import __builtin__ as builtins  # Py2
except ImportError:
    import builtins  # Py3

import example1
<|endoftext|>


<commit_before>"""Smartcard module exceptions.

This module defines the exceptions raised by the smartcard.pcsc modules.

__author__ = "http://www.gemalto.com"

Copyright 2001-2010 gemalto
Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com

This file is part of pyscard.

pyscard is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.

pyscard is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with pyscard; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
"""

# gemalto scard library
import smartcard.scard

class BaseSCardException:
    """Base class for scard (aka PCSC) exceptions.

    scard exceptions are raised by the scard module, i.e.
    low-level PCSC access to readers and cards.

    """

    def __init__(self, hresult):
        """Constructor that stores the pcsc error status."""
        self.hresult = hresult

    def __str__(self):
        """Returns a string representation of the exception."""
        return repr("scard exception: " +
            smartcard.scard.SCardGetErrorMessage(self.hresult))

class AddReaderToGroupException(BaseSCardException):
    """Raised when scard fails to add a new reader to a PCSC reader group."""

    def __init__(self, hresult, readername="", groupname=""):
        BaseSCardException.__init__(self, hresult)
        self.readername = readername
        self.groupname = groupname

    def __str__(self):
        return repr('Failure to add reader: ' + self.readername +
            ' to group: ' + self.groupname + ' ' +
            smartcard.scard.SCardGetErrorMessage(self.hresult))

class EstablishContextException(BaseSCardException):
    """Raised when scard failed to establish context with PCSC."""

    def __str__(self):
        """Returns a string representation of the exception."""
        return repr('Failure to establish context: ' +
            smartcard.scard.SCardGetErrorMessage(self.hresult))

class ListReadersException(BaseSCardException):
    """Raised when scard failed to list readers."""

    def __str__(self):
        return repr('Failure to list readers: ' +
            smartcard.scard.SCardGetErrorMessage(self.hresult))

class IntroduceReaderException(BaseSCardException):
    """Raised when scard fails to introduce a new reader to PCSC."""

    def __init__(self, hresult, readername=""):
        BaseSCardException.__init__(self, hresult)
        self.readername = readername

    def __str__(self):
        return repr('Failure to introduce a new reader: ' + self.readername
            + ' ' + smartcard.scard.SCardGetErrorMessage(self.hresult))

class ReleaseContextException(BaseSCardException):
    """Raised when scard failed to release PCSC context."""

    def __str__(self):
        return repr('Failure to release context: ' +
            smartcard.scard.SCardGetErrorMessage(self.hresult))

class RemoveReaderFromGroupException(BaseSCardException):
    """Raised when scard fails to remove a reader from a PCSC reader group."""

    def __init__(self, hresult, readername="", groupname=""):
        BaseSCardException.__init__(self, hresult)
        self.readername = readername
        self.groupname = groupname

    def __str__(self):
        return repr('Failure to remove reader: ' + self.readername +
            ' from group: ' + self.groupname + ' ' +
            smartcard.scard.SCardGetErrorMessage(self.hresult))

if __name__ == "__main__":
    import sys
    try:
        raise EstablishContextException(smartcard.scard.SCARD_E_NO_MEMORY)
    except BaseSCardException as exc:
        print exc
<commit_msg>do not import sys anymore<commit_after>"""Smartcard module exceptions.

This module defines the exceptions raised by the smartcard.pcsc modules.

__author__ = "http://www.gemalto.com"

Copyright 2001-2010 gemalto
Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com

This file is part of pyscard.

pyscard is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.

pyscard is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with pyscard; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
"""

# gemalto scard library
import smartcard.scard

class BaseSCardException:
    """Base class for scard (aka PCSC) exceptions.

    scard exceptions are raised by the scard module, i.e.
    low-level PCSC access to readers and cards.

    """

    def __init__(self, hresult):
        """Constructor that stores the pcsc error status."""
        self.hresult = hresult

    def __str__(self):
        """Returns a string representation of the exception."""
        return repr("scard exception: " +
            smartcard.scard.SCardGetErrorMessage(self.hresult))

class AddReaderToGroupException(BaseSCardException):
    """Raised when scard fails to add a new reader to a PCSC reader group."""

    def __init__(self, hresult, readername="", groupname=""):
        BaseSCardException.__init__(self, hresult)
        self.readername = readername
        self.groupname = groupname

    def __str__(self):
        return repr('Failure to add reader: ' + self.readername +
            ' to group: ' + self.groupname + ' ' +
            smartcard.scard.SCardGetErrorMessage(self.hresult))

class EstablishContextException(BaseSCardException):
    """Raised when scard failed to establish context with PCSC."""

    def __str__(self):
        """Returns a string representation of the exception."""
        return repr('Failure to establish context: ' +
            smartcard.scard.SCardGetErrorMessage(self.hresult))

class ListReadersException(BaseSCardException):
    """Raised when scard failed to list readers."""

    def __str__(self):
        return repr('Failure to list readers: ' +
            smartcard.scard.SCardGetErrorMessage(self.hresult))

class IntroduceReaderException(BaseSCardException):
    """Raised when scard fails to introduce a new reader to PCSC."""

    def __init__(self, hresult, readername=""):
        BaseSCardException.__init__(self, hresult)
        self.readername = readername

    def __str__(self):
        return repr('Failure to introduce a new reader: ' + self.readername
            + ' ' + smartcard.scard.SCardGetErrorMessage(self.hresult))

class ReleaseContextException(BaseSCardException):
    """Raised when scard failed to release PCSC context."""

    def __str__(self):
        return repr('Failure to release context: ' +
            smartcard.scard.SCardGetErrorMessage(self.hresult))

class RemoveReaderFromGroupException(BaseSCardException):
    """Raised when scard fails to remove a reader from a PCSC reader group."""

    def __init__(self, hresult, readername="", groupname=""):
        BaseSCardException.__init__(self, hresult)
        self.readername = readername
        self.groupname = groupname

    def __str__(self):
        return repr('Failure to remove reader: ' + self.readername +
            ' from group: ' + self.groupname + ' ' +
            smartcard.scard.SCardGetErrorMessage(self.hresult))

if __name__ == "__main__":
    try:
        raise EstablishContextException(smartcard.scard.SCARD_E_NO_MEMORY)
    except BaseSCardException as exc:
        print exc
<|endoftext|>


<commit_before>
def flatten_ec2_result(ec2_result):
    result = []
    for entry in ec2_result["results"]:
        for instance in entry["tagged_instances"]:
            result.append({"hostname": instance["public_dns_name"],
                           "ip": instance["public_ip"],
                           "id": instance["id"],
                           "groups": entry["item"]["value"]["groups"]})

    return result

def compute_ec2_update_lists(pod_name,
                             hosts_spec,
                             state,
                             region,
                             default_ssh_key,
                             default_image,
                             default_instance_type):

    from collections import defaultdict
    from itertools import chain
    from boto import ec2

    conn = ec2.connect_to_region(region)
    if conn is None:
        raise Exception(" ".join((
            "region name:",
            region,
            "likely not supported, or AWS is down."
            "connection to region failed.")))

    reservations = conn.get_all_instances()

    # short-circuit the case where the pod should be terminated
    if state == "absent":
        return {"start": [], "terminate": list(set(
            chain.from_iterable(
                (instance.id for instance in reservation.instances
                 if instance.tags.get("ec2_pod") == pod_name)
                for reservation in reservations)
        ))}

    ec2_host_table = defaultdict(lambda: defaultdict(set))
    for reservation in reservations:
        for instance in reservation.instances:
            if instance.tags.get("ec2_pod") != pod_name:
                continue

            if instance.state not in ("running", "stopped"):
                continue

            instance_name = instance.tags.get("ec2_pod_instance_name")
            composite_key = (unicode(instance_name),
                             unicode(instance.key_name),
                             unicode(instance.image_id),
                             unicode(instance.instance_type))

            ec2_host_table[composite_key][instance.state].add(instance.id)

    host_counter_table = dict(
        ((unicode(key),
          unicode(value.get("ssh_key", default_ssh_key)),
          unicode(value.get("image", default_image)),
          unicode(value.get("type", default_instance_type))),
         value.get("count", 1))
        for key, value in hosts_spec.items())

    start_set = set()
    terminate_set = set()

    for composite_key, sets in ec2_host_table.items():
        running_list = list(sets["running"])
        stopped_list = list(sets["stopped"])

        num_running = len(running_list)
        num_stopped = len(stopped_list)

        num_wanted = host_counter_table.get(composite_key, 0)

        num_to_keep = min(num_running, num_wanted)
        num_to_start = num_wanted - num_to_keep

        start_set |= set(stopped_list[:num_to_start])

        terminate_set |= set(stopped_list[num_to_start:])
        terminate_set |= set(running_list[num_to_keep:])

    return {"start": list(start_set), "terminate": list(terminate_set)}

def compute_ec2_ein_mapping(ec2_result, region, key_id, key):
    from boto import ec2

    conn = ec2.connect_to_region(region,
                                 aws_access_key_id=key_id,
                                 aws_secret_access_key=key)

    if conn is None:
        raise Exception(" ".join((
            "region name:",
            region,
            "likely not supported, or AWS is down."
            "connection to region failed.")))

    reservations = conn.get_all_instances()

    security_group_mapping = {
        group.name: group.id
        for group in conn.get_all_security_groups()
    }

    eni_mapping = {
        eni.attachment.instance_id: eni.id
        for eni in conn.get_all_network_interfaces()
    }

    result = {}
    for entry in ec2_result["results"]:
        groups = [
            security_group_mapping.get(group, group)
            for group in entry["item"]["value"]["group"]]

        result.update({
            eni_mapping[instance["id"]]: groups
            for instance in entry["tagged_instances"]})

    # TODO(opadron): need to remove this once we switch to Ansible 2.0
    for eni_id, groups in result.items():
        conn.modify_network_interface_attribute(interface_id=eni_id,
                                                attr="groupSet",
                                                value=groups)

    return result

def get_ec2_hosts(instance_table):
    import operator as op
    return map(op.itemgetter("id"), instance_table)

def get_ec2_eips(instance_table):
    import operator as op
    return map(
        op.itemgetter("eip", "id"),
        filter(op.itemgetter("eip"), instance_table))

def get_ec2_wait_list(instance_table, host_key):
    import operator as op
    return map(
        op.itemgetter(host_key),
        filter(op.itemgetter("wait"), instance_table))

class FilterModule(object):
    def filters(self):
        return {"compute_ec2_update_lists": compute_ec2_update_lists,
                "flatten_ec2_result": flatten_ec2_result,
                "compute_ec2_ein_mapping": compute_ec2_ein_mapping,
                "get_ec2_wait_list": get_ec2_wait_list,
                "get_ec2_hosts": get_ec2_hosts,
                "get_ec2_eips": get_ec2_eips}

<commit_msg>update filter plugin: compute_ec2_update_lists<commit_after>
def flatten_ec2_result(ec2_result):
    result = []
    for entry in ec2_result["results"]:
        for instance in entry["tagged_instances"]:
            result.append({"hostname": instance["public_dns_name"],
                           "ip": instance["public_ip"],
                           "id": instance["id"],
                           "groups": entry["item"]["value"]["groups"]})

    return result

def compute_ec2_update_lists(pod_name, instances, state, region, key_id, key):
    from collections import defaultdict
    from itertools import chain
    from boto import ec2

    conn = ec2.connect_to_region(region,
                                 aws_access_key_id=key_id,
                                 aws_secret_access_key=key)

    if conn is None:
        raise Exception(" ".join((
            "region name:",
            region,
            "likely not supported, or AWS is down."
            "connection to region failed.")))

    reservations = conn.get_all_instances()

    # short-circuit the case where the pod should be terminated
    if state == "absent":
        return {"start": [], "terminate": list(set(
            chain.from_iterable(
                (instance.id for instance in reservation.instances
                 if instance.tags.get("ec2_pod") == pod_name)
                for reservation in reservations)
        ))}

    ec2_host_table = defaultdict(lambda: defaultdict(set))
    for reservation in reservations:
        for instance in reservation.instances:
            if instance.tags.get("ec2_pod") != pod_name:
                continue

            if instance.state not in ("running", "stopped"):
                continue

            instance_name = instance.tags.get("ec2_pod_instance_name")
            composite_key = (unicode(instance_name),
                             unicode(instance.key_name),
                             unicode(instance.image_id),
                             unicode(instance.instance_type))

            ec2_host_table[composite_key][instance.state].add(instance.id)

    host_counter_table = dict(
        (
            (
                unicode(instance["count_tag"]["ec2_pod_instance_name"]),
                unicode(instance["ssh_key"]),
                unicode(instance["image"]),
                unicode(instance["type"])
            ),
            instance.get("count", 1)
        )
        for instance in instances.values()
    )

    start_set = set()
    terminate_set = set()

    for composite_key, sets in ec2_host_table.items():
        running_list = list(sets["running"])
        stopped_list = list(sets["stopped"])

        num_running = len(running_list)
        num_stopped = len(stopped_list)

        num_wanted = host_counter_table.get(composite_key, 0)

        num_to_keep = min(num_running, num_wanted)
        num_to_start = num_wanted - num_to_keep

        start_set |= set(stopped_list[:num_to_start])

        terminate_set |= set(stopped_list[num_to_start:])
        terminate_set |= set(running_list[num_to_keep:])

    return {"start": list(start_set), "terminate": list(terminate_set)}

def compute_ec2_ein_mapping(ec2_result, region, key_id, key):
    from boto import ec2

    conn = ec2.connect_to_region(region,
                                 aws_access_key_id=key_id,
                                 aws_secret_access_key=key)

    if conn is None:
        raise Exception(" ".join((
            "region name:",
            region,
            "likely not supported, or AWS is down."
            "connection to region failed.")))

    reservations = conn.get_all_instances()

    security_group_mapping = {
        group.name: group.id
        for group in conn.get_all_security_groups()
    }

    eni_mapping = {
        eni.attachment.instance_id: eni.id
        for eni in conn.get_all_network_interfaces()
    }

    result = {}
    for entry in ec2_result["results"]:
        groups = [
            security_group_mapping.get(group, group)
            for group in entry["item"]["value"]["group"]]

        result.update({
            eni_mapping[instance["id"]]: groups
            for instance in entry["tagged_instances"]})

    # TODO(opadron): need to remove this once we switch to Ansible 2.0
    for eni_id, groups in result.items():
        conn.modify_network_interface_attribute(interface_id=eni_id,
                                                attr="groupSet",
                                                value=groups)

    return result

def get_ec2_hosts(instance_table):
    import operator as op
    return map(op.itemgetter("id"), instance_table)

def get_ec2_eips(instance_table):
    import operator as op
    return map(
        op.itemgetter("eip", "id"),
        filter(op.itemgetter("eip"), instance_table))

def get_ec2_wait_list(instance_table, host_key):
    import operator as op
    return map(
        op.itemgetter(host_key),
        filter(op.itemgetter("wait"), instance_table))

class FilterModule(object):
    def filters(self):
        return {"compute_ec2_update_lists": compute_ec2_update_lists,
                "flatten_ec2_result": flatten_ec2_result,
                "compute_ec2_ein_mapping": compute_ec2_ein_mapping,
                "get_ec2_wait_list": get_ec2_wait_list,
                "get_ec2_hosts": get_ec2_hosts,
                "get_ec2_eips": get_ec2_eips}

<|endoftext|>


<commit_before>try:
    import ujson as json
except ImportError:
    import json

from networktables import NetworkTables

__all__ = ["NTSerial"]

class NTSerial(object):
    """
    A utility class for synchronizing NetworkTables over a serial connection.
    """

    def __init__(self, update_callback):
        """
        :param update_callback: A callable with signature ```callable(update)``` for processing outgoing updates
        formatted as strings.
        """
        self.update_callback = update_callback
        self.nt = NetworkTables.getGlobalTable()
        NetworkTables.addGlobalListener(self._nt_on_change, immediateNotify=True)
        self.nt.addConnectionListener(self._nt_connected, immediateNotify=True)

    def process_update(self, update):
        """Process an incoming update from a remote NetworkTables"""
        data = json.loads(update)
        self.nt.putValue(data['k'], data['v'])

    def _send_update(self, data):
        """Send a NetworkTables update via the stored send_update callback"""
        if isinstance(data, dict):
            data = json.dumps(data)
        self.update_callback(data)

    def _nt_on_change(self, key, value, isNew):
        """NetworkTables global listener callback"""
        self._send_update({'k': key, 'v': value, 'n': isNew})

    # NetworkTables connection listener callbacks
    def _nt_connected(self, connected, info):
        self._send_update({'r': connected, 'a': self.nt.getRemoteAddress()})

    def close(self):
        """
        Clean up NetworkTables listeners
        """
        NetworkTables.removeGlobalListener(self._nt_on_change)
        self.nt.removeConnectionListener(self._nt_connected)
<commit_msg>Remove deprecated NT apis<commit_after>try:
    import ujson as json
except ImportError:
    import json

from networktables import NetworkTables

__all__ = ["NTSerial"]

class NTSerial(object):
    """
    A utility class for synchronizing NetworkTables over a serial connection.
    """

    def __init__(self, update_callback):
        """
        :param update_callback: A callable with signature ```callable(update)``` for processing outgoing updates
        formatted as strings.
        """
        self.update_callback = update_callback
        self.nt = NetworkTables.getGlobalTable()
        NetworkTables.addGlobalListener(self._nt_on_change, immediateNotify=True)
        NetworkTables.addConnectionListener(self._nt_connected, immediateNotify=True)

    def process_update(self, update):
        """Process an incoming update from a remote NetworkTables"""
        data = json.loads(update)
        self.nt.putValue(data['k'], data['v'])

    def _send_update(self, data):
        """Send a NetworkTables update via the stored send_update callback"""
        if isinstance(data, dict):
            data = json.dumps(data)
        self.update_callback(data)

    def _nt_on_change(self, key, value, isNew):
        """NetworkTables global listener callback"""
        self._send_update({'k': key, 'v': value, 'n': isNew})

    # NetworkTables connection listener callbacks
    def _nt_connected(self, connected, info):
        self._send_update({'r': connected, 'a': NetworkTables.getRemoteAddress()})

    def close(self):
        """
        Clean up NetworkTables listeners
        """
        NetworkTables.removeGlobalListener(self._nt_on_change)
        NetworkTables.removeConnectionListener(self._nt_connected)
<|endoftext|>


<commit_before>"""
Python EDA Package
"""

__version__ = "0.16.0"
<commit_msg>Release 0.16.1<commit_after>"""
Python EDA Package
"""

__version__ = "0.16.1"
<|endoftext|>


<commit_before>import time
import handlers
import games
import games.settlers.stats
import hlib
import hlib.log
import hlib.error
import hlib.event
import events.game
import tournaments

import hlib.event

import lib.play

# Handlers
from handlers import page, require_write, require_hosts
from hlib.api import api

from hlib.input import validate_by

# pylint: disable-msg=F0401
import hruntime

maint_require_hosts = lambda: hruntime.app.config['hosts']['maint.*']

class Handler(handlers.GenericHandler):
  @require_hosts(get_hosts = maint_require_hosts)
  @require_write
  @api
  def process_free_deadlines(self):
    canceled = []

    for g in hruntime.dbroot.games.values():
      if not g.is_waiting_begin or g.deadline > hruntime.time:
        continue

      t = (g.id, g.type, hruntime.time - g.deadline)
      g.cancel(reason = events.game.GameCanceled.REASON_EMPTY, user = None)
      canceled.append(t)

    return hlib.api.Reply(200, canceled_games = canceled)

  @require_hosts(get_hosts = maint_require_hosts)
  @require_write
  @api
  def process_active_deadlines(self):
    canceled = []

    for g in hruntime.dbroot.games.values():
      if not g.is_waiting_turn or g.deadline > hruntime.time:
        continue

      d = [g.id, hruntime.time - g.deadline, [p.user.name for p in g.players.values()], g.forhont_player.user.name]

      g.cancel(reason = events.game.GameCanceled.REASON_ABSENTEE, user = g.forhont_player.user)
      canceled.append(d)

    return hlib.api.Reply(200, canceled_games = canceled)

  @require_hosts(get_hosts = maint_require_hosts)
  @require_write
  @api
  def process_archive_deadlines(self):
    def __process_list(playable_list, playable_archived_list, event_name, handle_name):
      archived = []

      for p in playable_list.values():
        try:
          if p.archive_deadline >= hruntime.time:
            continue

        except lib.play.CannotBeArchivedError:
          continue

        archived.append(p)

      for p in archived:
        del playable_list[p.id]

        playable_archived_list[p.id] = p

        # pylint: disable-msg=W0142
        hlib.event.trigger(event_name, p, **{handle_name: p})

      return [p.id for p in archived]

    return hlib.api.Reply(200, archived_games = __process_list(hruntime.dbroot.games, hruntime.dbroot.games_archived, 'game.GameArchived', 'game'),
                               archived_tournaments = __process_list(hruntime.dbroot.tournaments, hruntime.dbroot.tournaments_archived, 'tournament.Archived', 'tournament'))

  @require_hosts(get_hosts = maint_require_hosts)
  @require_write
  @validate_by(schema = games.GenericValidateKind)
  @api
  def refresh_stats_games(self, kind = None):
    gm = games.game_module(kind, submodule = 'stats')
    gm.stats.refresh_stats()

  @require_hosts(get_hosts = maint_require_hosts)
  @require_write
  @api
  def create_system_games(self):
    def __create_games(count, limit, sleep = 5):
      for _ in range(0, count):
        games.create_system_game('settlers', limit = limit, turn_limit = 604800)
        time.sleep(sleep)
        hruntime.time = None

    cnt = hruntime.app.config['system_games.limit'] - hruntime.dbroot.counters.games_free()
    if cnt > 0:
      __create_games(cnt, 3, sleep = hruntime.app.config['system_games.sleep'])

      # pylint: disable-msg=W0212
      games._game_lists.inval_all('active')

    else:
      cnt = 0

    return hlib.api.Reply(200, created_games = cnt)

  @require_hosts(get_hosts = maint_require_hosts)
  @require_write
  @api
  def pack_db(self):
    hruntime.db.pack()
<commit_msg>Output the same info for free/running games when dumping in maint handler<commit_after>import time
import handlers
import games
import games.settlers.stats
import hlib
import hlib.log
import hlib.error
import hlib.event
import events.game
import tournaments

import hlib.event

import lib.play

# Handlers
from handlers import page, require_write, require_hosts
from hlib.api import api

from hlib.input import validate_by

# pylint: disable-msg=F0401
import hruntime

maint_require_hosts = lambda: hruntime.app.config['hosts']['maint.*']

class Handler(handlers.GenericHandler):
  @require_hosts(get_hosts = maint_require_hosts)
  @require_write
  @api
  def process_free_deadlines(self):
    canceled = []

    for g in hruntime.dbroot.games.values():
      if not g.is_waiting_begin or g.deadline > hruntime.time:
        continue

      t = (g.id, g.type, hruntime.time - g.deadline, [p.user.name for p in g.players.values()], g.forhont_player.user.name)
      g.cancel(reason = events.game.GameCanceled.REASON_EMPTY, user = None)
      canceled.append(t)

    return hlib.api.Reply(200, canceled_games = canceled)

  @require_hosts(get_hosts = maint_require_hosts)
  @require_write
  @api
  def process_active_deadlines(self):
    canceled = []

    for g in hruntime.dbroot.games.values():
      if not g.is_waiting_turn or g.deadline > hruntime.time:
        continue

      t = (g.id, g.type, hruntime.time - g.deadline, [p.user.name for p in g.players.values()], g.forhont_player.user.name)
      #g.cancel(reason = events.game.GameCanceled.REASON_ABSENTEE, user = g.forhont_player.user)
      canceled.append(t)

    return hlib.api.Reply(200, canceled_games = canceled)

  @require_hosts(get_hosts = maint_require_hosts)
  @require_write
  @api
  def process_archive_deadlines(self):
    def __process_list(playable_list, playable_archived_list, event_name, handle_name):
      archived = []

      for p in playable_list.values():
        try:
          if p.archive_deadline >= hruntime.time:
            continue

        except lib.play.CannotBeArchivedError:
          continue

        archived.append(p)

      for p in archived:
        del playable_list[p.id]

        playable_archived_list[p.id] = p

        # pylint: disable-msg=W0142
        hlib.event.trigger(event_name, p, **{handle_name: p})

      return [p.id for p in archived]

    return hlib.api.Reply(200, archived_games = __process_list(hruntime.dbroot.games, hruntime.dbroot.games_archived, 'game.GameArchived', 'game'),
                               archived_tournaments = __process_list(hruntime.dbroot.tournaments, hruntime.dbroot.tournaments_archived, 'tournament.Archived', 'tournament'))

  @require_hosts(get_hosts = maint_require_hosts)
  @require_write
  @validate_by(schema = games.GenericValidateKind)
  @api
  def refresh_stats_games(self, kind = None):
    gm = games.game_module(kind, submodule = 'stats')
    gm.stats.refresh_stats()

  @require_hosts(get_hosts = maint_require_hosts)
  @require_write
  @api
  def create_system_games(self):
    def __create_games(count, limit, sleep = 5):
      for _ in range(0, count):
        games.create_system_game('settlers', limit = limit, turn_limit = 604800)
        time.sleep(sleep)
        hruntime.time = None

    cnt = hruntime.app.config['system_games.limit'] - hruntime.dbroot.counters.games_free()
    if cnt > 0:
      __create_games(cnt, 3, sleep = hruntime.app.config['system_games.sleep'])

      # pylint: disable-msg=W0212
      games._game_lists.inval_all('active')

    else:
      cnt = 0

    return hlib.api.Reply(200, created_games = cnt)

  @require_hosts(get_hosts = maint_require_hosts)
  @require_write
  @api
  def pack_db(self):
    hruntime.db.pack()
<|endoftext|>


<commit_before>"""fips verb to build the oryol samples webpage"""

import os
import yaml
import shutil
import subprocess
import glob
from string import Template

from mod import log, util, project, emscripten, android, nacl
from tools import texexport

GitHubSamplesURL = 'https://github.com/floooh/oryol/tree/master/code/Samples/'

BuildEmscripten = True
BuildPNaCl = True
BuildWasm = True
ExportAssets = True

#-------------------------------------------------------------------------------
def deploy_webpage(fips_dir, proj_dir, webpage_dir) :
    """builds the final webpage under under fips-deploy/oryol-webpage"""
    ws_dir = util.get_workspace_dir(fips_dir)

    # load the websamples.yml file, should have been created during the last build
    with open(webpage_dir + '/websamples.yml', 'r') as f :
        samples = yaml.load(f.read())

    # create directories
    for platform in ['asmjs', 'wasm', 'pnacl'] :
        platform_dir = '{}/{}'.format(webpage_dir, platform)
        if not os.path.isdir(platform_dir) :
            os.makedirs(platform_dir)

    # build the thumbnail gallery
    content = ''
    for sample in samples :
        if sample['name'] != '__end__' :
            name    = sample['name']
            imgPath = sample['image']
            types   = sample['type']
            desc    = sample['desc']
            head, tail = os.path.split(imgPath)
            if tail == 'none' :
                imgFileName = 'dummy.jpg'
            else :
                imgFileName = tail
            content += '
\n'
            content += '
{}
\n'.format(name)
            content += '

\n'.format(name,imgFileName,desc)
            content += '
\n'
            content += '
\n'
            if 'emscripten' in types :
                content += '
asm.js
\n'.format(name)
            if 'pnacl' in types :
                content += '
pnacl
\n'.format(name)
            if 'emscripten' in types :
                content += '
wasm
\n'.format(name)
            content += '
\n'
            content += '
\n'
            content += '
\n'

    # populate the html template, and write to the build directory
    with open(proj_dir + '/web/index.html', 'r') as f :
        templ = Template(f.read())
    html = templ.safe_substitute(samples=content)
    with open(webpage_dir + '/index.html', 'w') as f :
        f.write(html)

    # copy other required files
    for name in ['style.css', 'dummy.jpg', 'emsc.js', 'pnacl.js', 'wasm.js', 'about.html', 'favicon.png'] :
        log.info('> copy file: {}'.format(name))
        shutil.copy(proj_dir + '/web/' + name, webpage_dir + '/' + name)

    # generate emscripten HTML pages
    if BuildEmscripten and emscripten.check_exists(fips_dir) :
        emsc_deploy_dir = '{}/fips-deploy/oryol/emsc-ninja-release'.format(ws_dir)
        for sample in samples :
            name = sample['name']
            if name != '__end__' and 'emscripten' in sample['type'] :
                log.info('> generate emscripten HTML page: {}'.format(name))
                for ext in ['js', 'html.mem'] :
                    src_path = '{}/{}.{}'.format(emsc_deploy_dir, name, ext)
                    if os.path.isfile(src_path) :
                        shutil.copy(src_path, '{}/asmjs/'.format(webpage_dir))
                with open(proj_dir + '/web/emsc.html', 'r') as f :
                    templ = Template(f.read())
                src_url = GitHubSamplesURL + sample['src'];
                html = templ.safe_substitute(name=name, source=src_url)
                with open('{}/asmjs/{}.html'.format(webpage_dir, name, name), 'w') as f :
                    f.write(html)

    # generate WebAssembly HTML pages
    if BuildWasm and emscripten.check_exists(fips_dir) :
        wasm_deploy_dir = '{}/fips-deploy/oryol/wasm-ninja-release'.format(ws_dir)
        for sample in samples :
            name = sample['name']
            if name != '__end__' and 'emscripten' in sample['type'] :
                log.info('> generate wasm HTML page: {}'.format(name))
                for ext in ['js', 'wasm.mappedGlobals'] :
                    src_path = '{}/{}.{}'.format(wasm_deploy_dir, name, ext)
                    if os.path.isfile(src_path) :
                        shutil.copy(src_path, '{}/wasm/'.format(webpage_dir))
                for ext in ['html.mem', 'wasm'] :
                    src_path = '{}/{}.{}'.format(wasm_deploy_dir, name, ext)
                    if os.path.isfile(src_path) :
                        shutil.copy(src_path, '{}/wasm/{}.{}.txt'.format(webpage_dir, name, ext))
                with open(proj_dir + '/web/wasm.html', 'r') as f :
                    templ = Template(f.read())
                src_url = GitHubSamplesURL + sample['src'];
                html = templ.safe_substitute(name=name, source=src_url)
                with open('{}/wasm/{}.html'.format(webpage_dir, name), 'w') as f :
                    f.write(html)

    # generate PNaCl HTML pages
    if BuildPNaCl and nacl.check_exists(fips_dir) :
        pnacl_deploy_dir = '{}/fips-deploy/oryol/pnacl-ninja-release'.format(ws_dir)
        for sample in samples :
            name = sample['name']
            if name != '__end__' and 'pnacl' in sample['type'] :
                log.info('> generate PNaCl HTML page: {}'.format(name))
                for ext in ['nmf', 'pexe'] :
                    src_path = '{}/{}.{}'.format(pnacl_deploy_dir, name, ext)
                    if os.path.isfile(src_path) :
                        shutil.copy(src_path, '{}/pnacl/'.format(webpage_dir))
                with open(proj_dir + '/web/pnacl.html', 'r') as f :
                    templ = Template(f.read())
                src_url = GitHubSamplesURL + sample['src'];
                html = templ.safe_substitute(name=name, source=src_url)
                with open('{}/pnacl/{}.html'.format(webpage_dir, name), 'w') as f :
                    f.write(html)

    # copy the screenshots
    for sample in samples :
        if sample['name'] != '__end__' :
            img_path = sample['image']
            head, tail = os.path.split(img_path)
            if tail != 'none' :
                log.info('> copy screenshot: {}'.format(tail))
                shutil.copy(img_path, webpage_dir + '/' + tail)

#-------------------------------------------------------------------------------
def export_assets(fips_dir, proj_dir, webpage_dir) :

    tex_srcdir = proj_dir + '/data'
    tex_dstdir = webpage_dir + '/data'
    texexport.configure(proj_dir, tex_srcdir, tex_dstdir)
    texexport.exportSampleTextures()
    for ext in ['txt', 'dump'] :
        for dataFile in glob.glob(proj_dir + '/data/*.{}'.format(ext)) :
            shutil.copy(dataFile, '{}/data/'.format(webpage_dir))
    tbui_from = '{}/data/tbui'.format(proj_dir)
    tbui_to   = '{}/data/tbui'.format(webpage_dir)
    shutil.copytree(tbui_from, tbui_to)

#-------------------------------------------------------------------------------
def build_deploy_webpage(fips_dir, proj_dir) :
    # if webpage dir exists, clear it first
    ws_dir = util.get_workspace_dir(fips_dir)
    webpage_dir = '{}/fips-deploy/oryol-webpage'.format(ws_dir)
    if os.path.isdir(webpage_dir) :
        shutil.rmtree(webpage_dir)
    os.makedirs(webpage_dir)

    # compile samples
    if BuildPNaCl and nacl.check_exists(fips_dir) :
        project.gen(fips_dir, proj_dir, 'pnacl-ninja-release')
        project.build(fips_dir, proj_dir, 'pnacl-ninja-release')
    if BuildEmscripten and emscripten.check_exists(fips_dir) :
        project.gen(fips_dir, proj_dir, 'emsc-ninja-release')
        project.build(fips_dir, proj_dir, 'emsc-ninja-release')
    if BuildWasm and emscripten.check_exists(fips_dir) :
        project.gen(fips_dir, proj_dir, 'wasm-ninja-release')
        project.build(fips_dir, proj_dir, 'wasm-ninja-release')

    # export sample assets
    if ExportAssets :
        export_assets(fips_dir, proj_dir, webpage_dir)

    # deploy the webpage
    deploy_webpage(fips_dir, proj_dir, webpage_dir)

    log.colored(log.GREEN, 'Generated Samples web page under {}.'.format(webpage_dir))

#-------------------------------------------------------------------------------
def serve_webpage(fips_dir, proj_dir) :
    ws_dir = util.get_workspace_dir(fips_dir)
    webpage_dir = '{}/fips-deploy/oryol-webpage'.format(ws_dir)
    p = util.get_host_platform()
    if p == 'osx' :
        try :
            subprocess.call(
                'open http://localhost:8000 ; python {}/mod/httpserver.py'.format(fips_dir),
                cwd = webpage_dir, shell=True)
        except KeyboardInterrupt :
            pass
    elif p == 'win':
        try:
            subprocess.call(
                'cmd /c start http://localhost:8000 && python {}/mod/httpserver.py'.format(fips_dir),
                cwd = webpage_dir, shell=True)
        except KeyboardInterrupt:
            pass
    elif p == 'linux':
        try:
            subprocess.call(
                'xdg-open http://localhost:8000; python {}/mod/httpserver.py'.format(fips_dir),
                cwd = webpage_dir, shell=True)
        except KeyboardInterrupt:
            pass

#-------------------------------------------------------------------------------
def run(fips_dir, proj_dir, args) :
    if len(args) > 0 :
        if args[0] == 'build' :
            build_deploy_webpage(fips_dir, proj_dir)
        elif args[0] == 'serve' :
            serve_webpage(fips_dir, proj_dir)
        else :
            log.error("Invalid param '{}', expected 'build' or 'serve'".format(args[0]))
    else :
        log.error("Param 'build' or 'serve' expected")

#-------------------------------------------------------------------------------
def help() :
    log.info(log.YELLOW +
             'fips webpage build\n' +
             'fips webpage serve\n' +
             log.DEF +
             '    build oryol samples webpage')

<commit_msg>Disable WebAssembly samples by default (requires manual SDK setup)<commit_after>"""fips verb to build the oryol samples webpage"""

import os
import yaml
import shutil
import subprocess
import glob
from string import Template

from mod import log, util, project, emscripten, android, nacl
from tools import texexport

GitHubSamplesURL = 'https://github.com/floooh/oryol/tree/master/code/Samples/'

BuildEmscripten = True
BuildPNaCl = True
BuildWasm = False
ExportAssets = True

#-------------------------------------------------------------------------------
def deploy_webpage(fips_dir, proj_dir, webpage_dir) :
    """builds the final webpage under under fips-deploy/oryol-webpage"""
    ws_dir = util.get_workspace_dir(fips_dir)

    # load the websamples.yml file, should have been created during the last build
    with open(webpage_dir + '/websamples.yml', 'r') as f :
        samples = yaml.load(f.read())

    # create directories
    for platform in ['asmjs', 'wasm', 'pnacl'] :
        platform_dir = '{}/{}'.format(webpage_dir, platform)
        if not os.path.isdir(platform_dir) :
            os.makedirs(platform_dir)

    # build the thumbnail gallery
    content = ''
    for sample in samples :
        if sample['name'] != '__end__' :
            name    = sample['name']
            imgPath = sample['image']
            types   = sample['type']
            desc    = sample['desc']
            head, tail = os.path.split(imgPath)
            if tail == 'none' :
                imgFileName = 'dummy.jpg'
            else :
                imgFileName = tail
            content += '
\n'
            content += '
{}
\n'.format(name)
            content += '

\n'.format(name,imgFileName,desc)
            content += '
\n'
            content += '
\n'
            if 'emscripten' in types :
                content += '
asm.js
\n'.format(name)
            if 'pnacl' in types :
                content += '
pnacl
\n'.format(name)
            if 'emscripten' in types :
                content += '
wasm
\n'.format(name)
            content += '
\n'
            content += '
\n'
            content += '
\n'

    # populate the html template, and write to the build directory
    with open(proj_dir + '/web/index.html', 'r') as f :
        templ = Template(f.read())
    html = templ.safe_substitute(samples=content)
    with open(webpage_dir + '/index.html', 'w') as f :
        f.write(html)

    # copy other required files
    for name in ['style.css', 'dummy.jpg', 'emsc.js', 'pnacl.js', 'wasm.js', 'about.html', 'favicon.png'] :
        log.info('> copy file: {}'.format(name))
        shutil.copy(proj_dir + '/web/' + name, webpage_dir + '/' + name)

    # generate emscripten HTML pages
    if BuildEmscripten and emscripten.check_exists(fips_dir) :
        emsc_deploy_dir = '{}/fips-deploy/oryol/emsc-ninja-release'.format(ws_dir)
        for sample in samples :
            name = sample['name']
            if name != '__end__' and 'emscripten' in sample['type'] :
                log.info('> generate emscripten HTML page: {}'.format(name))
                for ext in ['js', 'html.mem'] :
                    src_path = '{}/{}.{}'.format(emsc_deploy_dir, name, ext)
                    if os.path.isfile(src_path) :
                        shutil.copy(src_path, '{}/asmjs/'.format(webpage_dir))
                with open(proj_dir + '/web/emsc.html', 'r') as f :
                    templ = Template(f.read())
                src_url = GitHubSamplesURL + sample['src'];
                html = templ.safe_substitute(name=name, source=src_url)
                with open('{}/asmjs/{}.html'.format(webpage_dir, name, name), 'w') as f :
                    f.write(html)

    # generate WebAssembly HTML pages
    if BuildWasm and emscripten.check_exists(fips_dir) :
        wasm_deploy_dir = '{}/fips-deploy/oryol/wasm-ninja-release'.format(ws_dir)
        for sample in samples :
            name = sample['name']
            if name != '__end__' and 'emscripten' in sample['type'] :
                log.info('> generate wasm HTML page: {}'.format(name))
                for ext in ['js', 'wasm.mappedGlobals'] :
                    src_path = '{}/{}.{}'.format(wasm_deploy_dir, name, ext)
                    if os.path.isfile(src_path) :
                        shutil.copy(src_path, '{}/wasm/'.format(webpage_dir))
                for ext in ['html.mem', 'wasm'] :
                    src_path = '{}/{}.{}'.format(wasm_deploy_dir, name, ext)
                    if os.path.isfile(src_path) :
                        shutil.copy(src_path, '{}/wasm/{}.{}.txt'.format(webpage_dir, name, ext))
                with open(proj_dir + '/web/wasm.html', 'r') as f :
                    templ = Template(f.read())
                src_url = GitHubSamplesURL + sample['src'];
                html = templ.safe_substitute(name=name, source=src_url)
                with open('{}/wasm/{}.html'.format(webpage_dir, name), 'w') as f :
                    f.write(html)

    # generate PNaCl HTML pages
    if BuildPNaCl and nacl.check_exists(fips_dir) :
        pnacl_deploy_dir = '{}/fips-deploy/oryol/pnacl-ninja-release'.format(ws_dir)
        for sample in samples :
            name = sample['name']
            if name != '__end__' and 'pnacl' in sample['type'] :
                log.info('> generate PNaCl HTML page: {}'.format(name))
                for ext in ['nmf', 'pexe'] :
                    src_path = '{}/{}.{}'.format(pnacl_deploy_dir, name, ext)
                    if os.path.isfile(src_path) :
                        shutil.copy(src_path, '{}/pnacl/'.format(webpage_dir))
                with open(proj_dir + '/web/pnacl.html', 'r') as f :
                    templ = Template(f.read())
                src_url = GitHubSamplesURL + sample['src'];
                html = templ.safe_substitute(name=name, source=src_url)
                with open('{}/pnacl/{}.html'.format(webpage_dir, name), 'w') as f :
                    f.write(html)

    # copy the screenshots
    for sample in samples :
        if sample['name'] != '__end__' :
            img_path = sample['image']
            head, tail = os.path.split(img_path)
            if tail != 'none' :
                log.info('> copy screenshot: {}'.format(tail))
                shutil.copy(img_path, webpage_dir + '/' + tail)

#-------------------------------------------------------------------------------
def export_assets(fips_dir, proj_dir, webpage_dir) :

    tex_srcdir = proj_dir + '/data'
    tex_dstdir = webpage_dir + '/data'
    texexport.configure(proj_dir, tex_srcdir, tex_dstdir)
    texexport.exportSampleTextures()
    for ext in ['txt', 'dump'] :
        for dataFile in glob.glob(proj_dir + '/data/*.{}'.format(ext)) :
            shutil.copy(dataFile, '{}/data/'.format(webpage_dir))
    tbui_from = '{}/data/tbui'.format(proj_dir)
    tbui_to   = '{}/data/tbui'.format(webpage_dir)
    shutil.copytree(tbui_from, tbui_to)

#-------------------------------------------------------------------------------
def build_deploy_webpage(fips_dir, proj_dir) :
    # if webpage dir exists, clear it first
    ws_dir = util.get_workspace_dir(fips_dir)
    webpage_dir = '{}/fips-deploy/oryol-webpage'.format(ws_dir)
    if os.path.isdir(webpage_dir) :
        shutil.rmtree(webpage_dir)
    os.makedirs(webpage_dir)

    # compile samples
    if BuildPNaCl and nacl.check_exists(fips_dir) :
        project.gen(fips_dir, proj_dir, 'pnacl-ninja-release')
        project.build(fips_dir, proj_dir, 'pnacl-ninja-release')
    if BuildEmscripten and emscripten.check_exists(fips_dir) :
        project.gen(fips_dir, proj_dir, 'emsc-ninja-release')
        project.build(fips_dir, proj_dir, 'emsc-ninja-release')
    if BuildWasm and emscripten.check_exists(fips_dir) :
        project.gen(fips_dir, proj_dir, 'wasm-ninja-release')
        project.build(fips_dir, proj_dir, 'wasm-ninja-release')

    # export sample assets
    if ExportAssets :
        export_assets(fips_dir, proj_dir, webpage_dir)

    # deploy the webpage
    deploy_webpage(fips_dir, proj_dir, webpage_dir)

    log.colored(log.GREEN, 'Generated Samples web page under {}.'.format(webpage_dir))

#-------------------------------------------------------------------------------
def serve_webpage(fips_dir, proj_dir) :
    ws_dir = util.get_workspace_dir(fips_dir)
    webpage_dir = '{}/fips-deploy/oryol-webpage'.format(ws_dir)
    p = util.get_host_platform()
    if p == 'osx' :
        try :
            subprocess.call(
                'open http://localhost:8000 ; python {}/mod/httpserver.py'.format(fips_dir),
                cwd = webpage_dir, shell=True)
        except KeyboardInterrupt :
            pass
    elif p == 'win':
        try:
            subprocess.call(
                'cmd /c start http://localhost:8000 && python {}/mod/httpserver.py'.format(fips_dir),
                cwd = webpage_dir, shell=True)
        except KeyboardInterrupt:
            pass
    elif p == 'linux':
        try:
            subprocess.call(
                'xdg-open http://localhost:8000; python {}/mod/httpserver.py'.format(fips_dir),
                cwd = webpage_dir, shell=True)
        except KeyboardInterrupt:
            pass

#-------------------------------------------------------------------------------
def run(fips_dir, proj_dir, args) :
    if len(args) > 0 :
        if args[0] == 'build' :
            build_deploy_webpage(fips_dir, proj_dir)
        elif args[0] == 'serve' :
            serve_webpage(fips_dir, proj_dir)
        else :
            log.error("Invalid param '{}', expected 'build' or 'serve'".format(args[0]))
    else :
        log.error("Param 'build' or 'serve' expected")

#-------------------------------------------------------------------------------
def help() :
    log.info(log.YELLOW +
             'fips webpage build\n' +
             'fips webpage serve\n' +
             log.DEF +
             '    build oryol samples webpage')

<|endoftext|>