<commit_before>import math

from django.shortcuts import get_object_or_404
from django.http import HttpResponseRedirect
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required
from django.conf import settings
from django.core.urlresolvers import reverse
from django.db import connection

from pybb.util import render_to, paged, build_form, quote_text
from pybb.models import Category, Forum, Topic, Post, Profile, PrivateMessage
from pybb.forms import AddPostForm, EditProfileForm, EditPostForm, UserSearchForm, CreatePMForm
from pybb import settings as pybb_settings

def index_ctx(request):
    quick = {'posts': Post.objects.count(),
             'topics': Topic.objects.count(),
             'users': User.objects.count(),
             'last_topics': Topic.objects.all().select_related()[:pybb_settings.QUICK_TOPICS_NUMBER],
             'last_posts': Post.objects.order_by('-created').select_related()[:pybb_settings.QUICK_POSTS_NUMBER],
             }

    cats = {}
    forums = {}

    for forum in Forum.objects.all().select_related():
        cat = cats.setdefault(forum.category.id,
            {'cat': forum.category, 'forums': []})
        cat['forums'].append(forum)
        forums[forum.id] = forum

    cmpdef = lambda a, b: cmp(a['cat'].position, b['cat'].position)
    cats = sorted(cats.values(), cmpdef)

    return {'cats': cats,
            'quick': quick,
            }
index = render_to('pybb/index.html')(index_ctx)

def show_category_ctx(request, category_id):
    category = Category.objects.get(pk=category_id)
    quick = {'posts': category.posts.count(),
             'topics': category.topics.count(),
             'last_topics': category.topics.select_related()[:pybb_settings.QUICK_TOPICS_NUMBER],
             'last_posts': category.posts.order_by('-created').select_related()[:pybb_settings.QUICK_POSTS_NUMBER],
             }
    return {'category': category,
            'quick': quick,
            }
show_category = render_to('pybb/category.html')(show_category_ctx)

@paged('topics', pybb_settings.FORUM_PAGE_SIZE)
def show_forum_ctx(request, forum_id):
    forum = Forum.objects.get(pk=forum_id)
    topics = forum.topics.order_by('-sticky').select_related()
    quick = {'posts': forum.posts.count(),
             'topics': forum.topics.count(),
             'last_topics': forum.topics.all().select_related()[:pybb_settings.QUICK_TOPICS_NUMBER],
             'last_posts': forum.posts.order_by('-created').select_related()[:pybb_settings.QUICK_POSTS_NUMBER],
             }

    return {'forum': forum,
            'topics': topics,
            'quick': quick,
            'paged_qs': topics,
            }
show_forum = render_to('pybb/forum.html')(show_forum_ctx)

@paged('posts', pybb_settings.TOPIC_PAGE_SIZE)
def show_topic_ctx(request, topic_id):
    topic = Topic.objects.select_related().get(pk=topic_id)
    topic.views += 1
    topic.save()

    if request.user.is_authenticated():
        topic.update_read(request.user)

    posts = topic.posts.all().select_related()
    if pybb_settings.FREEZE_FIRST_POST:
        first_post = topic.posts.order_by('created')[0]
    else:
        first_post = None
    last_post = topic.posts.order_by('-created')[0]

    profiles = Profile.objects.filter(user__pk__in=set(x.user.id for x in posts))
    profiles = dict((x.user_id, x) for x in profiles)

    for post in posts:
        post.user.pybb_profile = profiles[post.user.id]

    initial = {}
    if request.user.is_authenticated():
        initial = {'markup': request.user.pybb_profile.markup}
    form = AddPostForm(topic=topic, initial=initial)

    moderator = request.user.is_superuser or\
        request.user in topic.forum.moderators.all()
    if request.user.is_authenticated() and request.user in topic.subscribers.all():
        subscribed = True
    else:
        subscribed = False

    return {'topic': topic,
            'last_post': last_post,
            'first_post': first_post,
            'form': form,
            'moderator': moderator,
            'subscribed': subscribed,
            'paged_qs': posts,
            }
show_topic = render_to('pybb/topic.html')(show_topic_ctx)

@login_required
def add_post_ctx(request, forum_id, topic_id):
    forum = None
    topic = None

    if forum_id:
        forum = get_object_or_404(Forum, pk=forum_id)
    elif topic_id:
        topic = get_object_or_404(Topic, pk=topic_id)

    if topic and topic.closed:
        return HttpResponseRedirect(topic.get_absolute_url())

    try:
        quote_id = int(request.GET.get('quote_id'))
    except TypeError:
        quote = ''
    else:
        post = get_object_or_404(Post, pk=quote_id)
        quote = quote_text(post.body_text, request.user.pybb_profile.markup)

    ip = request.META.get('REMOTE_ADDR', '')
    form = build_form(AddPostForm, request, topic=topic, forum=forum,
                      user=request.user, ip=ip,
                      initial={'markup': request.user.pybb_profile.markup, 'body': quote})

    if form.is_valid():
        post = form.save();
        return HttpResponseRedirect(post.get_absolute_url())

    return {'form': form,
            'topic': topic,
            'forum': forum,
            }
add_post = render_to('pybb/add_post.html')(add_post_ctx)

def user_ctx(request, username):
    user = get_object_or_404(User, username=username)
    topic_count = Topic.objects.filter(user=user).count()
    return {'profile': user,
            'topic_count': topic_count,
            }
user = render_to('pybb/user.html')(user_ctx)

def show_post(request, post_id):
    post = get_object_or_404(Post, pk=post_id)
    count = post.topic.posts.filter(created__lt=post.created).count() + 1
    page = math.ceil(count / float(pybb_settings.TOPIC_PAGE_SIZE))
    url = '%s?page=%d#post-%d' % (reverse('pybb_topic', args=[post.topic.id]), page, post.id)
    return HttpResponseRedirect(url)

@login_required
def edit_profile_ctx(request):
    form = build_form(EditProfileForm, request, instance=request.user.pybb_profile)
    if form.is_valid():
        form.save()
        return HttpResponseRedirect(reverse('pybb_edit_profile'))
    return {'form': form,
            'profile': request.user.pybb_profile,
            }
edit_profile = render_to('pybb/edit_profile.html')(edit_profile_ctx)

@login_required
def edit_post_ctx(request, post_id):
    from pybb.templatetags.pybb_extras import pybb_editable_by

    post = get_object_or_404(Post, pk=post_id)
    if not pybb_editable_by(post, request.user):
        return HttpResponseRedirect(post.get_absolute_url())

    form = build_form(EditPostForm, request, instance=post)

    if form.is_valid():
        post = form.save()
        return HttpResponseRedirect(post.get_absolute_url())

    return {'form': form,
            'post': post,
            }
edit_post = render_to('pybb/edit_post.html')(edit_post_ctx)

@login_required
def stick_topic(request, topic_id):
    from pybb.templatetags.pybb_extras import pybb_moderated_by

    topic = get_object_or_404(Topic, pk=topic_id)
    if pybb_moderated_by(topic, request.user):
        if not topic.sticky:
            topic.sticky = True
            topic.save()
    return HttpResponseRedirect(topic.get_absolute_url())

@login_required
def unstick_topic(request, topic_id):
    from pybb.templatetags.pybb_extras import pybb_moderated_by

    topic = get_object_or_404(Topic, pk=topic_id)
    if pybb_moderated_by(topic, request.user):
        if topic.sticky:
            topic.sticky = False
            topic.save()
    return HttpResponseRedirect(topic.get_absolute_url())

@login_required
def delete_post_ctx(request, post_id):
    post = get_object_or_404(Post, pk=post_id)
    last_post = post.topic.posts.order_by('-created')[0]
    topic = post.topic

    allowed = False
    if request.user.is_superuser or\
        request.user in post.topic.forum.moderators.all() or \
        (post.user == request.user and post == last_post):
        allowed = True

    if not allowed:
        return HttpResponseRedirect(post.get_absolute_url())

    if 'POST' == request.method:
        topic = post.topic
        forum = post.topic.forum
        post.delete()

        try:
            Topic.objects.get(pk=topic.id)
        except Topic.DoesNotExist:
            return HttpResponseRedirect(forum.get_absolute_url())
        else:
            return HttpResponseRedirect(topic.get_absolute_url())
    else:
        return {'post': post,
                }
delete_post = render_to('pybb/delete_post.html')(delete_post_ctx)

@login_required
def close_topic(request, topic_id):
    from pybb.templatetags.pybb_extras import pybb_moderated_by

    topic = get_object_or_404(Topic, pk=topic_id)
    if pybb_moderated_by(topic, request.user):
        if not topic.closed:
            topic.closed = True
            topic.save()
    return HttpResponseRedirect(topic.get_absolute_url())

@login_required
def open_topic(request, topic_id):
    from pybb.templatetags.pybb_extras import pybb_moderated_by

    topic = get_object_or_404(Topic, pk=topic_id)
    if pybb_moderated_by(topic, request.user):
        if topic.closed:
            topic.closed = False
            topic.save()
    return HttpResponseRedirect(topic.get_absolute_url())

@render_to('pybb/users.html')
@paged('users', pybb_settings.USERS_PAGE_SIZE)
def users_ctx(request):
    users = User.objects.order_by('username')
    form = UserSearchForm(request.GET)
    users = form.filter(users)
    return {'paged_qs': users,
            'form': form,
            }
users = paged('users', pybb_settings.USERS_PAGE_SIZE)(users_ctx)

@login_required
def delete_subscription(request, topic_id):
    topic = get_object_or_404(Topic, pk=topic_id)
    topic.subscribers.remove(request.user)
    if 'from_topic' in request.GET:
        return HttpResponseRedirect(reverse('pybb_topic', args=[topic.id]))
    else:
        return HttpResponseRedirect(reverse('pybb_edit_profile'))

@login_required
def add_subscription(request, topic_id):
    topic = get_object_or_404(Topic, pk=topic_id)
    topic.subscribers.add(request.user)
    return HttpResponseRedirect(reverse('pybb_topic', args=[topic.id]))

@login_required
def create_pm_ctx(request):
    recipient = request.GET.get('recipient', '')
    form = build_form(CreatePMForm, request, user=request.user,
                      initial={'markup': request.user.pybb_profile.markup,
                               'recipient': recipient})

    if form.is_valid():
        post = form.save();
        return HttpResponseRedirect(reverse('pybb_pm_outbox'))

    return {'form': form,
            'pm_mode': 'create',
            }
create_pm = render_to('pybb/pm/create_pm.html')(create_pm_ctx)

@login_required
def pm_outbox_ctx(request):
    messages = PrivateMessage.objects.filter(src_user=request.user)
    return {'messages': messages,
            'pm_mode': 'outbox',
            }
pm_outbox = render_to('pybb/pm/outbox.html')(pm_outbox_ctx)

@login_required
def pm_inbox_ctx(request):
    messages = PrivateMessage.objects.filter(dst_user=request.user)
    return {'messages': messages,
            'pm_mode': 'inbox',
            }
pm_inbox = render_to('pybb/pm/inbox.html')(pm_inbox_ctx)

@login_required
def show_pm_ctx(request, pm_id):
    msg = get_object_or_404(PrivateMessage, pk=pm_id)
    if not request.user in [msg.dst_user, msg.src_user]:
        return HttpRedirectException('/')
    if request.user == msg.dst_user:
        pm_mode = 'inbox'
        if not msg.read:
            msg.read = True
            msg.save()
        post_user = msg.src_user
    else:
        pm_mode = 'outbox'
        post_user = msg.dst_user
    return {'msg': msg,
            'pm_mode': pm_mode,
            'post_user': post_user,
            }
show_pm = render_to('pybb/pm/message.html')(show_pm_ctx)
<commit_msg>apply the #57 patch: correct topic ordering<commit_after>import math

from django.shortcuts import get_object_or_404
from django.http import HttpResponseRedirect
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required
from django.conf import settings
from django.core.urlresolvers import reverse
from django.db import connection

from pybb.util import render_to, paged, build_form, quote_text
from pybb.models import Category, Forum, Topic, Post, Profile, PrivateMessage
from pybb.forms import AddPostForm, EditProfileForm, EditPostForm, UserSearchForm, CreatePMForm
from pybb import settings as pybb_settings

def index_ctx(request):
    quick = {'posts': Post.objects.count(),
             'topics': Topic.objects.count(),
             'users': User.objects.count(),
             'last_topics': Topic.objects.all().select_related()[:pybb_settings.QUICK_TOPICS_NUMBER],
             'last_posts': Post.objects.order_by('-created').select_related()[:pybb_settings.QUICK_POSTS_NUMBER],
             }

    cats = {}
    forums = {}

    for forum in Forum.objects.all().select_related():
        cat = cats.setdefault(forum.category.id,
            {'cat': forum.category, 'forums': []})
        cat['forums'].append(forum)
        forums[forum.id] = forum

    cmpdef = lambda a, b: cmp(a['cat'].position, b['cat'].position)
    cats = sorted(cats.values(), cmpdef)

    return {'cats': cats,
            'quick': quick,
            }
index = render_to('pybb/index.html')(index_ctx)

def show_category_ctx(request, category_id):
    category = Category.objects.get(pk=category_id)
    quick = {'posts': category.posts.count(),
             'topics': category.topics.count(),
             'last_topics': category.topics.select_related()[:pybb_settings.QUICK_TOPICS_NUMBER],
             'last_posts': category.posts.order_by('-created').select_related()[:pybb_settings.QUICK_POSTS_NUMBER],
             }
    return {'category': category,
            'quick': quick,
            }
show_category = render_to('pybb/category.html')(show_category_ctx)

@paged('topics', pybb_settings.FORUM_PAGE_SIZE)
def show_forum_ctx(request, forum_id):
    forum = Forum.objects.get(pk=forum_id)
    topics = forum.topics.order_by('-sticky', '-updated').select_related()
    quick = {'posts': forum.post_count,
             'topics': forum.topics.count(),
             'last_topics': forum.topics.all().select_related()[:pybb_settings.QUICK_TOPICS_NUMBER],
             'last_posts': forum.posts.order_by('-created').select_related()[:pybb_settings.QUICK_POSTS_NUMBER],
             }

    return {'forum': forum,
            'topics': topics,
            'quick': quick,
            'paged_qs': topics,
            }
show_forum = render_to('pybb/forum.html')(show_forum_ctx)

@paged('posts', pybb_settings.TOPIC_PAGE_SIZE)
def show_topic_ctx(request, topic_id):
    topic = Topic.objects.select_related().get(pk=topic_id)
    topic.views += 1
    topic.save()

    if request.user.is_authenticated():
        topic.update_read(request.user)

    posts = topic.posts.all().select_related()
    if pybb_settings.FREEZE_FIRST_POST:
        first_post = topic.posts.order_by('created')[0]
    else:
        first_post = None
    last_post = topic.posts.order_by('-created')[0]

    profiles = Profile.objects.filter(user__pk__in=set(x.user.id for x in posts))
    profiles = dict((x.user_id, x) for x in profiles)

    for post in posts:
        post.user.pybb_profile = profiles[post.user.id]

    initial = {}
    if request.user.is_authenticated():
        initial = {'markup': request.user.pybb_profile.markup}
    form = AddPostForm(topic=topic, initial=initial)

    moderator = request.user.is_superuser or\
        request.user in topic.forum.moderators.all()
    if request.user.is_authenticated() and request.user in topic.subscribers.all():
        subscribed = True
    else:
        subscribed = False

    return {'topic': topic,
            'last_post': last_post,
            'first_post': first_post,
            'form': form,
            'moderator': moderator,
            'subscribed': subscribed,
            'paged_qs': posts,
            }
show_topic = render_to('pybb/topic.html')(show_topic_ctx)

@login_required
def add_post_ctx(request, forum_id, topic_id):
    forum = None
    topic = None

    if forum_id:
        forum = get_object_or_404(Forum, pk=forum_id)
    elif topic_id:
        topic = get_object_or_404(Topic, pk=topic_id)

    if topic and topic.closed:
        return HttpResponseRedirect(topic.get_absolute_url())

    try:
        quote_id = int(request.GET.get('quote_id'))
    except TypeError:
        quote = ''
    else:
        post = get_object_or_404(Post, pk=quote_id)
        quote = quote_text(post.body_text, request.user.pybb_profile.markup)

    ip = request.META.get('REMOTE_ADDR', '')
    form = build_form(AddPostForm, request, topic=topic, forum=forum,
                      user=request.user, ip=ip,
                      initial={'markup': request.user.pybb_profile.markup, 'body': quote})

    if form.is_valid():
        post = form.save();
        return HttpResponseRedirect(post.get_absolute_url())

    return {'form': form,
            'topic': topic,
            'forum': forum,
            }
add_post = render_to('pybb/add_post.html')(add_post_ctx)

def user_ctx(request, username):
    user = get_object_or_404(User, username=username)
    topic_count = Topic.objects.filter(user=user).count()
    return {'profile': user,
            'topic_count': topic_count,
            }
user = render_to('pybb/user.html')(user_ctx)

def show_post(request, post_id):
    post = get_object_or_404(Post, pk=post_id)
    count = post.topic.posts.filter(created__lt=post.created).count() + 1
    page = math.ceil(count / float(pybb_settings.TOPIC_PAGE_SIZE))
    url = '%s?page=%d#post-%d' % (reverse('pybb_topic', args=[post.topic.id]), page, post.id)
    return HttpResponseRedirect(url)

@login_required
def edit_profile_ctx(request):
    form = build_form(EditProfileForm, request, instance=request.user.pybb_profile)
    if form.is_valid():
        form.save()
        return HttpResponseRedirect(reverse('pybb_edit_profile'))
    return {'form': form,
            'profile': request.user.pybb_profile,
            }
edit_profile = render_to('pybb/edit_profile.html')(edit_profile_ctx)

@login_required
def edit_post_ctx(request, post_id):
    from pybb.templatetags.pybb_extras import pybb_editable_by

    post = get_object_or_404(Post, pk=post_id)
    if not pybb_editable_by(post, request.user):
        return HttpResponseRedirect(post.get_absolute_url())

    form = build_form(EditPostForm, request, instance=post)

    if form.is_valid():
        post = form.save()
        return HttpResponseRedirect(post.get_absolute_url())

    return {'form': form,
            'post': post,
            }
edit_post = render_to('pybb/edit_post.html')(edit_post_ctx)

@login_required
def stick_topic(request, topic_id):
    from pybb.templatetags.pybb_extras import pybb_moderated_by

    topic = get_object_or_404(Topic, pk=topic_id)
    if pybb_moderated_by(topic, request.user):
        if not topic.sticky:
            topic.sticky = True
            topic.save()
    return HttpResponseRedirect(topic.get_absolute_url())

@login_required
def unstick_topic(request, topic_id):
    from pybb.templatetags.pybb_extras import pybb_moderated_by

    topic = get_object_or_404(Topic, pk=topic_id)
    if pybb_moderated_by(topic, request.user):
        if topic.sticky:
            topic.sticky = False
            topic.save()
    return HttpResponseRedirect(topic.get_absolute_url())

@login_required
def delete_post_ctx(request, post_id):
    post = get_object_or_404(Post, pk=post_id)
    last_post = post.topic.posts.order_by('-created')[0]
    topic = post.topic

    allowed = False
    if request.user.is_superuser or\
        request.user in post.topic.forum.moderators.all() or \
        (post.user == request.user and post == last_post):
        allowed = True

    if not allowed:
        return HttpResponseRedirect(post.get_absolute_url())

    if 'POST' == request.method:
        topic = post.topic
        forum = post.topic.forum
        post.delete()

        try:
            Topic.objects.get(pk=topic.id)
        except Topic.DoesNotExist:
            return HttpResponseRedirect(forum.get_absolute_url())
        else:
            return HttpResponseRedirect(topic.get_absolute_url())
    else:
        return {'post': post,
                }
delete_post = render_to('pybb/delete_post.html')(delete_post_ctx)

@login_required
def close_topic(request, topic_id):
    from pybb.templatetags.pybb_extras import pybb_moderated_by

    topic = get_object_or_404(Topic, pk=topic_id)
    if pybb_moderated_by(topic, request.user):
        if not topic.closed:
            topic.closed = True
            topic.save()
    return HttpResponseRedirect(topic.get_absolute_url())

@login_required
def open_topic(request, topic_id):
    from pybb.templatetags.pybb_extras import pybb_moderated_by

    topic = get_object_or_404(Topic, pk=topic_id)
    if pybb_moderated_by(topic, request.user):
        if topic.closed:
            topic.closed = False
            topic.save()
    return HttpResponseRedirect(topic.get_absolute_url())

@render_to('pybb/users.html')
@paged('users', pybb_settings.USERS_PAGE_SIZE)
def users_ctx(request):
    users = User.objects.order_by('username')
    form = UserSearchForm(request.GET)
    users = form.filter(users)
    return {'paged_qs': users,
            'form': form,
            }
users = paged('users', pybb_settings.USERS_PAGE_SIZE)(users_ctx)

@login_required
def delete_subscription(request, topic_id):
    topic = get_object_or_404(Topic, pk=topic_id)
    topic.subscribers.remove(request.user)
    if 'from_topic' in request.GET:
        return HttpResponseRedirect(reverse('pybb_topic', args=[topic.id]))
    else:
        return HttpResponseRedirect(reverse('pybb_edit_profile'))

@login_required
def add_subscription(request, topic_id):
    topic = get_object_or_404(Topic, pk=topic_id)
    topic.subscribers.add(request.user)
    return HttpResponseRedirect(reverse('pybb_topic', args=[topic.id]))

@login_required
def create_pm_ctx(request):
    recipient = request.GET.get('recipient', '')
    form = build_form(CreatePMForm, request, user=request.user,
                      initial={'markup': request.user.pybb_profile.markup,
                               'recipient': recipient})

    if form.is_valid():
        post = form.save();
        return HttpResponseRedirect(reverse('pybb_pm_outbox'))

    return {'form': form,
            'pm_mode': 'create',
            }
create_pm = render_to('pybb/pm/create_pm.html')(create_pm_ctx)

@login_required
def pm_outbox_ctx(request):
    messages = PrivateMessage.objects.filter(src_user=request.user)
    return {'messages': messages,
            'pm_mode': 'outbox',
            }
pm_outbox = render_to('pybb/pm/outbox.html')(pm_outbox_ctx)

@login_required
def pm_inbox_ctx(request):
    messages = PrivateMessage.objects.filter(dst_user=request.user)
    return {'messages': messages,
            'pm_mode': 'inbox',
            }
pm_inbox = render_to('pybb/pm/inbox.html')(pm_inbox_ctx)

@login_required
def show_pm_ctx(request, pm_id):
    msg = get_object_or_404(PrivateMessage, pk=pm_id)
    if not request.user in [msg.dst_user, msg.src_user]:
        return HttpRedirectException('/')
    if request.user == msg.dst_user:
        pm_mode = 'inbox'
        if not msg.read:
            msg.read = True
            msg.save()
        post_user = msg.src_user
    else:
        pm_mode = 'outbox'
        post_user = msg.dst_user
    return {'msg': msg,
            'pm_mode': pm_mode,
            'post_user': post_user,
            }
show_pm = render_to('pybb/pm/message.html')(show_pm_ctx)
<|endoftext|>


<commit_before>import praw
import codecs
import unidecode
import os
import requests
import datetime
import regex as re
from collections import Counter

requests.packages.urllib3.disable_warnings()
subreddits = ["earthporn", "japanpics"]

class redditLogger:
    def __init__(self, logfile):
        self.logfile = logfile

    def logEntry(self, entry, level):
        with codecs.open(self.logfile, mode='a', encoding='utf-8') as log:
            log.write(entry + '\n')
        if 'progress' in level:
            print unidecode.unidecode(entry)

class reddit:
    def __init__(self, logobj):
        self.logger = logobj
        self.ua = "Python:ReddWall:v0.1 (by /u/verstandinvictus)"
        self.r = praw.Reddit(user_agent=self.ua)
        self.dest = os.path.join(os.getcwdu(), 'images')
        if not os.path.exists(self.dest):
            os.makedirs(self.dest)
        self.results = None
        self.resetResults()

    def resetResults(self):
        self.results = dict(
            count=0,
            skipped=0,
            failed=0,
            succeeded=0,
            nonexistent=0,
        )

    def getTopLinks(self, sub):
        atop = self.r.get_subreddit(sub).get_top_from_all(limit=None)
        submissions = set()
        for s in (atop,):
            for link in s:
                submissions.add(link)
        titles = list()
        for each in submissions:
            t = self.generateName(each)
            titles.append(re.split(' ', t))
        #self.upGoerFive(titles)

    def generateName(self, sub):
        rawtitle = unidecode.unidecode(sub.title.lower())
        spacesubs = ['\n', ur'\p{P}+']
        blanksubs = ['[\[\(].*[\)\]]', '/r/.*', '[0-9]']
        subdict = {
            "mt": "mount",
            "st helens": "saint_helens"
        }
        for pattern in spacesubs:
            rawtitle = re.sub(pattern, ' ', rawtitle)
        for pattern in blanksubs:
            rawtitle = re.sub(pattern, '', rawtitle)
        rawtitle = ' '.join(rawtitle.split())
        for pattern in subdict.iterkeys():
            rawtitle = re.sub(pattern, subdict[pattern], rawtitle)
        eatshorts = [x for x in re.split(' ', rawtitle) if len(x) > 1]
        try:
            ind = eatshorts.index('mount')
            print eatshorts[ind], eatshorts[ind+1], eatshorts[ind+2]
            #print rawtitle
        except:
            pass
        return rawtitle

    def upGoerFive(self, titles):
        c = Counter()
        for t in titles:
                c.update(t)
        for word, count in c.most_common(50):
            print "{0} :: {1}".format(count, word)

    def downloadImage(self, imgurl, imgname, dest=None):
        if not dest:
            rdest = self.dest
        else:
            rdest = dest
        try:
            imgwrite = os.path.join(rdest, imgname)
            if not os.path.exists(imgwrite):
                r = requests.get(imgurl)
                with open(imgwrite, "wb") as code:
                    code.write(r.content)
                self.logger.logEntry(('downloaded ' + imgname), 'progress')
                self.results['succeeded'] += 1
                return True
            else:
                self.logger.logEntry(('already have ' + imgname),
                                     'verbose')
                self.results['skipped'] += 1
                return True
        except:
            self.logger.logEntry('failed to get: {0} from {1}'.format(
                imgurl, imgname), 'verbose')
            self.results['failed'] += 1
            return None

if __name__ == "__main__":
    dt = datetime.date.today().strftime('%m-%d-%y')
    logfile = os.path.join('logs', str('reddwall ' + dt + '.log'))
    logger = redditLogger(logfile)
    site = reddit(logger)
    logfile = os.path.join('logs', )
    for target in subreddits:
        site.getTopLinks(target)
<commit_msg>this is a dead end<commit_after>import praw
import codecs
import unidecode
import os
import requests
import datetime
import regex as re
from collections import Counter

try:
    requests.packages.urllib3.disable_warnings()
except:
    pass
subreddits = ["earthporn", "japanpics"]

class redditLogger:
    def __init__(self, logfile):
        self.logfile = logfile

    def logEntry(self, entry, level):
        with codecs.open(self.logfile, mode='a', encoding='utf-8') as log:
            log.write(entry + '\n')
        if 'progress' in level:
            print unidecode.unidecode(entry)

class reddit:
    def __init__(self, logobj):
        self.logger = logobj
        self.ua = "Python:ReddWall:v0.1 (by /u/verstandinvictus)"
        self.r = praw.Reddit(user_agent=self.ua)
        self.dest = os.path.join(os.getcwdu(), 'images')
        if not os.path.exists(self.dest):
            os.makedirs(self.dest)
        self.results = None
        self.resetResults()

    def resetResults(self):
        self.results = dict(
            count=0,
            skipped=0,
            failed=0,
            succeeded=0,
            nonexistent=0,
        )

    def getTopLinks(self, sub):
        atop = self.r.get_subreddit(sub).get_top_from_all(limit=None)
        submissions = set()
        for s in (atop,):
            for link in s:
                submissions.add(link)
        titles = list()
        for each in submissions:
            t = self.generateName(each)
            for tag in t:
                titles.append(t)
        #self.upGoerFive(titles)

    def mergeNames(self, wordlist, swaps, direction):
        for s in swaps:
            indices = [i for i, x in enumerate(wordlist) if x == s]
            for ind in indices:
                if direction == "next":
                    ind2 = ind + 1
                else:
                    ind2 = ind
                    ind -= 1
                insert = "_".join((wordlist[ind], wordlist[ind2]))
                wordlist.pop(ind)
                wordlist.pop(ind2)
                wordlist.append(insert)
                print "====="
        return wordlist

    def generateName(self, sub):
        rawtitle = unidecode.unidecode(sub.title.lower())
        spacesubs = ['\n', ur'\p{P}+']
        blanksubs = ['[\[\(].*[\)\]]', '/r/.*', '[0-9]']
        abbrevdict = {
            " mt ": " mount ",
            " st ": " saint ",
        }
        subdict = {
            "saint helens": "saint_helens"
        }
        forelabels = ["mount", "lake", "north", "south", "west", "east"]
        afterlabels = ['river', 'ridge']
        for pattern in spacesubs:
            rawtitle = re.sub(pattern, ' ', rawtitle)
        for pattern in blanksubs:
            rawtitle = re.sub(pattern, '', rawtitle)
        rawtitle = ' '.join(rawtitle.split())
        for pattern in abbrevdict.iterkeys():
            rawtitle = re.sub(pattern, abbrevdict[pattern], rawtitle)
        for pattern in subdict.iterkeys():
            rawtitle = re.sub(pattern, subdict[pattern], rawtitle)
        eatshorts = [x for x in re.split(' ', rawtitle) if len(x) > 3]
        self.mergeNames(eatshorts, forelabels, "next")
        self.mergeNames(eatshorts, afterlabels, "prev")
        print eatshorts
        print rawtitle
        return eatshorts

    def upGoerFive(self, titles):
        c = Counter()
        for t in titles:
                c.update(t)
        for word, count in c.most_common(50):
            print "{0} :: {1}".format(count, word)

    def downloadImage(self, imgurl, imgname, dest=None):
        if not dest:
            rdest = self.dest
        else:
            rdest = dest
        try:
            imgwrite = os.path.join(rdest, imgname)
            if not os.path.exists(imgwrite):
                r = requests.get(imgurl)
                with open(imgwrite, "wb") as code:
                    code.write(r.content)
                self.logger.logEntry(('downloaded ' + imgname), 'progress')
                self.results['succeeded'] += 1
                return True
            else:
                self.logger.logEntry(('already have ' + imgname),
                                     'verbose')
                self.results['skipped'] += 1
                return True
        except:
            self.logger.logEntry('failed to get: {0} from {1}'.format(
                imgurl, imgname), 'verbose')
            self.results['failed'] += 1
            return None

if __name__ == "__main__":
    dt = datetime.date.today().strftime('%m-%d-%y')
    logfile = os.path.join('logs', str('reddwall ' + dt + '.log'))
    logger = redditLogger(logfile)
    site = reddit(logger)
    logfile = os.path.join('logs', )
    for target in subreddits:
        site.getTopLinks(target)
<|endoftext|>


<commit_before># -*- coding: iso-8859-15 -*-
# =================================================================
#
# Authors: Tom Kralidis <tomkralidis@hotmail.com>
#
# Copyright (c) 2010 Tom Kralidis
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation
# files (the "Software"), to deal in the Software without
# restriction, including without limitation the rights to use,
# copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following
# conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
#
# =================================================================

import time
import datetime
import logging
import urllib2
from lxml import etree
from shapely.wkt import loads
from owslib.util import http_post

LOGGER = logging.getLogger(__name__)

def get_today_and_now():
    """Get the date, right now, in ISO8601"""
    return time.strftime('%Y-%m-%dT%H:%M:%SZ', time.localtime())

def datetime2iso8601(value):
    """Return a datetime value as ISO8601"""
    if value is None:
        return None
    if isinstance(value, datetime.date):
        return value.strftime('%Y-%m-%d')
    if value.hour == 0 and value.minute == 0 and value.second == 0:
        # YYYY-MM-DD only
        return value.strftime('%Y-%m-%d')
    else:
        return value.strftime('%Y-%m-%dT%H:%M:%SZ')

def get_time_iso2unix(isotime):
    """Convert ISO8601 to UNIX timestamp"""
    return int(time.mktime(time.strptime(
        isotime, '%Y-%m-%dT%H:%M:%SZ'))) - time.timezone

def get_version_integer(version):
    """Get an integer of the OGC version value x.y.z"""
    if version is not None:  # split and make integer
        xyz = version.split('.')
        if len(xyz) != 3:
            return -1
        try:
            return int(xyz[0]) * 10000 + int(xyz[1]) * 100 + int(xyz[2])
        except Exception, err:
            raise RuntimeError('%s' % str(err))
    else:  # not a valid version string
        return -1

def find_exml(val, attrib=False):
    """Test that the XML value exists, return value, else return None"""
    if val is not None:
        if attrib:  # it's an XML attribute
            return val
        else:  # it's an XML value
            return val.text
    else:
        return None

def nspath_eval(xpath, nsmap):
    """Return an etree friendly xpath"""
    out = []
    for chunks in xpath.split('/'):
        namespace, element = chunks.split(':')
        out.append('{%s}%s' % (nsmap[namespace], element))
    return '/'.join(out)

def xmltag_split(tag):
    """Return XML element bare tag name (without prefix)"""
    try:
        return tag.split('}')[1]
    except:
        return tag

def xmltag_split2(tag, namespaces, colon=False):
    """Return XML namespace prefix of element"""
    try:
        nsuri = tag.split('}')[0].split('{')[1]
        nsprefix = [key for key, value in namespaces.iteritems()
                    if value == nsuri]
        value = nsprefix[0]
        if colon:
            return '%s:' % nsprefix[0]
        else:
            return nsprefix[0]
    except:
        return ''

def bbox2wktpolygon(bbox):
    """Return OGC WKT Polygon of a simple bbox string"""
    tmp = bbox.split(',')
    minx = float(tmp[0])
    miny = float(tmp[1])
    maxx = float(tmp[2])
    maxy = float(tmp[3])
    return 'POLYGON((%.2f %.2f, %.2f %.2f, %.2f %.2f, %.2f %.2f, %.2f %.2f))' \
        % (minx, miny, minx, maxy, maxx, maxy, maxx, miny, minx, miny)

def query_spatial(bbox_data_wkt, bbox_input_wkt, predicate, distance):
    """perform spatial query"""

    if bbox_data_wkt is None or bbox_input_wkt is None:
        return 'false'

    if predicate in ['beyond', 'dwithin'] and distance == 'false':
        return 'false'

    if bbox_data_wkt.find('SRID') != -1:  # it's EWKT; chop off 'SRID=\d+;'
        bbox1 = loads(bbox_data_wkt.split(';')[-1])
    else:
        bbox1 = loads(bbox_data_wkt)

    bbox2 = loads(bbox_input_wkt)

    # map query to Shapely Binary Predicates:
    if predicate == 'bbox':
        result = bbox1.intersects(bbox2)
    elif predicate == 'beyond':
        result = bbox1.distance(bbox2) > float(distance)
    elif predicate == 'contains':
        result = bbox1.contains(bbox2)
    elif predicate == 'crosses':
        result = bbox1.crosses(bbox2)
    elif predicate == 'disjoint':
        result = bbox1.disjoint(bbox2)
    elif predicate == 'dwithin':
        result = bbox1.distance(bbox2) <= float(distance)
    elif predicate == 'equals':
        result = bbox1.equals(bbox2)
    elif predicate == 'intersects':
        result = bbox1.intersects(bbox2)
    elif predicate == 'overlaps':
        if bbox1.intersects(bbox2) and not bbox1.touches(bbox2):
            result = True
        else:
            result = False
    elif predicate == 'touches':
        result = bbox1.touches(bbox2)
    elif predicate == 'within':
        result = bbox1.within(bbox2)
    else:
        raise RuntimeError('Invalid spatial query predicate: %s' % predicate)

    if result:
        return 'true'
    else:
        return 'false'

def get_geometry_area(geometry):
    """Derive area of a given geometry"""
    try:
        if geometry is not None:
            return str(loads(geometry).area)
        return '0'
    except:
        return '0'

def bbox_from_polygons(bboxs):
    """Derive an aggregated bbox from n polygons"""

    from shapely.geometry import MultiPolygon

    polys = []
    for bbx in bboxs:
        polys.append(loads(bbx))

    try:
        bbx = MultiPolygon(polys).bounds
        bstr = '%.2f,%.2f,%.2f,%.2f' % (bbx[0], bbx[1], bbx[2], bbx[3])
        return bbox2wktpolygon(bstr)
    except Exception, err:
        raise RuntimeError('Cannot aggregate polygons: %s' % str(err))

def update_xpath(nsmap, xml, recprop):
    """Update XML document XPath values"""

    if isinstance(xml, unicode):  # not lxml serialized yet
        xml = etree.fromstring(xml)

    recprop = eval(recprop)
    nsmap = eval(nsmap)
    try:
        nodes = xml.xpath(recprop['rp']['xpath'], namespaces=nsmap)
        if len(nodes) > 0:  # matches
            for node1 in nodes:
                if node1.text != recprop['value']:  # values differ, update
                    node1.text = recprop['value']
    except Exception, err:
        raise RuntimeError('ERROR: %s' % str(err))

    return etree.tostring(xml)

def transform_mappings(queryables, typename, reverse=False):
    """transform metadata model mappings"""
    if reverse:  # from csw:Record
        for qbl in queryables.keys():
            if qbl in typename.values():
                tmp = [k for k, v in typename.iteritems() if v == qbl][0]
                val = queryables[tmp]
                queryables[qbl] = {}
                queryables[qbl]['xpath'] = val['xpath']
                queryables[qbl]['dbcol'] = val['dbcol']
    else:  # to csw:Record
        for qbl in queryables.keys():
            if qbl in typename.keys():
                queryables[qbl] = queryables[qbl]

def get_anytext(xml):
    """get all element and attribute data from an XML document"""

    if isinstance(xml, unicode) or isinstance(xml, str):  # not serialized yet
        xml = etree.fromstring(xml)
    return '%s %s' % (' '.join([value for value in xml.xpath('//text()')]),
           ' '.join([value for value in xml.xpath('//attribute::*')]))

def exml2dict(element, namespaces):
    """Convert an lxml object to JSON
        From:
        http://bitbucket.org/smulloni/pesterfish/src/1578db946d74/pesterfish.py
    """

    jdict = dict(tag='%s%s' % (xmltag_split2(element.tag, namespaces, True),
                               xmltag_split(element.tag)))
    if element.text:
        if element.text.find('\n') == -1:
            jdict['text'] = element.text
    if element.attrib:
        jdict['attributes'] = dict(('%s%s' % (xmltag_split2(k, namespaces, True),
                                   xmltag_split(k)), f(v) if hasattr(v, 'keys') else v)
                                   for k, v in element.attrib.items())
    children = element.getchildren()
    if children:
        jdict['children'] = map(lambda x: exml2dict(x, namespaces), children)
    return jdict

def getqattr(obj, name):
    """get value of an object, safely"""
    try:
        value = getattr(obj, name)
        if hasattr(value, '__call__'):  # function generated value
            LOGGER.debug('attribute is a function')
            if name.find('link') != -1:  # list of link tuple quadruplets
                LOGGER.debug('attribute is a link')
                return _linkify(value())
            return value()
        elif (isinstance(value, datetime.datetime)
              or isinstance(value, datetime.date)):  # datetime object
            LOGGER.debug('attribute is a date')
            return datetime2iso8601(value)
        return value
    except:
        return None

def _linkify(value):
    """create link format"""
    out = []
    for link in value:
        out.append(','.join(list(link)))
    return '^'.join(out)

def http_request(method, url, request=None, timeout=10):
    """Perform HTTP request"""
    if method == 'POST':
        return http_post(url, request, timeout)
    else:  # GET
        request = urllib2.Request(url)
        request.add_header('User-Agent', 'pycsw (http://pycsw.org/)')
        return urllib2.urlopen(request, timeout=timeout).read()

def bind_url(url):
    """binds an HTTP GET query string endpiont"""
    if url.find('?') == -1: # like http://host/wms
        binder = '?'

    # if like http://host/wms?foo=bar& or http://host/wms?foo=bar
    if url.find('=') != -1:
        if url.find('&', -1) != -1: # like http://host/wms?foo=bar&
            binder = ''
        else: # like http://host/wms?foo=bar
            binder = '&'

    # if like http://host/wms?foo
    if url.find('?') != -1:
        if url.find('?', -1) != -1: # like http://host/wms?
            binder = ''
        elif url.find('&', -1) == -1: # like http://host/wms?foo=bar
            binder = '&'
    return '%s%s' % (url, binder)

def ip_in_network_cidr(ip, net):
    """decipher whether IP is within CIDR range"""
    ipaddr = int(''.join([ '%02x' % int(x) for x in ip.split('.') ]), 16)
    netstr, bits = net.split('/')
    netaddr = int(''.join([ '%02x' % int(x) for x in netstr.split('.') ]), 16)
    mask = (0xffffffff << (32 - int(bits))) & 0xffffffff
    return (ipaddr & mask) == (netaddr & mask)

def ipaddress_in_whitelist(ipaddress, whitelist):
    """
    decipher whether IP is in IP whitelist
    IP whitelist is a list supporting:
    - single IP address (e.g. 192.168.0.1)
    - IP range using CIDR (e.g. 192.168.0/22)
    - IP range using subnet wildcard (e.g. 192.168.0.*, 192.168.*)
    """

    if ipaddress in whitelist:
        return True
    else:
        for white in whitelist:
            if white.find('/') != -1:  # CIDR
                if ip_in_network_cidr(ipaddress, white):
                    return True
            elif white.find('*') != -1:  # subnet wildcard
                    if ipaddress.startswith(white.split('*')[0]):
                        return True
    return False
<commit_msg>remove XML attribute inclusion when generating anytext field (#132)<commit_after># -*- coding: iso-8859-15 -*-
# =================================================================
#
# Authors: Tom Kralidis <tomkralidis@hotmail.com>
#
# Copyright (c) 2010 Tom Kralidis
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation
# files (the "Software"), to deal in the Software without
# restriction, including without limitation the rights to use,
# copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following
# conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
#
# =================================================================

import time
import datetime
import logging
import urllib2
from lxml import etree
from shapely.wkt import loads
from owslib.util import http_post

LOGGER = logging.getLogger(__name__)

def get_today_and_now():
    """Get the date, right now, in ISO8601"""
    return time.strftime('%Y-%m-%dT%H:%M:%SZ', time.localtime())

def datetime2iso8601(value):
    """Return a datetime value as ISO8601"""
    if value is None:
        return None
    if isinstance(value, datetime.date):
        return value.strftime('%Y-%m-%d')
    if value.hour == 0 and value.minute == 0 and value.second == 0:
        # YYYY-MM-DD only
        return value.strftime('%Y-%m-%d')
    else:
        return value.strftime('%Y-%m-%dT%H:%M:%SZ')

def get_time_iso2unix(isotime):
    """Convert ISO8601 to UNIX timestamp"""
    return int(time.mktime(time.strptime(
        isotime, '%Y-%m-%dT%H:%M:%SZ'))) - time.timezone

def get_version_integer(version):
    """Get an integer of the OGC version value x.y.z"""
    if version is not None:  # split and make integer
        xyz = version.split('.')
        if len(xyz) != 3:
            return -1
        try:
            return int(xyz[0]) * 10000 + int(xyz[1]) * 100 + int(xyz[2])
        except Exception, err:
            raise RuntimeError('%s' % str(err))
    else:  # not a valid version string
        return -1

def find_exml(val, attrib=False):
    """Test that the XML value exists, return value, else return None"""
    if val is not None:
        if attrib:  # it's an XML attribute
            return val
        else:  # it's an XML value
            return val.text
    else:
        return None

def nspath_eval(xpath, nsmap):
    """Return an etree friendly xpath"""
    out = []
    for chunks in xpath.split('/'):
        namespace, element = chunks.split(':')
        out.append('{%s}%s' % (nsmap[namespace], element))
    return '/'.join(out)

def xmltag_split(tag):
    """Return XML element bare tag name (without prefix)"""
    try:
        return tag.split('}')[1]
    except:
        return tag

def xmltag_split2(tag, namespaces, colon=False):
    """Return XML namespace prefix of element"""
    try:
        nsuri = tag.split('}')[0].split('{')[1]
        nsprefix = [key for key, value in namespaces.iteritems()
                    if value == nsuri]
        value = nsprefix[0]
        if colon:
            return '%s:' % nsprefix[0]
        else:
            return nsprefix[0]
    except:
        return ''

def bbox2wktpolygon(bbox):
    """Return OGC WKT Polygon of a simple bbox string"""
    tmp = bbox.split(',')
    minx = float(tmp[0])
    miny = float(tmp[1])
    maxx = float(tmp[2])
    maxy = float(tmp[3])
    return 'POLYGON((%.2f %.2f, %.2f %.2f, %.2f %.2f, %.2f %.2f, %.2f %.2f))' \
        % (minx, miny, minx, maxy, maxx, maxy, maxx, miny, minx, miny)

def query_spatial(bbox_data_wkt, bbox_input_wkt, predicate, distance):
    """perform spatial query"""

    if bbox_data_wkt is None or bbox_input_wkt is None:
        return 'false'

    if predicate in ['beyond', 'dwithin'] and distance == 'false':
        return 'false'

    if bbox_data_wkt.find('SRID') != -1:  # it's EWKT; chop off 'SRID=\d+;'
        bbox1 = loads(bbox_data_wkt.split(';')[-1])
    else:
        bbox1 = loads(bbox_data_wkt)

    bbox2 = loads(bbox_input_wkt)

    # map query to Shapely Binary Predicates:
    if predicate == 'bbox':
        result = bbox1.intersects(bbox2)
    elif predicate == 'beyond':
        result = bbox1.distance(bbox2) > float(distance)
    elif predicate == 'contains':
        result = bbox1.contains(bbox2)
    elif predicate == 'crosses':
        result = bbox1.crosses(bbox2)
    elif predicate == 'disjoint':
        result = bbox1.disjoint(bbox2)
    elif predicate == 'dwithin':
        result = bbox1.distance(bbox2) <= float(distance)
    elif predicate == 'equals':
        result = bbox1.equals(bbox2)
    elif predicate == 'intersects':
        result = bbox1.intersects(bbox2)
    elif predicate == 'overlaps':
        if bbox1.intersects(bbox2) and not bbox1.touches(bbox2):
            result = True
        else:
            result = False
    elif predicate == 'touches':
        result = bbox1.touches(bbox2)
    elif predicate == 'within':
        result = bbox1.within(bbox2)
    else:
        raise RuntimeError('Invalid spatial query predicate: %s' % predicate)

    if result:
        return 'true'
    else:
        return 'false'

def get_geometry_area(geometry):
    """Derive area of a given geometry"""
    try:
        if geometry is not None:
            return str(loads(geometry).area)
        return '0'
    except:
        return '0'

def bbox_from_polygons(bboxs):
    """Derive an aggregated bbox from n polygons"""

    from shapely.geometry import MultiPolygon

    polys = []
    for bbx in bboxs:
        polys.append(loads(bbx))

    try:
        bbx = MultiPolygon(polys).bounds
        bstr = '%.2f,%.2f,%.2f,%.2f' % (bbx[0], bbx[1], bbx[2], bbx[3])
        return bbox2wktpolygon(bstr)
    except Exception, err:
        raise RuntimeError('Cannot aggregate polygons: %s' % str(err))

def update_xpath(nsmap, xml, recprop):
    """Update XML document XPath values"""

    if isinstance(xml, unicode):  # not lxml serialized yet
        xml = etree.fromstring(xml)

    recprop = eval(recprop)
    nsmap = eval(nsmap)
    try:
        nodes = xml.xpath(recprop['rp']['xpath'], namespaces=nsmap)
        if len(nodes) > 0:  # matches
            for node1 in nodes:
                if node1.text != recprop['value']:  # values differ, update
                    node1.text = recprop['value']
    except Exception, err:
        raise RuntimeError('ERROR: %s' % str(err))

    return etree.tostring(xml)

def transform_mappings(queryables, typename, reverse=False):
    """transform metadata model mappings"""
    if reverse:  # from csw:Record
        for qbl in queryables.keys():
            if qbl in typename.values():
                tmp = [k for k, v in typename.iteritems() if v == qbl][0]
                val = queryables[tmp]
                queryables[qbl] = {}
                queryables[qbl]['xpath'] = val['xpath']
                queryables[qbl]['dbcol'] = val['dbcol']
    else:  # to csw:Record
        for qbl in queryables.keys():
            if qbl in typename.keys():
                queryables[qbl] = queryables[qbl]

def get_anytext(xml):
    """get all element and attribute data from an XML document"""

    if isinstance(xml, unicode) or isinstance(xml, str):  # not serialized yet
        xml = etree.fromstring(xml)
    return ' '.join([value for value in xml.xpath('//text()')])

def exml2dict(element, namespaces):
    """Convert an lxml object to JSON
        From:
        http://bitbucket.org/smulloni/pesterfish/src/1578db946d74/pesterfish.py
    """

    jdict = dict(tag='%s%s' % (xmltag_split2(element.tag, namespaces, True),
                               xmltag_split(element.tag)))
    if element.text:
        if element.text.find('\n') == -1:
            jdict['text'] = element.text
    if element.attrib:
        jdict['attributes'] = dict(('%s%s' % (xmltag_split2(k, namespaces, True),
                                   xmltag_split(k)), f(v) if hasattr(v, 'keys') else v)
                                   for k, v in element.attrib.items())
    children = element.getchildren()
    if children:
        jdict['children'] = map(lambda x: exml2dict(x, namespaces), children)
    return jdict

def getqattr(obj, name):
    """get value of an object, safely"""
    try:
        value = getattr(obj, name)
        if hasattr(value, '__call__'):  # function generated value
            LOGGER.debug('attribute is a function')
            if name.find('link') != -1:  # list of link tuple quadruplets
                LOGGER.debug('attribute is a link')
                return _linkify(value())
            return value()
        elif (isinstance(value, datetime.datetime)
              or isinstance(value, datetime.date)):  # datetime object
            LOGGER.debug('attribute is a date')
            return datetime2iso8601(value)
        return value
    except:
        return None

def _linkify(value):
    """create link format"""
    out = []
    for link in value:
        out.append(','.join(list(link)))
    return '^'.join(out)

def http_request(method, url, request=None, timeout=10):
    """Perform HTTP request"""
    if method == 'POST':
        return http_post(url, request, timeout)
    else:  # GET
        request = urllib2.Request(url)
        request.add_header('User-Agent', 'pycsw (http://pycsw.org/)')
        return urllib2.urlopen(request, timeout=timeout).read()

def bind_url(url):
    """binds an HTTP GET query string endpiont"""
    if url.find('?') == -1: # like http://host/wms
        binder = '?'

    # if like http://host/wms?foo=bar& or http://host/wms?foo=bar
    if url.find('=') != -1:
        if url.find('&', -1) != -1: # like http://host/wms?foo=bar&
            binder = ''
        else: # like http://host/wms?foo=bar
            binder = '&'

    # if like http://host/wms?foo
    if url.find('?') != -1:
        if url.find('?', -1) != -1: # like http://host/wms?
            binder = ''
        elif url.find('&', -1) == -1: # like http://host/wms?foo=bar
            binder = '&'
    return '%s%s' % (url, binder)

def ip_in_network_cidr(ip, net):
    """decipher whether IP is within CIDR range"""
    ipaddr = int(''.join([ '%02x' % int(x) for x in ip.split('.') ]), 16)
    netstr, bits = net.split('/')
    netaddr = int(''.join([ '%02x' % int(x) for x in netstr.split('.') ]), 16)
    mask = (0xffffffff << (32 - int(bits))) & 0xffffffff
    return (ipaddr & mask) == (netaddr & mask)

def ipaddress_in_whitelist(ipaddress, whitelist):
    """
    decipher whether IP is in IP whitelist
    IP whitelist is a list supporting:
    - single IP address (e.g. 192.168.0.1)
    - IP range using CIDR (e.g. 192.168.0/22)
    - IP range using subnet wildcard (e.g. 192.168.0.*, 192.168.*)
    """

    if ipaddress in whitelist:
        return True
    else:
        for white in whitelist:
            if white.find('/') != -1:  # CIDR
                if ip_in_network_cidr(ipaddress, white):
                    return True
            elif white.find('*') != -1:  # subnet wildcard
                    if ipaddress.startswith(white.split('*')[0]):
                        return True
    return False
<|endoftext|>


<commit_before># coding: utf-8

from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse, HttpResponseForbidden
from push.models import DeviceTokenModel, NotificationModel, DevelopFileModel, ProductFileModel
from django.shortcuts import render, render_to_response, redirect
from django.template import RequestContext
from django.template.context_processors import csrf
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt

from ast import literal_eval
from datetime import datetime
from user_agents import parse
import json, urllib, ast, sys, os, threading, os.path, csv

UPLOAD_DIR = os.path.dirname(os.path.abspath(__file__)) + '/files/'
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/modules')

import push_notification

@login_required(login_url = '/accounts/login/')
def index(request):
    device_tokens = DeviceTokenModel.objects.filter(username = request.user.username)
    return render(request, 'push/top.html', {'device_tokens': device_tokens})

@login_required(login_url = '/accounts/login')
def download_device_token(request):
    device_tokens = DeviceTokenModel.objects.filter(username = request.user.username)

    response = HttpResponse(content_type = 'text/csv')
    response['Content-Disposition'] = 'attachment; filename="device_token_list.csv"'
    writer = csv.writer(response)
    writer.writerow(['OS Version', 'Device Token', 'Register Date'])

    for item in device_tokens:
        writer.writerow([str(item.os_version), item.device_token, '{0:%Y/%m/%d %H:%M}'.format(item.register_datetime)])

    return response

@login_required(login_url = '/accounts/login/')
def sender(request):
    if len(DevelopFileModel.objects.filter(upload_username = request.user.username)) > 0 and len(ProductFileModel.objects.filter(upload_username = request.user.username)) == 0:
        return render(request, 'push/sender.html', {'is_develop': True, 'is_product': False})
    elif len(DevelopFileModel.objects.filter(upload_username = request.user.username)) == 0 and len(ProductFileModel.objects.filter(upload_username = request.user.username)) > 0:
        return render(request, 'push/sender.html', {'is_develop': False, 'is_product': True})
    elif len(DevelopFileModel.objects.filter(upload_username = request.user.username)) == 0 and len(ProductFileModel.objects.filter(upload_username = request.user.username)) == 0:
        return render(request, 'push/sender.html', {'is_develop': False, 'is_product': False})
    else:
        return render(request, 'push/sender.html', {'is_develop': True, 'is_product': True})

@login_required(login_url = '/accounts/login/')
def notification_list(request):
    notifications = NotificationModel.objects.filter(username = request.user.username)
    return render(request, 'push/notification_list.html', {'notifications': notifications})

@login_required(login_url = '/accounts/login')
def notification_detail(request, notification_id):
    result = NotificationModel.objects.filter(id = notification_id)[0]
    return render(request, 'push/notification_detail.html', {'result': result})

@login_required(login_url = '/accounts/login/')
def settings(request):
    if request.method == 'POST' and (request.FILES.has_key('development') or request.FILES.has_key('production')):
        if request.FILES.has_key('development'):
            file = request.FILES['development']
            pem_file = DevelopFileModel(upload_username = request.user.username,
                                        development_file_name = str(request.user.username) + '/' + file.name)
        elif request.FILES.has_key('production'):
            file = request.FILES['production']
            pem_file = ProductFileModel(upload_username = request.user.username,
                                        production_file_name = str(request.user.username) + '/' + file.name)

        if '.pem' not in file.name:
            return render(request, 'push/settings.html', {'result': 'wrong'})
        else:
            USER_UPLOAD_DIR = UPLOAD_DIR + str(request.user.username) + '/'
            if os.path.isdir(USER_UPLOAD_DIR) == False:
                os.mkdir(USER_UPLOAD_DIR)
            path = os.path.join(USER_UPLOAD_DIR, file.name)
            destination = open(path, 'wb')
            for chunk in file.chunks():
                destination.write(chunk)

            if isinstance(pem_file, DevelopFileModel):
                results = DevelopFileModel.objects.all()
                for item in results:
                    if os.path.isfile(USER_UPLOAD_DIR + item.development_file_name):
                        os.remove(USER_UPLOAD_DIR + item.development_file_name)
                DevelopFileModel.objects.all().delete()
            elif isinstance(pem_file, ProductFileModel):
                results = ProductFileModel.objects.all()
                for item in results:
                    if os.path.isfile(USER_UPLOAD_DIR + item.production_file_name):
                        os.remove(USER_UPLOAD_DIR + item.production_file_name)
                ProductFileModel.objects.all().delete()
            pem_file.save()

        return render(request, 'push/settings.html', {'result': 'success'})
    else:
        return render(request, 'push/settings.html')

@login_required(login_url = '/accounts/login/')
def notification(request):
    if request.method == 'POST':
        notification = NotificationModel()
        if request.POST['title'] != '':
            notification.title = urllib.unquote(request.POST['title'])
        if request.POST['message'] != '':
            notification.message = urllib.unquote(request.POST['message'])
        if request.POST['os_version'] != '':
            notification.os_version = urllib.unquote(request.POST['os_version'])
        if request.POST['sound'] != '':
            notification.sound = request.POST['sound']
        if request.POST['badge'] != '':
            notification.badge = request.POST['badge']
        elif request.POST['badge'] == '':
            notification.badge = 0
        if request.POST['url'] != '':
            notification.url = urllib.unquote(request.POST['url'])
        if request.POST['datetime'] != '':
            tmp_datetime = request.POST['datetime'].split(' ')
            date = tmp_datetime[0]
            hour = tmp_datetime[1].split(':')[0]
            minute = tmp_datetime[1].split(':')[1]
            is_fm = True if tmp_datetime[2] == u'午後' else False
            if is_fm:
                hour = str(int(hour) + 12)
            notification.execute_datetime = date + ' ' + hour + ':' + minute
        else:
            notification.execute_datetime = '{0:%Y/%m/%d %H:%M}'.format(datetime.now())
        if request.POST.has_key('json'):
            notification.json = json.dumps(ast.literal_eval(request.POST['json'])).replace('\'', '\"')
        if request.POST.has_key('content-available'):
            notification.content_available = True
        if request.POST.has_key('is_production'):
            notification.is_production = True
        notification.username = request.user.username

        notification.save()

        if notification.execute_datetime == '{0:%Y/%m/%d %H:%M}'.format(datetime.now()) or notification.execute_datetime == '':
            device_tokens = DeviceTokenModel.objects.filter(os_version__gte = notification.os_version,
                                                            username = request.user.username)

            t = threading.Thread(target = prepare_push_notification, args = (notification, device_tokens))
            t.start();

        return redirect('push:notification_list')
    else:
        return HttpResponseForbidden()

@login_required(login_url = '/accounts/login/')
def delete_device_token(request, device_token_id):
    DeviceTokenModel.objects.filter(id = device_token_id).delete()
    return redirect('push:index')

@login_required(login_url = '/accounts/login')
def detail_device_token(request, device_token_id):
    result = DeviceTokenModel.objects.filter(id = device_token_id)[0]
    return render(request, 'push/device_token_detail.html', {'result': result})

@csrf_exempt
def device_token_register(request, username):
    if request.method == 'POST' and request.META['HTTP_USER_AGENT'] == 'iOS/nnsnodnb-mBaaS-Service':
        response_data = {}
        post_device_token, post_os_version = '', ''
        json_data = literal_eval(request.body)

        if json_data.has_key('device_token'):
            post_device_token = json_data['device_token']

        if json_data.has_key('os_version'):
            post_os_version = json_data['os_version']

        device_token_model = DeviceTokenModel.objects.filter(device_token = post_device_token,
                                                             username = username)

        if len(device_token_model) == 0 and post_device_token != '' and post_os_version != '':
            float_os_version = convert_float_os_version(post_os_version)

            insert_data = DeviceTokenModel(os_version = float_os_version,
                                           device_token = post_device_token,
                                           username = username)
            insert_data.save()

            response_data['result'] = 'success'
            response_data['message'] = '"' + post_device_token + '" is registered'
            return HttpResponse(json.dumps(response_data), content_type="application/json")
        else:
            float_os_version = convert_float_os_version(post_os_version)

            # Version down and Version up of iOS
            if device_token_model[0].os_version != float_os_version:
                device_token_model[0].os_version = float_os_version
                device_token_model[0].save()
            response_data['result'] = 'success'
            response_data['message'] = '"' + post_device_token + '" was registered'

            return HttpResponse(json.dumps(response_data), content_type="application/json")
    else:
        # return HttpResponseForbidden()
        return HttpResponse('Access Denied', status=403)

def convert_float_os_version(os_version):
    try:
        return float(os_version['os_version'])
    except Exception as e:
        os_version_arrays = os_version.split('.')
        tmp_string = os_version_arrays[0] + '.' + os_version_arrays[1]
        return float(tmp_string)

def prepare_push_notification(notification, device_tokens):
    device_token_lists = []
    for item in device_tokens:
        device_token_lists.append(item.device_token)

    push_notification.execute(device_token_lists, notification)
<commit_msg>Add UUID query filter<commit_after># coding: utf-8

from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse, HttpResponseForbidden
from push.models import DeviceTokenModel, NotificationModel, DevelopFileModel, ProductFileModel
from django.shortcuts import render, render_to_response, redirect
from django.template import RequestContext
from django.template.context_processors import csrf
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt

from ast import literal_eval
from datetime import datetime
from user_agents import parse
import json, urllib, ast, sys, os, threading, os.path, csv

UPLOAD_DIR = os.path.dirname(os.path.abspath(__file__)) + '/files/'
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/modules')

import push_notification

@login_required(login_url = '/accounts/login/')
def index(request):
    device_tokens = DeviceTokenModel.objects.filter(username = request.user.username)
    return render(request, 'push/top.html', {'device_tokens': device_tokens})

@login_required(login_url = '/accounts/login')
def download_device_token(request):
    device_tokens = DeviceTokenModel.objects.filter(username = request.user.username)

    response = HttpResponse(content_type = 'text/csv')
    response['Content-Disposition'] = 'attachment; filename="device_token_list.csv"'
    writer = csv.writer(response)
    writer.writerow(['OS Version', 'Device Token', 'Register Date'])

    for item in device_tokens:
        writer.writerow([str(item.os_version), item.device_token, '{0:%Y/%m/%d %H:%M}'.format(item.register_datetime)])

    return response

@login_required(login_url = '/accounts/login/')
def sender(request):
    if len(DevelopFileModel.objects.filter(upload_username = request.user.username)) > 0 and len(ProductFileModel.objects.filter(upload_username = request.user.username)) == 0:
        return render(request, 'push/sender.html', {'is_develop': True, 'is_product': False})
    elif len(DevelopFileModel.objects.filter(upload_username = request.user.username)) == 0 and len(ProductFileModel.objects.filter(upload_username = request.user.username)) > 0:
        return render(request, 'push/sender.html', {'is_develop': False, 'is_product': True})
    elif len(DevelopFileModel.objects.filter(upload_username = request.user.username)) == 0 and len(ProductFileModel.objects.filter(upload_username = request.user.username)) == 0:
        return render(request, 'push/sender.html', {'is_develop': False, 'is_product': False})
    else:
        return render(request, 'push/sender.html', {'is_develop': True, 'is_product': True})

@login_required(login_url = '/accounts/login/')
def notification_list(request):
    notifications = NotificationModel.objects.filter(username = request.user.username)
    return render(request, 'push/notification_list.html', {'notifications': notifications})

@login_required(login_url = '/accounts/login')
def notification_detail(request, notification_id):
    result = NotificationModel.objects.filter(id = notification_id)[0]
    return render(request, 'push/notification_detail.html', {'result': result})

@login_required(login_url = '/accounts/login/')
def settings(request):
    if request.method == 'POST' and (request.FILES.has_key('development') or request.FILES.has_key('production')):
        if request.FILES.has_key('development'):
            file = request.FILES['development']
            pem_file = DevelopFileModel(upload_username = request.user.username,
                                        development_file_name = str(request.user.username) + '/' + file.name)
        elif request.FILES.has_key('production'):
            file = request.FILES['production']
            pem_file = ProductFileModel(upload_username = request.user.username,
                                        production_file_name = str(request.user.username) + '/' + file.name)

        if '.pem' not in file.name:
            return render(request, 'push/settings.html', {'result': 'wrong'})
        else:
            USER_UPLOAD_DIR = UPLOAD_DIR + str(request.user.username) + '/'
            if os.path.isdir(USER_UPLOAD_DIR) == False:
                os.mkdir(USER_UPLOAD_DIR)
            path = os.path.join(USER_UPLOAD_DIR, file.name)
            destination = open(path, 'wb')
            for chunk in file.chunks():
                destination.write(chunk)

            if isinstance(pem_file, DevelopFileModel):
                results = DevelopFileModel.objects.all()
                for item in results:
                    if os.path.isfile(USER_UPLOAD_DIR + item.development_file_name):
                        os.remove(USER_UPLOAD_DIR + item.development_file_name)
                DevelopFileModel.objects.all().delete()
            elif isinstance(pem_file, ProductFileModel):
                results = ProductFileModel.objects.all()
                for item in results:
                    if os.path.isfile(USER_UPLOAD_DIR + item.production_file_name):
                        os.remove(USER_UPLOAD_DIR + item.production_file_name)
                ProductFileModel.objects.all().delete()
            pem_file.save()

        return render(request, 'push/settings.html', {'result': 'success'})
    else:
        return render(request, 'push/settings.html')

@login_required(login_url = '/accounts/login/')
def notification(request):
    if request.method == 'POST':
        notification = NotificationModel()
        if request.POST['title'] != '':
            notification.title = urllib.unquote(request.POST['title'])
        if request.POST['message'] != '':
            notification.message = urllib.unquote(request.POST['message'])
        if request.POST['os_version'] != '':
            notification.os_version = urllib.unquote(request.POST['os_version'])
        if request.POST['sound'] != '':
            notification.sound = request.POST['sound']
        if request.POST['badge'] != '':
            notification.badge = request.POST['badge']
        elif request.POST['badge'] == '':
            notification.badge = 0
        if request.POST['url'] != '':
            notification.url = urllib.unquote(request.POST['url'])
        if request.POST['datetime'] != '':
            tmp_datetime = request.POST['datetime'].split(' ')
            date = tmp_datetime[0]
            hour = tmp_datetime[1].split(':')[0]
            minute = tmp_datetime[1].split(':')[1]
            is_fm = True if tmp_datetime[2] == u'午後' else False
            if is_fm:
                hour = str(int(hour) + 12)
            notification.execute_datetime = date + ' ' + hour + ':' + minute
        else:
            notification.execute_datetime = '{0:%Y/%m/%d %H:%M}'.format(datetime.now())
        if request.POST.has_key('json'):
            notification.json = json.dumps(ast.literal_eval(request.POST['json'])).replace('\'', '\"')
        if request.POST.has_key('content-available'):
            notification.content_available = True
        if request.POST.has_key('is_production'):
            notification.is_production = True
        notification.username = request.user.username

        notification.save()

        if notification.execute_datetime == '{0:%Y/%m/%d %H:%M}'.format(datetime.now()) or notification.execute_datetime == '':
            device_tokens = DeviceTokenModel.objects.filter(os_version__gte = notification.os_version,
                                                            username = request.user.username)

            t = threading.Thread(target = prepare_push_notification, args = (notification, device_tokens))
            t.start();

        return redirect('push:notification_list')
    else:
        return HttpResponseForbidden()

@login_required(login_url = '/accounts/login/')
def delete_device_token(request, device_token_id):
    DeviceTokenModel.objects.filter(id = device_token_id).delete()
    return redirect('push:index')

@login_required(login_url = '/accounts/login')
def detail_device_token(request, device_token_id):
    result = DeviceTokenModel.objects.filter(id = device_token_id)[0]
    return render(request, 'push/device_token_detail.html', {'result': result})

@csrf_exempt
def device_token_register(request, username):
    if request.method == 'POST' and request.META['HTTP_USER_AGENT'] == 'iOS/nnsnodnb-mBaaS-Service':
        response_data = {}
        post_device_token, post_os_version, post_uuid = '', '', ''
        json_data = literal_eval(request.body)

        if json_data.has_key('device_token'):
            post_device_token = json_data['device_token']

        if json_data.has_key('os_version'):
            post_os_version = json_data['os_version']

        if json_data.has_key('uuid'):
            post_uuid = json_data['uuid']

        device_token_model = DeviceTokenModel.objects.filter(device_token = post_device_token,
                                                             username = username,
                                                             uuid = post_uuid)

        if len(device_token_model) == 0 and post_device_token != '' and post_os_version != '' and post_uuid != '':
            float_os_version = convert_float_os_version(post_os_version)

            insert_data = DeviceTokenModel(os_version = float_os_version,
                                           device_token = post_device_token,
                                           username = username)
            insert_data.save()

            response_data['result'] = 'success'
            response_data['message'] = '"' + post_device_token + '" is registered'
            return HttpResponse(json.dumps(response_data), content_type="application/json")
        else:
            float_os_version = convert_float_os_version(post_os_version)

            # Version down and Version up of iOS
            if device_token_model[0].os_version != float_os_version:
                device_token_model[0].os_version = float_os_version
                device_token_model[0].save()
            response_data['result'] = 'success'
            response_data['message'] = '"' + post_device_token + '" was registered'

            return HttpResponse(json.dumps(response_data), content_type="application/json")
    else:
        # return HttpResponseForbidden()
        return HttpResponse('Access Denied', status=403)

def convert_float_os_version(os_version):
    try:
        return float(os_version['os_version'])
    except Exception as e:
        os_version_arrays = os_version.split('.')
        tmp_string = os_version_arrays[0] + '.' + os_version_arrays[1]
        return float(tmp_string)

def prepare_push_notification(notification, device_tokens):
    device_token_lists = []
    for item in device_tokens:
        device_token_lists.append(item.device_token)

    push_notification.execute(device_token_lists, notification)
<|endoftext|>


<commit_before>#!/usr/bin/env python

import math
import pygame
import random
import sys

screen_width = 640
screen_height = 480

screen = None
rendered_main_texts = {}
rendered_small_texts = {}

def start():
    global screen, ready_text, ready_text_pos, end_text, end_text_pos
    pygame.init()
    screen = pygame.display.set_mode( ( screen_width, screen_height ) )

def write_main_text( screen, text, color ):
    global rendered_main_texts
    if text not in rendered_main_texts:
        font = pygame.font.Font( None, screen_height / 5 )
        rend = font.render( text, 1, color )
        pos = rend.get_rect(
            centerx = screen.get_width() / 2,
            centery = screen.get_height() / 2
        )
        rendered_main_texts[text] = rend, pos
    else:
        rend, pos = rendered_main_texts[text]
    screen.blit( rend, pos )

def write_small_text( screen, text, color ):
    global rendered_small_texts
    if text not in rendered_small_texts:
        font = pygame.font.Font( None, screen_height / 12 )
        rend = font.render( text, 1, color )
        pos = rend.get_rect(
            centerx = screen.get_width() / 2,
            centery = screen.get_height() - ( screen_height / 24 )
        )
        rendered_small_texts[text] = rend, pos
    else:
        rend, pos = rendered_small_texts[text]
    screen.blit( rend, pos )

def quit():
    pygame.quit()
    sys.exit()

def ready_screen( go_number ):
    screen.fill( pygame.Color( "black" ) )
    write_main_text( screen, "Ready?", pygame.Color( "white" ) )

    go_number_str = "Go number: %d" % go_number

    write_small_text( screen, go_number_str, pygame.Color( "white" ) )

    pygame.display.flip()

def timed_wait( time_to_wait, event_types_that_cancel ):
    """
    Wait for the specified time_to_wait, but cancel if we receive an
    event of one of the types in event_types_that_cancel.
    Return True if we were cancelled, or False if the time ran out.
    """

    start_time = pygame.time.get_ticks()

    while pygame.time.get_ticks() - start_time < time_to_wait:
        evt = pygame.event.poll()
        if evt.type == pygame.QUIT:
            quit()
        elif evt.type in event_types_that_cancel:
            return True
        pygame.time.wait( 10 ) # Give the system a little rest

    return False

def wait():
    time_to_wait = random.randint( 1500, 3000 ) # Between 1.5 and 3 seconds
    timed_wait( time_to_wait, [] )

def shape_wait():

    wait_time = 2000     # We will wait for 2 seconds for a keypress

    pygame.event.clear()
    return timed_wait( wait_time, ( pygame.KEYDOWN, pygame.MOUSEBUTTONDOWN ) )

def smiley_face():
    green = pygame.Color( "green" )
    centre_x = screen.get_width() / 2
    centre_y = screen.get_height() / 2
    centre = centre_x, centre_y
    radius = int( screen.get_height() / 2.5 )
    width = screen.get_height() / 30

    eye_radius = screen.get_height() / 10
    eye1_centre_x = centre_x - ( radius / 3 )
    eye1_centre_y = centre_y - ( 13 * radius / 30 )
    eye2_centre_x = centre_x + ( radius / 3 )
    eye2_centre_y = centre_y - ( 13 * radius / 30 )

    eye1_centre = eye1_centre_x, eye1_centre_y
    eye2_centre = eye2_centre_x, eye2_centre_y

    mouth_left   = centre_x - ( 3 * radius / 8 )
    mouth_width  = 3 * radius / 4
    mouth_top    = centre_y
    mouth_height = 2 * radius / 3

    mouth_rect = ( ( mouth_left, mouth_top ), ( mouth_width, mouth_height ) )
    mouth_start = math.pi       # Downwards
    mouth_end   = 2 * math.pi   # Upwards

    screen.fill( pygame.Color( "white" ) )
    pygame.draw.circle( screen, green, centre, radius, width )
    pygame.draw.circle( screen, green, eye1_centre, eye_radius, width )
    pygame.draw.circle( screen, green, eye2_centre, eye_radius, width )
    pygame.draw.arc( screen, green, mouth_rect, mouth_start, mouth_end, width )

def sad_face():
    red = pygame.Color( "red" )
    centre_x = screen.get_width() / 2
    centre_y = screen.get_height() / 2
    centre = centre_x, centre_y
    radius = int( screen.get_height() / 2.5 )
    width = screen.get_height() / 30

    eye_radius = screen.get_height() / 10
    eye1_centre_x = centre_x - ( radius / 3 )
    eye1_centre_y = centre_y - ( 13 * radius / 30 )
    eye2_centre_x = centre_x + ( radius / 3 )
    eye2_centre_y = centre_y - ( 13 * radius / 30 )

    eye1_centre = eye1_centre_x, eye1_centre_y
    eye2_centre = eye2_centre_x, eye2_centre_y

    mouth_left   = centre_x - ( 3 * radius / 8 )
    mouth_width  = 3 * radius / 4
    mouth_top    = centre_y + ( radius / 5 )
    mouth_height = 2 * radius / 3

    mouth_rect = ( ( mouth_left, mouth_top ), ( mouth_width, mouth_height ) )
    mouth_start = 0
    mouth_end   = math.pi

    screen.fill( pygame.Color( "white" ) )
    pygame.draw.circle( screen, red, centre, radius, width )
    pygame.draw.circle( screen, red, eye1_centre, eye_radius, width )
    pygame.draw.circle( screen, red, eye2_centre, eye_radius, width )
    pygame.draw.arc( screen, red, mouth_rect, mouth_start, mouth_end, width )

def result_wait():
    result_time = 3000 # wait for 4 seconds
    timed_wait( result_time, ( pygame.KEYDOWN, pygame.MOUSEBUTTONDOWN ) )

def green_success():
    smiley_face()
    write_main_text( screen, "Well done!", pygame.Color( "green" ) )
    write_small_text(
        screen, "You pressed on green!", pygame.Color( "black" ) )
    pygame.display.flip()

    result_wait()

def green_failure():
    sad_face()
    write_main_text( screen, "Bad luck!", pygame.Color( "red" ) )
    write_small_text(
        screen, "Green means press something!", pygame.Color( "black" ) )

    pygame.display.flip()

    result_wait()

def red_success():
    smiley_face()
    write_main_text( screen, "Well done!", pygame.Color( "green" ) )
    write_small_text(
        screen, "You didn't press on red!", pygame.Color( "black" ) )
    pygame.display.flip()

    result_wait()

def red_failure():
    sad_face()
    write_main_text( screen, "Bad luck!", pygame.Color( "red" ) )
    write_small_text(
        screen, "Red means don't press anything!", pygame.Color( "black" ) )

    pygame.display.flip()

    result_wait()

def green_shape():
    green = pygame.Color( "green" )
    centre = ( screen.get_width() / 2, screen.get_height() / 2 )
    radius = screen.get_height() / 3

    screen.fill( pygame.Color( "white" ) )
    pygame.draw.circle( screen, green, centre, radius, 0 )

    write_small_text( screen, "Press something!", pygame.Color( "black" ) )

    pygame.display.flip()

    pressed = shape_wait()

    if pressed:
        green_success()
        return 1
    else:
        green_failure()
        return 0

def red_shape():
    red = pygame.Color( "red" )
    height = 2 * ( screen.get_height() / 3 )
    left = ( screen.get_width() / 2 ) - ( height / 2 )
    top = screen.get_height() / 6
    centre = ( screen.get_width() / 2, screen.get_height() / 2 )
    radius = screen.get_height() / 3

    screen.fill( pygame.Color( "white" ) )
    pygame.draw.rect( screen, red, ( left, top, height, height ), 0 )

    write_small_text( screen, "Don't press!", pygame.Color( "black" ) )

    pygame.display.flip()

    pressed = shape_wait()

    if pressed:
        red_failure()
        return 0
    else:
        red_success()
        return 1

def shape():
    GREEN = 0
    RED   = 1
    shape = random.choice( [GREEN, RED] )

    if shape == GREEN:
        return green_shape()
    else:
        return red_shape()

def end( correct ):
    print "You got %d correct answers" % correct
    screen.fill( pygame.Color( "white" ) )
    black = pygame.Color( "black" )
    write_main_text( screen, "Thanks for playing!", black )

    write_small_text( screen, "You got %d correct answers." % correct, black )

    pygame.display.flip()

    end_time = 10000 # wait for 10 seconds
    timed_wait( end_time, ( pygame.KEYDOWN, pygame.MOUSEBUTTONDOWN ) )

    quit()

# We start from here

start()

correct = 0
for i in range( 10 ):
    ready_screen( i )
    wait()
    correct += shape()

end( correct )

<commit_msg>Calculate the amount of time waiting before each press, and give a score based on the max minus what we waited for, with max time allocated for pressing on red.<commit_after>#!/usr/bin/env python

import math
import pygame
import random
import sys

screen_width = 640
screen_height = 480

screen = None
rendered_main_texts = {}
rendered_small_texts = {}

wait_time = 2000 # Display each shape for 2 seconds

def start():
    global screen, ready_text, ready_text_pos, end_text, end_text_pos
    pygame.init()
    screen = pygame.display.set_mode( ( screen_width, screen_height ) )

def write_main_text( screen, text, color ):
    global rendered_main_texts
    if text not in rendered_main_texts:
        font = pygame.font.Font( None, screen_height / 5 )
        rend = font.render( text, 1, color )
        pos = rend.get_rect(
            centerx = screen.get_width() / 2,
            centery = screen.get_height() / 2
        )
        rendered_main_texts[text] = rend, pos
    else:
        rend, pos = rendered_main_texts[text]
    screen.blit( rend, pos )

def write_small_text( screen, text, color ):
    global rendered_small_texts
    if text not in rendered_small_texts:
        font = pygame.font.Font( None, screen_height / 12 )
        rend = font.render( text, 1, color )
        pos = rend.get_rect(
            centerx = screen.get_width() / 2,
            centery = screen.get_height() - ( screen_height / 24 )
        )
        rendered_small_texts[text] = rend, pos
    else:
        rend, pos = rendered_small_texts[text]
    screen.blit( rend, pos )

def quit():
    pygame.quit()
    sys.exit()

def ready_screen( go_number ):
    screen.fill( pygame.Color( "black" ) )
    write_main_text( screen, "Ready?", pygame.Color( "white" ) )

    go_number_str = "Go number: %d" % go_number

    write_small_text( screen, go_number_str, pygame.Color( "white" ) )

    pygame.display.flip()

def timed_wait( time_to_wait, event_types_that_cancel ):
    """
    Wait for the specified time_to_wait, but cancel if we receive an
    event of one of the types in event_types_that_cancel.
    Return True if we were cancelled, or False if the time ran out.
    """

    start_time = pygame.time.get_ticks()

    while pygame.time.get_ticks() - start_time < time_to_wait:
        evt = pygame.event.poll()
        if evt.type == pygame.QUIT:
            quit()
        elif evt.type in event_types_that_cancel:
            return ( True, pygame.time.get_ticks() - start_time )
        pygame.time.wait( 10 ) # Give the system a little rest

    return ( False, time_to_wait )

def wait():
    time_to_wait = random.randint( 1500, 3000 ) # Between 1.5 and 3 seconds
    timed_wait( time_to_wait, [] )

def shape_wait():
    global wait_time

    pygame.event.clear()
    return timed_wait( wait_time, ( pygame.KEYDOWN, pygame.MOUSEBUTTONDOWN ) )

def smiley_face():
    green = pygame.Color( "green" )
    centre_x = screen.get_width() / 2
    centre_y = screen.get_height() / 2
    centre = centre_x, centre_y
    radius = int( screen.get_height() / 2.5 )
    width = screen.get_height() / 30

    eye_radius = screen.get_height() / 10
    eye1_centre_x = centre_x - ( radius / 3 )
    eye1_centre_y = centre_y - ( 13 * radius / 30 )
    eye2_centre_x = centre_x + ( radius / 3 )
    eye2_centre_y = centre_y - ( 13 * radius / 30 )

    eye1_centre = eye1_centre_x, eye1_centre_y
    eye2_centre = eye2_centre_x, eye2_centre_y

    mouth_left   = centre_x - ( 3 * radius / 8 )
    mouth_width  = 3 * radius / 4
    mouth_top    = centre_y
    mouth_height = 2 * radius / 3

    mouth_rect = ( ( mouth_left, mouth_top ), ( mouth_width, mouth_height ) )
    mouth_start = math.pi       # Downwards
    mouth_end   = 2 * math.pi   # Upwards

    screen.fill( pygame.Color( "white" ) )
    pygame.draw.circle( screen, green, centre, radius, width )
    pygame.draw.circle( screen, green, eye1_centre, eye_radius, width )
    pygame.draw.circle( screen, green, eye2_centre, eye_radius, width )
    pygame.draw.arc( screen, green, mouth_rect, mouth_start, mouth_end, width )

def sad_face():
    red = pygame.Color( "red" )
    centre_x = screen.get_width() / 2
    centre_y = screen.get_height() / 2
    centre = centre_x, centre_y
    radius = int( screen.get_height() / 2.5 )
    width = screen.get_height() / 30

    eye_radius = screen.get_height() / 10
    eye1_centre_x = centre_x - ( radius / 3 )
    eye1_centre_y = centre_y - ( 13 * radius / 30 )
    eye2_centre_x = centre_x + ( radius / 3 )
    eye2_centre_y = centre_y - ( 13 * radius / 30 )

    eye1_centre = eye1_centre_x, eye1_centre_y
    eye2_centre = eye2_centre_x, eye2_centre_y

    mouth_left   = centre_x - ( 3 * radius / 8 )
    mouth_width  = 3 * radius / 4
    mouth_top    = centre_y + ( radius / 5 )
    mouth_height = 2 * radius / 3

    mouth_rect = ( ( mouth_left, mouth_top ), ( mouth_width, mouth_height ) )
    mouth_start = 0
    mouth_end   = math.pi

    screen.fill( pygame.Color( "white" ) )
    pygame.draw.circle( screen, red, centre, radius, width )
    pygame.draw.circle( screen, red, eye1_centre, eye_radius, width )
    pygame.draw.circle( screen, red, eye2_centre, eye_radius, width )
    pygame.draw.arc( screen, red, mouth_rect, mouth_start, mouth_end, width )

def result_wait():
    result_time = 3000 # wait for 4 seconds
    timed_wait( result_time, ( pygame.KEYDOWN, pygame.MOUSEBUTTONDOWN ) )

def green_success():
    smiley_face()
    write_main_text( screen, "Well done!", pygame.Color( "green" ) )
    write_small_text(
        screen, "You pressed on green!", pygame.Color( "black" ) )
    pygame.display.flip()

    result_wait()

def green_failure():
    sad_face()
    write_main_text( screen, "Bad luck!", pygame.Color( "red" ) )
    write_small_text(
        screen, "Green means press something!", pygame.Color( "black" ) )

    pygame.display.flip()

    result_wait()

def red_success():
    smiley_face()
    write_main_text( screen, "Well done!", pygame.Color( "green" ) )
    write_small_text(
        screen, "You didn't press on red!", pygame.Color( "black" ) )
    pygame.display.flip()

    result_wait()

def red_failure():
    sad_face()
    write_main_text( screen, "Bad luck!", pygame.Color( "red" ) )
    write_small_text(
        screen, "Red means don't press anything!", pygame.Color( "black" ) )

    pygame.display.flip()

    result_wait()

def green_shape():
    green = pygame.Color( "green" )
    centre = ( screen.get_width() / 2, screen.get_height() / 2 )
    radius = screen.get_height() / 3

    screen.fill( pygame.Color( "white" ) )
    pygame.draw.circle( screen, green, centre, radius, 0 )

    write_small_text( screen, "Press something!", pygame.Color( "black" ) )

    pygame.display.flip()

    pressed, time = shape_wait()

    if pressed:
        green_success()
        return 1, time
    else:
        green_failure()
        return 0, time

def red_shape():
    global wait_time

    red = pygame.Color( "red" )
    height = 2 * ( screen.get_height() / 3 )
    left = ( screen.get_width() / 2 ) - ( height / 2 )
    top = screen.get_height() / 6
    centre = ( screen.get_width() / 2, screen.get_height() / 2 )
    radius = screen.get_height() / 3

    screen.fill( pygame.Color( "white" ) )
    pygame.draw.rect( screen, red, ( left, top, height, height ), 0 )

    write_small_text( screen, "Don't press!", pygame.Color( "black" ) )

    pygame.display.flip()

    pressed, time = shape_wait()

    if pressed:
        red_failure()
        return 0, wait_time
    else:
        red_success()
        return 1, 0

def shape():
    GREEN = 0
    RED   = 1
    shape = random.choice( [GREEN, RED] )

    if shape == GREEN:
        return green_shape()
    else:
        return red_shape()

def end( correct, time_score ):
    print "You got %d correct answers" % correct
    print "You scored %d" % time_score
    screen.fill( pygame.Color( "white" ) )
    black = pygame.Color( "black" )
    write_main_text( screen, "Thanks for playing!", black )

    write_small_text( screen, "You got %d correct answers." % correct, black )

    pygame.display.flip()

    end_time = 10000 # wait for 10 seconds
    timed_wait( end_time, ( pygame.KEYDOWN, pygame.MOUSEBUTTONDOWN ) )

    quit()

# We start from here

start()

num_goes = 10

correct = 0
time_millis = 0
for i in range( num_goes ):
    ready_screen( i )
    wait()
    correct_points, tm_points = shape()
    correct += correct_points
    time_millis += tm_points

max_time = num_goes * wait_time

end( correct, max_time - time_millis )

<|endoftext|>