<commit_before>from django.contrib.auth.decorators import login_required
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import PermissionDenied
from django.http import HttpResponse
from django.shortcuts import get_object_or_404, redirect, render_to_response
from django.template import RequestContext
from django.utils.translation import ugettext, ugettext_lazy as _

from iris.conf import settings
from iris.forms import TopicForm
from iris.models import Item, Topic

# --- TOPICS ---

def topic(request, topic_id, slug=None, template_name="iris/topic.html", extra_context=None, *args, **kwargs):
    extra_context = extra_context or {}
    topic = get_object_or_404(Topic, pk=topic_id)
    if not request.user.has_perm('iris.view_topic', topic):
        raise PermissionDenied()
    item_type_plugin_list = settings.ITEM_TYPE_PLUGINS
    template_context = dict(
        topic=topic,
        item_type_plugin_list=item_type_plugin_list,
    )
    template_context.update(extra_context)
    return render_to_response(template_name, template_context, RequestContext(request))

def default_post_topic_create(request, topic, *args, **kwargs):
    topic.add_participant(creator=request.user, obj=request.user)

def topic_create(request, form_class=TopicForm, post_topic_create=default_post_topic_create,
                 template_name="iris/topic_create.html", extra_context=None, *args, **kwargs):
    if not request.user.has_perm('iris.add_topic'):
        raise PermissionDenied()
    extra_context = extra_context or {}
    if request.method == 'POST':
        topic_create_form = form_class(request.POST)
        if topic_create_form.is_valid():
            topic = topic_create_form.save(commit=False)
            topic.creator = request.user
            topic.save()
            post_topic_create(request, topic, *args, **kwargs)
            return redirect(topic)
    else:
        topic_create_form = form_class()
    template_context = dict(
        topic_create_form=topic_create_form,
    )
    template_context.update(extra_context)
    return render_to_response(template_name, template_context, RequestContext(request))

def topic_join(request, topic_id, *args, **kwargs):
    topic = get_object_or_404(Topic, pk=topic_id)
    destination = topic
    if request.method == 'POST':
        if not request.user.has_perm('iris.join_topic', topic):
            raise PermissionDenied()
        if not topic.has_participant(request.user):
            destination = topic.add_participant(request.user, request.user)
    return redirect(destination)

def topics(request, template_name="iris/topics.html", form_class=TopicForm, queryset=None, queryset_fn=None, extra_context=None, *args, **kwargs):
    """Render a list of topics.

    Set `queryset_fn` to a function that accepts `request` and `queryset`
    if you would like to select topics other than the default `queryset`
    which is all topics in last-modified order.
    """
    extra_context = extra_context or {}
    if queryset is None:
        queryset = Topic.objects.order_by('modified')
    if callable(queryset_fn):
        queryset = queryset_fn(request, queryset)
    topic_create_form = form_class()
    template_context = dict(
        topic_list=queryset,
        topic_create_form=topic_create_form,
    )
    template_context.update(extra_context)
    return render_to_response(template_name, template_context, RequestContext(request))

# --- ITEMS ---

def item_add(request, topic_id, plugin_name, template_name="iris/item_add.html", extra_context=None, *args, **kwargs):
    extra_context = extra_context or {}
    topic = get_object_or_404(Topic, pk=topic_id)
    if not request.user.has_perm('iris.add_to_topic', topic):
        raise PermissionDenied()
    plugin = settings.ITEM_TYPE_PLUGINS_BY_NAME[plugin_name]
    form_class = plugin.form_class
    if request.method == 'POST':
        form = form_class(request.POST)
        if form.is_valid():
            item = form.save(request, topic)
            if request.is_ajax():
                return HttpResponse('1', 'application/json')
            else:
                if item:
                    return redirect(item)
                else:
                    # Form saved, but due to duplicate data or other circumstance,
                    # no item was generated but no error state either, so
                    # redirect to topic.
                    return redirect(topic)
    else:
        form = form_class()
    template_context = dict(
        topic=topic,
        item_type_plugin=plugin,
        item_add_form=form,
    )
    template_context.update(extra_context)
    # Just return the snippet for an AJAX request.
    if request.is_ajax():
        template_name = plugin.add_template
    return render_to_response(template_name, template_context, RequestContext(request))

def items_after(request, topic_id, after_item_id, template_name="iris/items_after.html", extra_context=None, *args, **kwargs):
    extra_context = extra_context or {}
    topic = get_object_or_404(Topic, pk=topic_id)
    if not request.user.has_perm('iris.view_topic', topic):
        raise PermissionDenied()
    after_item = get_object_or_404(Item, pk=after_item_id, topic=topic)
    item_list = topic.items.filter(created__gt=after_item.created)
    template_context = dict(
        after_item=after_item,
        item_list=item_list,
    )
    template_context.update(extra_context)
    if request.is_ajax():
        bits = template_name.rsplit('.', 1)
        template_name = bits[0] + '_ajax.' + bits[1]
    return render_to_response(template_name, template_context, RequestContext(request))
<commit_msg>Pass along GET params through POST actions<commit_after>from django.contrib.auth.decorators import login_required
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import PermissionDenied
from django.http import HttpResponse
from django.shortcuts import get_object_or_404, redirect, render_to_response
from django.template import RequestContext
from django.utils.translation import ugettext, ugettext_lazy as _

from iris.conf import settings
from iris.forms import TopicForm
from iris.models import Item, Topic

# --- TOPICS ---

def topic(request, topic_id, slug=None, template_name="iris/topic.html", extra_context=None, *args, **kwargs):
    extra_context = extra_context or {}
    topic = get_object_or_404(Topic, pk=topic_id)
    if not request.user.has_perm('iris.view_topic', topic):
        raise PermissionDenied()
    item_type_plugin_list = settings.ITEM_TYPE_PLUGINS
    template_context = dict(
        topic=topic,
        item_type_plugin_list=item_type_plugin_list,
    )
    template_context.update(extra_context)
    return render_to_response(template_name, template_context, RequestContext(request))

def default_post_topic_create(request, topic, *args, **kwargs):
    topic.add_participant(creator=request.user, obj=request.user)

def topic_create(request, form_class=TopicForm, post_topic_create=default_post_topic_create,
                 template_name="iris/topic_create.html", extra_context=None, *args, **kwargs):
    if not request.user.has_perm('iris.add_topic'):
        raise PermissionDenied()
    extra_context = extra_context or {}
    if request.method == 'POST':
        topic_create_form = form_class(request.POST)
        if topic_create_form.is_valid():
            topic = topic_create_form.save(commit=False)
            topic.creator = request.user
            topic.save()
            post_topic_create(request, topic, *args, **kwargs)
            # attach get params
            url = '{0}?{1}'.format(topic.get_absolute_url(), request.GET.urlencode())
            return redirect(url)
    else:
        topic_create_form = form_class()
    template_context = dict(
        topic_create_form=topic_create_form,
    )
    template_context.update(extra_context)
    return render_to_response(template_name, template_context, RequestContext(request))

def topic_join(request, topic_id, *args, **kwargs):
    topic = get_object_or_404(Topic, pk=topic_id)
    destination = topic
    if request.method == 'POST':
        if not request.user.has_perm('iris.join_topic', topic):
            raise PermissionDenied()
        if not topic.has_participant(request.user):
            destination = topic.add_participant(request.user, request.user)
    url = '{0}?{1}'.format(destination.get_absolute_url(), request.GET.urlencode())
    return redirect(url)

def topics(request, template_name="iris/topics.html", form_class=TopicForm, queryset=None, queryset_fn=None, extra_context=None, *args, **kwargs):
    """Render a list of topics.

    Set `queryset_fn` to a function that accepts ``request, queryset, *args, **kwargs``
    if you would like to select topics other than the default `queryset`
    which is all topics in last-modified order.
    """
    extra_context = extra_context or {}
    if queryset is None:
        queryset = Topic.objects.order_by('modified')
    if callable(queryset_fn):
        queryset = queryset_fn(request, queryset, *args, **kwargs)
    topic_create_form = form_class()
    template_context = dict(
        topic_list=queryset,
        topic_create_form=topic_create_form,
    )
    template_context.update(extra_context)
    return render_to_response(template_name, template_context, RequestContext(request))

# --- ITEMS ---

def item_add(request, topic_id, plugin_name, template_name="iris/item_add.html", extra_context=None, *args, **kwargs):
    extra_context = extra_context or {}
    topic = get_object_or_404(Topic, pk=topic_id)
    if not request.user.has_perm('iris.add_to_topic', topic):
        raise PermissionDenied()
    plugin = settings.ITEM_TYPE_PLUGINS_BY_NAME[plugin_name]
    form_class = plugin.form_class
    if request.method == 'POST':
        form = form_class(request.POST)
        if form.is_valid():
            item = form.save(request, topic)
            if request.is_ajax():
                return HttpResponse('1', 'application/json')
            else:
                if item:
                    url = '{0}?{1}'.format(item.get_absolute_url(), request.GET.urlencode())
                else:
                    # Form saved, but due to duplicate data or other circumstance,
                    # no item was generated but no error state either, so
                    # redirect to topic.
                    url = '{0}?{1}'.format(topic.get_absolute_url(), request.GET.urlencode())
                return redirect(url)
    else:
        form = form_class()
    template_context = dict(
        topic=topic,
        item_type_plugin=plugin,
        item_add_form=form,
    )
    template_context.update(extra_context)
    # Just return the snippet for an AJAX request.
    if request.is_ajax():
        template_name = plugin.add_template
    return render_to_response(template_name, template_context, RequestContext(request))

def items_after(request, topic_id, after_item_id, template_name="iris/items_after.html", extra_context=None, *args, **kwargs):
    extra_context = extra_context or {}
    topic = get_object_or_404(Topic, pk=topic_id)
    if not request.user.has_perm('iris.view_topic', topic):
        raise PermissionDenied()
    after_item = get_object_or_404(Item, pk=after_item_id, topic=topic)
    item_list = topic.items.filter(created__gt=after_item.created)
    template_context = dict(
        after_item=after_item,
        item_list=item_list,
    )
    template_context.update(extra_context)
    if request.is_ajax():
        bits = template_name.rsplit('.', 1)
        template_name = bits[0] + '_ajax.' + bits[1]
    return render_to_response(template_name, template_context, RequestContext(request))
<|endoftext|>


<commit_before>#!/usr/bin/python vendor/pyy/cgi.py

from vendor.pyy          import web
from vendor.pyy.htmlpage import xhtmlpage
from vendor.pyy.xhtml11  import *
import re

def MediaInfo2Dict(text):
    """
    This method takes the text output from the program MediaInfo and parses it
    into a dictionary heirarchy.
    """
    import re
    rkeyval = re.compile(r'\s+:\s')
    res = {}

    for category in text.replace('\r\n', '\n').strip().split('\n\n'):
        pairs = map(str.strip, category.split('\n'))
        if pairs:
            name = pairs.pop(0).replace(' ', '_').lower()
            res[name] = dict(rkeyval.split(pair, 2) for pair in pairs)
    if 'video' in res and 'Encoding settings' in res['video']:
        res['video']['Encoding settings'] = dict(pair.split('=', 1) for pair in map(str.strip, filter(None, res['video']['Encoding settings'].split('/'))))
    return res

def is_awesome(text, is_animation):
    info = MediaInfo2Dict(text)

    is_a = True
    is_d = True
    warnings = ul()
    errors = ul()

    a = strong('Awesome: ')
    d = strong('DXVA: ')

    is_1080p = (info['video']['Width'] == '1 920 pixels')
    is_720p  = (info['video']['Width'] == '1 280 pixels')

    #Check 1: 720p/1080p
    if not is_720p and not is_1080p:
        is_a = False
        errors += li(a, 'Must be 1920 or 1280 pixels wide. Got: ', info['video']['Width'])

    #Check 2: is x264
    if info['video']['Codec ID'] != 'V_MPEG4/ISO/AVC':
        is_a = False
        errors += li(a, 'Not MPEG4/ISO/AVC (x264) codec. Got: ', info['video']['Codec ID'])

    #Check 3: DTS or AC3 track
    if 'audio' in info:
        a_codec = info['audio']['Format']
        if not a_codec == 'DTS' and not a_codec == 'AC3':
            is_a = False
            errors += li(a, 'Audio track not DTS or AC3. Got: ', info['audio']['Format'])
    elif 'audio_#1' in info:
        a_codec = info['audio_#1']['Format']
        if not a_codec == 'DTS' and not a_codec == 'AC3':
            is_a = False
            errors += li(a, 'Audio track not DTS or AC3. Got: ', info['audio_#1']['Format'])
    else:
        is_a = False
        errors += li(a, 'No audio tracks.')

    #Check 4: English subtitles
    if 'text' in info:
        if info['text']['Language'] != 'English':
            is_a = False
            errors += li(a, 'Subtitle track not English. Got: ', info['text']['Language'])
    elif 'text_#1' in info:
        if info['text_#1']['Language'] != 'English':
            is_a = False
            errors += li(a, 'No English subtitles. Got: ', info['text_#1']['Language'])
    else:
        is_a = False
        errors += li('No subtitle tracks.')

    height = int(info['video']['Height'].replace('pixels', '').replace(' ', '').strip())
    ref = int(info['video']['Encoding settings']['ref'])
    if is_1080p:
        if height <= 720:
            #Check 6: 3<=ref<=6
            if ref < 3 or ref > 6:
                is_d = False
                errors += li(d, 'Reference frames not between 3 and 6. Got: ', ref)
        elif height <= 864:
            #Check 6: 3<=ref<=5
            if ref < 3 or ref > 5:
                is_d = False
                errors += li(d, 'Reference frames not between 3 and 5. Got: ', ref)
        else:
            #Check 6: 3<=ref<=4
            if ref < 3 or ref > 4:
                is_d = False
                errors += li(d, 'Reference frames not between 3 and 4. Got: ', ref)
    else:
        if height <= 540:
            #Check 6: 5<=ref<=12
            if ref < 5 or ref > 12:
                is_d = False
                errors += li(d, 'Reference frames not between 5 and 12. Got: ', ref)
        elif height <= 588:
            #Check 6: 5<=ref<=11
            if ref < 5 or ref > 11:
                is_d = False
                errors += li(d, 'Reference frames not between 5 and 11. Got: ', ref)
        elif height <= 648:
            #Check 6: 5<=ref<=10
            if ref < 5 or ref > 10:
                is_d = False
                errors += li(d, 'Reference frames not between 5 and 10. Got: ', ref)
        else:
            #Check 6: 5<=ref<=9
            if ref < 5 or ref > 9:
                is_d = False
                errors += li(d, 'Reference frames not between 5 and 9. Got: ', ref)

    #Check 5: cabac = 1
    if info['video']['Encoding settings']['cabac'] != '1':
        is_a = False
        errors += li(a, code('cabac'), ' must be 1. Got: ', info['video']['Encoding settings']['cabac'])

    #Check 7: vbv_maxrate <= 50000
    if 'vbv_maxrate' in info['video']['Encoding settings']:
        if int(info['video']['Encoding settings']['vbv_maxrate']) > 50000:
            is_d = False
            errors += li(d, code('vbv_maxrate'), ' must be less than or equal to 50,000. Got: ', info['video']['Encoding settings']['vbv_maxrate'])
    else:
        warnings += li(code('vbv_maxrate'), ' can not be determined. Assuming a value lower than 50,000.')

    #Check 8: vbv_bufsize <= 50000
    if 'vbv_bufsize' in info['video']['Encoding settings']:
        if int(info['video']['Encoding settings']['vbv_bufsize']) > 50000:
            is_d = False
            errors += li(d, code('vbv_bufsize'), ' must be less than or equal to 50,000.', info['video']['Encoding settings']['vbv_bufsize'])
    else:
        warnings += li(d, code('vbv_bufsize'), ' can not be determined. Assuming a value lower than 50,000.')

    #Check 9: analyse = 0x3:0x113
    if info['video']['Encoding settings']['analyse'] != '0x3:0x113':
        is_d = False
        errors += li(d, code('analyse'), ' must be 0x3:0x113. Got: ', info['video']['Encoding settings']['analyse'])

    #Check 10: rc = crf or 2-pass
    rc = info['video']['Encoding settings']['rc']
    if rc != 'crf' and rc != '2pass':
        is_a = False
        errors += li(a, code('rc'), ' must be CRF or 2pass. Got: ', info['video']['Encoding settings']['rc'])

    #Check 11: me_range >= 16
    if int(info['video']['Encoding settings']['me_range']) < 16:
        is_a = False
        errors += li(a, code('me_range'), ' must be greater than or equal to 16. Got: ', info['video']['Encoding settings']['me_range'])

    #Check 12: trellis = 1 or 2 or deadzone <= 10
    trellis = info['video']['Encoding settings']['trellis']
    if trellis != '1' and trellis != 2:
        deadzone = map(int, info['video']['Encoding settings']['deadzone'].split(','))
        if deadzone[0] > 10 or deadzone[1] > 10:
            is_a = False
            errors += li(a, code('trellis')+' must be 1 or 2 or ', code('deadzone'), ' values need to be less than 10. Got: ', info['video']['Encoding settings']['trellis'], ' and ', info['video']['Encoding settings']['deadzone'])

    #Check 13: bframe >= 3
    if int(info['video']['Encoding settings']['bframes']) < 3:
        is_a = False
        errors += li(a, code('bframes'), ' must be greater than or equal to 3. Got: ', info['video']['Encoding settings']['bframes'])

    deblock = int(info['video']['Encoding settings']['deblock'].split(':')[2])
    if is_animation:
        #Check 14: 0<=deblock<=2
        if deblock < 0 or deblock > 2:
            id_a = False
            errors += li(a, code('deblock'), ' must be between 0 and 2. Got: ', deblock)
    else:
        #Check 14: -3<=deblock<=-1
        if deblock < -3 or deblock > -1:
            is_a = False
            errors += li(a, code('deblock'), ' must be between -3 and -1. Got: ', deblock)

    #Check 15: me != dia or hex
    me = info['video']['Encoding settings']['me']
    if me == 'dia' or me == 'hex':
        is_a = False
        errors += li(a, code('me'), ' must not be "dia" or "hex". Got: ', me)

    #Check 16: subme >= 7
    if int(info['video']['Encoding settings']['subme']) < 7:
        is_a = False
        errors += li(a, code('subme'), ' must be greater than or equal to 7. Got: ', info['video']['Encoding settings']['subme'])

    #AWESOME!
    return (is_a and is_d, is_d, errors, warnings)

#Output types
XHTML = 0
JSON  = 1

#URL mapping
urls = (
    (r'^/$', XHTML),
    (r'^/json/?$', JSON),
)

#Determine output format
output = XHTML
for regex, url_output in urls:
    if re.match(regex, web.env['REQUEST_URI']):
        output = url_output
        break

#Parse POSTed data (if any)
is_post = 'mediainfo' in web.post
if is_post:
    try:
        (is_a, is_d, errors, warnings) = is_awesome(web.post['mediainfo'], 'is_animation' in web.post)
    except (ValueError, KeyError), e:
        is_a = is_d = False
        errors = ul(li(strong('Fatal %s: ' % e.__type__.__name__), str(e)))
        warnings = ul()

if output == JSON:
    print 'Content-type: application/json'
    print
    if not is_post:
        is_a = is_d = False
        errors = ul(li(strong('Fatal Error: '), 'No MediaInfo text POSTed.'))
        warnings = ul()
    print '{"dxva": %s, "awesome": %s, "error_count": %s, "errors": "%s", "warning_count": %s, "warnings": "%s"}' % (is_d and 'true' or 'false', is_a and 'true' or 'false', len(errors.children), str(errors), len(warnings.children), str(warnings))

elif output == XHTML:
    page = xhtmlpage('Is Awesome?')
    page.html.head += link(rel='stylesheet', type='text/css', href='is_awesome.css')

    wrapper = page.html.body.add(div(id='wrapper'))
    header  = wrapper.add(div(id='header'))
    content = wrapper.add(div(id='content'))
    footer  = wrapper.add(div(id='footer'))

    header += h1(a('Is Awesome?', href='/'))
    footer += div('Designed and developed by ', a('Jake Wharton', href='http://jakewharton.com'), '. ', a('Source code', href='http://github.com/JakeWharton/is_awesome/'), '.')

    if is_post:
        dxva = div(h1('DXVA'), p('DirectX Video Acceleration (DXVA) is a Microsoft API specification for the Microsoft Windows and Xbox 360 platforms that allows video decoding to be hardware accelerated.'))
        awsm = div(h1('Awesome'), p('"Awesome" is a standard higher than DXVA. It is used to determine the highest quality encodes by certain individuals. If you are unaware of it, then you most likely do not need to concern yourself with compliance.'))

        dxva['class'] = is_d and 'good' or 'bad'
        awsm['class'] = is_a and 'good' or 'bad'
        content += dxva
        content += awsm

        if len(warnings.children) > 0:
            content += h3('Warnings')
            content += warnings

        if len(errors.children) > 0:
            content += h3('Errors')
            content += errors

        content += p(a('Try Again »', href='/'))
    else:
        content += p('The requirements for testing DXVA compliance are straight forward but tedious to check. The rules for "awesome"-ness are even more strict.')
        content += p('Paste the text output of the ', a('MediaInfo', href='http://mediainfo.sf.net'), ' program below and press "Check".')
        form = content.add(form(method='post', action=''))
        form += label('Is Animation?:', _for='is_animation')
        form += input(type='checkbox', name='is_animation')
        form += br()
        form += textarea(name='mediainfo')
        form += br()
        form += input(type='submit', name='submit', value='Check')

    #Google Analytics
    page.html += script('''
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
''', type='text/javascript')
    page.html += script('''
try {
var pageTracker = _gat._getTracker("UA-3637749-9");
pageTracker._trackPageview();
} catch(err) {}
''', type='text/javascript')

    page.render()
<commit_msg>Add XML support.<commit_after>#!/usr/bin/python vendor/pyy/cgi.py

from vendor.pyy          import web
from vendor.pyy.htmlpage import xhtmlpage
from vendor.pyy.xhtml11  import *
import re

def MediaInfo2Dict(text):
    """
    This method takes the text output from the program MediaInfo and parses it
    into a dictionary heirarchy.
    """
    import re
    rkeyval = re.compile(r'\s+:\s')
    res = {}

    for category in text.replace('\r\n', '\n').strip().split('\n\n'):
        pairs = map(str.strip, category.split('\n'))
        if pairs:
            name = pairs.pop(0).replace(' ', '_').lower()
            res[name] = dict(rkeyval.split(pair, 2) for pair in pairs)
    if 'video' in res and 'Encoding settings' in res['video']:
        res['video']['Encoding settings'] = dict(pair.split('=', 1) for pair in map(str.strip, filter(None, res['video']['Encoding settings'].split('/'))))
    return res

def is_awesome(text, is_animation):
    info = MediaInfo2Dict(text)

    is_a = True
    is_d = True
    warnings = ul()
    errors = ul()

    a = strong('Awesome: ')
    d = strong('DXVA: ')

    is_1080p = (info['video']['Width'] == '1 920 pixels')
    is_720p  = (info['video']['Width'] == '1 280 pixels')

    #Check 1: 720p/1080p
    if not is_720p and not is_1080p:
        is_a = False
        errors += li(a, 'Must be 1920 or 1280 pixels wide. Got: ', info['video']['Width'])

    #Check 2: is x264
    if info['video']['Codec ID'] != 'V_MPEG4/ISO/AVC':
        is_a = False
        errors += li(a, 'Not MPEG4/ISO/AVC (x264) codec. Got: ', info['video']['Codec ID'])

    #Check 3: DTS or AC3 track
    if 'audio' in info:
        a_codec = info['audio']['Format']
        if not a_codec == 'DTS' and not a_codec == 'AC3':
            is_a = False
            errors += li(a, 'Audio track not DTS or AC3. Got: ', info['audio']['Format'])
    elif 'audio_#1' in info:
        a_codec = info['audio_#1']['Format']
        if not a_codec == 'DTS' and not a_codec == 'AC3':
            is_a = False
            errors += li(a, 'Audio track not DTS or AC3. Got: ', info['audio_#1']['Format'])
    else:
        is_a = False
        errors += li(a, 'No audio tracks.')

    #Check 4: English subtitles
    if 'text' in info:
        if info['text']['Language'] != 'English':
            is_a = False
            errors += li(a, 'Subtitle track not English. Got: ', info['text']['Language'])
    elif 'text_#1' in info:
        if info['text_#1']['Language'] != 'English':
            is_a = False
            errors += li(a, 'No English subtitles. Got: ', info['text_#1']['Language'])
    else:
        is_a = False
        errors += li('No subtitle tracks.')

    height = int(info['video']['Height'].replace('pixels', '').replace(' ', '').strip())
    ref = int(info['video']['Encoding settings']['ref'])
    if is_1080p:
        if height <= 720:
            #Check 6: 3<=ref<=6
            if ref < 3 or ref > 6:
                is_d = False
                errors += li(d, 'Reference frames not between 3 and 6. Got: ', ref)
        elif height <= 864:
            #Check 6: 3<=ref<=5
            if ref < 3 or ref > 5:
                is_d = False
                errors += li(d, 'Reference frames not between 3 and 5. Got: ', ref)
        else:
            #Check 6: 3<=ref<=4
            if ref < 3 or ref > 4:
                is_d = False
                errors += li(d, 'Reference frames not between 3 and 4. Got: ', ref)
    else:
        if height <= 540:
            #Check 6: 5<=ref<=12
            if ref < 5 or ref > 12:
                is_d = False
                errors += li(d, 'Reference frames not between 5 and 12. Got: ', ref)
        elif height <= 588:
            #Check 6: 5<=ref<=11
            if ref < 5 or ref > 11:
                is_d = False
                errors += li(d, 'Reference frames not between 5 and 11. Got: ', ref)
        elif height <= 648:
            #Check 6: 5<=ref<=10
            if ref < 5 or ref > 10:
                is_d = False
                errors += li(d, 'Reference frames not between 5 and 10. Got: ', ref)
        else:
            #Check 6: 5<=ref<=9
            if ref < 5 or ref > 9:
                is_d = False
                errors += li(d, 'Reference frames not between 5 and 9. Got: ', ref)

    #Check 5: cabac = 1
    if info['video']['Encoding settings']['cabac'] != '1':
        is_a = False
        errors += li(a, code('cabac'), ' must be 1. Got: ', info['video']['Encoding settings']['cabac'])

    #Check 7: vbv_maxrate <= 50000
    if 'vbv_maxrate' in info['video']['Encoding settings']:
        if int(info['video']['Encoding settings']['vbv_maxrate']) > 50000:
            is_d = False
            errors += li(d, code('vbv_maxrate'), ' must be less than or equal to 50,000. Got: ', info['video']['Encoding settings']['vbv_maxrate'])
    else:
        warnings += li(code('vbv_maxrate'), ' can not be determined. Assuming a value lower than 50,000.')

    #Check 8: vbv_bufsize <= 50000
    if 'vbv_bufsize' in info['video']['Encoding settings']:
        if int(info['video']['Encoding settings']['vbv_bufsize']) > 50000:
            is_d = False
            errors += li(d, code('vbv_bufsize'), ' must be less than or equal to 50,000.', info['video']['Encoding settings']['vbv_bufsize'])
    else:
        warnings += li(d, code('vbv_bufsize'), ' can not be determined. Assuming a value lower than 50,000.')

    #Check 9: analyse = 0x3:0x113
    if info['video']['Encoding settings']['analyse'] != '0x3:0x113':
        is_d = False
        errors += li(d, code('analyse'), ' must be 0x3:0x113. Got: ', info['video']['Encoding settings']['analyse'])

    #Check 10: rc = crf or 2-pass
    rc = info['video']['Encoding settings']['rc']
    if rc != 'crf' and rc != '2pass':
        is_a = False
        errors += li(a, code('rc'), ' must be CRF or 2pass. Got: ', info['video']['Encoding settings']['rc'])

    #Check 11: me_range >= 16
    if int(info['video']['Encoding settings']['me_range']) < 16:
        is_a = False
        errors += li(a, code('me_range'), ' must be greater than or equal to 16. Got: ', info['video']['Encoding settings']['me_range'])

    #Check 12: trellis = 1 or 2 or deadzone <= 10
    trellis = info['video']['Encoding settings']['trellis']
    if trellis != '1' and trellis != 2:
        deadzone = map(int, info['video']['Encoding settings']['deadzone'].split(','))
        if deadzone[0] > 10 or deadzone[1] > 10:
            is_a = False
            errors += li(a, code('trellis')+' must be 1 or 2 or ', code('deadzone'), ' values need to be less than 10. Got: ', info['video']['Encoding settings']['trellis'], ' and ', info['video']['Encoding settings']['deadzone'])

    #Check 13: bframe >= 3
    if int(info['video']['Encoding settings']['bframes']) < 3:
        is_a = False
        errors += li(a, code('bframes'), ' must be greater than or equal to 3. Got: ', info['video']['Encoding settings']['bframes'])

    deblock = int(info['video']['Encoding settings']['deblock'].split(':')[2])
    if is_animation:
        #Check 14: 0<=deblock<=2
        if deblock < 0 or deblock > 2:
            id_a = False
            errors += li(a, code('deblock'), ' must be between 0 and 2. Got: ', deblock)
    else:
        #Check 14: -3<=deblock<=-1
        if deblock < -3 or deblock > -1:
            is_a = False
            errors += li(a, code('deblock'), ' must be between -3 and -1. Got: ', deblock)

    #Check 15: me != dia or hex
    me = info['video']['Encoding settings']['me']
    if me == 'dia' or me == 'hex':
        is_a = False
        errors += li(a, code('me'), ' must not be "dia" or "hex". Got: ', me)

    #Check 16: subme >= 7
    if int(info['video']['Encoding settings']['subme']) < 7:
        is_a = False
        errors += li(a, code('subme'), ' must be greater than or equal to 7. Got: ', info['video']['Encoding settings']['subme'])

    #AWESOME!
    return (is_a and is_d, is_d, errors, warnings)

#Output types
XHTML = 0
JSON  = 1
XML = 2

#URL mapping
urls = (
    (r'^/$', XHTML),
    (r'^/json/$', JSON),
    (r'^/xml/$', XML),
)

#Determine output format
output = XHTML
for regex, url_output in urls:
    if re.match(regex, web.env['REQUEST_URI']):
        output = url_output
        break

#Parse POSTed data (if any)
is_post = 'mediainfo' in web.post
if is_post:
    try:
        (is_a, is_d, errors, warnings) = is_awesome(web.post['mediainfo'], 'is_animation' in web.post and web.post['is_animation'])
    except (ValueError, KeyError), e:
        is_a = is_d = False
        errors = ul(li(strong('Fatal %s: ' % e.__type__.__name__), str(e)))
        warnings = ul()
else:
    is_a = is_d = False
    errors = ul(li(strong('Fatal Error: '), 'No MediaInfo text POSTed.'))
    warnings = ul()

#Output in specified format
if output == JSON:
    print 'Content-type: application/json'
    print
    print '{"dxva": %s, "awesome": %s, "error_count": %s, "errors": "%s", "warning_count": %s, "warnings": "%s"}' % (is_d and 'true' or 'false', is_a and 'true' or 'false', len(errors.children), str(errors), len(warnings.children), str(warnings))

elif output == XML:
    print 'Content-type: application/xml'
    print
    print '<?xml version="1.0" encoding="UTF-8"?>'
    print '<compliant>'
    print '<dxva>%s</dxva>' % is_d and 'true' or 'false'
    print '\t<awesome>%s</awesome>' % is_a and 'true' or 'false'
    print '\t<errors count="%s">%s\n\t</errors>' % (len(errors.children), errors.render_children(2, True))
    print '\t<warnings count="%s">%s\n\t</warnings>' % (len(warnings.children), warnings.render_children(2, True))
    print '</compliant>'

elif output == XHTML:
    page = xhtmlpage('Is Awesome?')
    page.html.head += link(rel='stylesheet', type='text/css', href='is_awesome.css')

    wrapper = page.html.body.add(div(id='wrapper'))
    header  = wrapper.add(div(id='header'))
    content = wrapper.add(div(id='content'))
    footer  = wrapper.add(div(id='footer'))

    header += h1(a('Is Awesome?', href='/'))
    footer += div('Designed and developed by ', a('Jake Wharton', href='http://jakewharton.com'), '. ', a('Source code', href='http://github.com/JakeWharton/is_awesome/'), '.')

    if is_post:
        dxva = div(h1('DXVA'), p('DirectX Video Acceleration (DXVA) is a Microsoft API specification for the Microsoft Windows and Xbox 360 platforms that allows video decoding to be hardware accelerated.'))
        awsm = div(h1('Awesome'), p('"Awesome" is a standard higher than DXVA. It is used to determine the highest quality encodes by certain individuals. If you are unaware of it, then you most likely do not need to concern yourself with compliance.'))

        dxva['class'] = is_d and 'good' or 'bad'
        awsm['class'] = is_a and 'good' or 'bad'
        content += dxva
        content += awsm

        if len(warnings.children) > 0:
            content += h3('Warnings')
            content += warnings

        if len(errors.children) > 0:
            content += h3('Errors')
            content += errors

        content += p(a('Try Again »', href='/'))
    else:
        content += p('The requirements for testing DXVA compliance are straight forward but tedious to check. The rules for "awesome"-ness are even more strict.')
        content += p('Paste the text output of the ', a('MediaInfo', href='http://mediainfo.sf.net'), ' program below and press "Check".')
        form = content.add(form(method='post', action=''))
        form += label('Is Animation?:', _for='is_animation')
        form += input(type='checkbox', name='is_animation')
        form += br()
        form += textarea(name='mediainfo')
        form += br()
        form += input(type='submit', name='submit', value='Check')

    #Google Analytics
    page.html += script('''
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
''', type='text/javascript')
    page.html += script('''
try {
var pageTracker = _gat._getTracker("UA-3637749-9");
pageTracker._trackPageview();
} catch(err) {}
''', type='text/javascript')

    page.render()
<|endoftext|>


<commit_before><commit_msg>Revert "Replace test_shell_tests dependency on the test_shell with test_shell_pak dependency."<commit_after><|endoftext|>


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

# Copyright(C) 2010-2011  Christophe Benz
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 3 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

import sys

from weboob.core import CallErrors
from weboob.capabilities.messages import ICapMessages, Message, Thread
from weboob.capabilities.account import ICapAccount
from weboob.tools.application.repl import ReplApplication
from weboob.tools.application.formatters.iformatter import IFormatter
from weboob.tools.misc import html2text

__all__ = ['Boobmsg']

class MessageFormatter(IFormatter):
    def flush(self):
        pass

    def format_dict(self, item):
        result = u'%sTitle:%s %s\n' % (self.BOLD,
                                       self.NC, item['title'])
        result += u'%sDate:%s %s\n' % (self.BOLD,
                                       self.NC, item['date'])
        result += u'%sFrom:%s %s\n' % (self.BOLD,
                                       self.NC, item['sender'])
        if item['receivers']:
            result += u'%sTo:%s %s\n' % (self.BOLD,
                                         self.NC,
                                         ', '.join(item['receivers']))

        if item['flags'] & Message.IS_HTML:
            content = html2text(item['content'])
        else:
            content = item['content']

        result += '\n%s' % content
        return result

class MessagesListFormatter(IFormatter):
    MANDATORY_FIELDS = ()
    count = 0
    _list_messages = False

    def flush(self):
        self.count = 0

    def format_dict(self, item):
        if not self._list_messages:
            return self.format_dict_thread(item)
        else:
            return self.format_dict_messages(item)

    def format_dict_thread(self, item):
        self.count += 1
        if item['nb_unread'] and item['nb_unread'] > 0:
            unread = '[N]'
        else:
            unread = '   '
        if self.interactive:
            backend = item['id'].split('@', 1)[1]
            result = u'%s* (%d) %s %s (%s)%s' % (self.BOLD,
                                                 self.count, unread,
                                                 item['title'], backend,
                                                 self.NC)
        else:
            result = u'%s* (%s) %s %s%s' % (self.BOLD, item['id'],
                                            unread, item['title'],
                                            self.NC)
        if item['date']:
            result += u'\n             %s' % item['date']
        return result

    def format_dict_messages(self, item):
        backend = item['id'].split('@', 1)[1]
        if item['flags'] == Thread.IS_THREADS:
            depth = 0
        else:
            depth = -1

        result = self.format_message(backend, item['root'], depth)
        return result

    def format_message(self, backend, message, depth=0):
        if not message:
            return u''
        self.count += 1

        flags = '['
        if message.flags & message.IS_UNREAD:
            flags += 'N'
        else:
            flags += '-'
        if message.flags & message.IS_NOT_ACCUSED:
            flags += 'U'
        elif message.flags & message.IS_ACCUSED:
            flags += 'R'
        else:
            flags += '-'
        flags += ']'

        if self.interactive:
            result = u'%s%s* (%d)%s %s <%s> %s (%s)\n' % (depth * '  ',
                                                          self.BOLD,
                                                          self.count,
                                                          self.NC,
                                                          flags,
                                                          message.sender,
                                                          message.title,
                                                          backend)
        else:
            result = u'%s%s* (%s.%s@%s)%s %s <%s> %s\n' % (depth * '  ',
                                                           self.BOLD,
                                                           message.thread.id,
                                                           message.id,
                                                           backend,
                                                           flags,
                                                           self.NC,
                                                           message.sender,
                                                           message.title)
        if message.children:
            if depth >= 0:
                depth += 1
            for m in message.children:
                result += self.format_message(backend, m, depth)
        return result

class Boobmsg(ReplApplication):
    APPNAME = 'boobmsg'
    VERSION = '0.7'
    COPYRIGHT = 'Copyright(C) 2010-2011 Christophe Benz'
    DESCRIPTION = "Boobmsg is a console application to send messages on " \
                  "supported websites and " \
                  "to display messages threads and contents."
    CAPS = ICapMessages
    EXTRA_FORMATTERS = {'msglist': MessagesListFormatter,
                        'msg':     MessageFormatter,
                       }
    COMMANDS_FORMATTERS = {'list':      'msglist',
                           'show':      'msg',
                           'export_thread': 'msg',
                           'export_all': 'msg'
                          }

    def add_application_options(self, group):
        group.add_option('-e', '--skip-empty',  action='store_true',
                         help='Don\'t send messages with an empty body.')
        group.add_option('-t', '--title', action='store',
                         help='For the "post" command, set a title to message',
                         type='string', dest='title')

    def load_default_backends(self):
        self.load_backends(ICapMessages, storage=self.create_storage())

    def do_status(self, line):
        """
        status

        Display status information about a backend.
        """
        if len(line) > 0:
            backend_name = line
        else:
            backend_name = None

        results = {}
        for backend, field in self.do('get_account_status',
                                      backends=backend_name,
                                      caps=ICapAccount):
            if backend.name in results:
                results[backend.name].append(field)
            else:
                results[backend.name] = [field]

        for name, fields in results.iteritems():
            print ':: %s ::' % name
            for f in fields:
                if f.flags & f.FIELD_HTML:
                    value = html2text(f.value)
                else:
                    value = f.value
                print '%s: %s' % (f.label, value)
            print ''

    def do_post(self, line):
        """
        post RECEIVER@BACKEND[,RECEIVER@BACKEND[...]] [TEXT]

        Post a message to the specified receivers.
        Multiple receivers are separated by a comma.

        If no text is supplied on command line, the content of message is read on stdin.
        """
        receivers, text = self.parse_command_args(line, 2, 1)
        if text is None:
            if self.interactive:
                print 'Reading message content from stdin... Type ctrl-D ' \
                      'from an empty line to post message.'
            text = sys.stdin.read()
            if sys.stdin.encoding:
                text = text.decode(sys.stdin.encoding)

        if self.options.skip_empty and not text.strip():
            return

        for receiver in receivers.strip().split(','):
            receiver, backend_name = self.parse_id(receiver.strip(),
                                                   unique_backend=True)
            if not backend_name and len(self.enabled_backends) > 1:
                self.logger.warning(u'No backend specified for receiver "%s": message will be sent with all the '
                    'enabled backends (%s)' % (receiver,
                    ','.join(backend.name for backend in self.enabled_backends)))

            if '.' in receiver:
                # It's a reply
                thread_id, parent_id = receiver.rsplit('.', 1)
            else:
                # It's an original message
                thread_id = receiver
                parent_id = None

            thread = Thread(thread_id)
            message = Message(thread,
                              0,
                              title=self.options.title,
                              parent=Message(thread, parent_id) if parent_id else None,
                              content=text)

            try:
                self.do('post_message', message, backends=backend_name).wait()
            except CallErrors, errors:
                self.bcall_errors_handler(errors)
            else:
                if self.interactive:
                    print 'Message sent sucessfully to %s' % receiver

    threads = []
    messages = []

    def do_list(self, arg):
        """
        list

        Display all threads.
        """
        if len(arg) > 0:
            try:
                thread = self.threads[int(arg) - 1]
            except (IndexError, ValueError):
                id, backend_name = self.parse_id(arg)
            else:
                id = thread.id
                backend_name = thread.backend

            self.messages = []
            cmd = self.do('get_thread', id, backends=backend_name)
            self.formatter._list_messages = True
        else:
            self.threads = []
            cmd = self.do('iter_threads')
            self.formatter._list_messages = False

        for backend, thread in cmd:
            if len(arg) > 0:
                for m in thread.iter_all_messages():
                    if not m.backend:
                        m.backend = thread.backend
                    self.messages.append(m)
            else:
                self.threads.append(thread)
            self.format(thread)
        self.flush()

    def do_export_all(self, arg):
        """
        export_all

        Export All threads
        """

        cmd = self.do('iter_threads')
        for backend, thread in cmd:
            t  = backend.get_thread(thread.id)
            for msg in t.iter_all_messages():
                self.format(msg)

    def do_export_thread(self, arg):
        """
        export_thread

        Export a thread
        """
        _id, backend_name = self.parse_id(arg)
        cmd = self.do('get_thread', _id, backends=backend_name)
        for backend, thread in cmd:
            if thread is not None :
                for msg in thread.iter_all_messages():
                    self.format(msg)

    def do_show(self, arg):
        """
        show MESSAGE

        Read a message
        """
        if len(arg) == 0:
            print 'Please give a message ID.'
            return

        try:
            message = self.messages[int(arg) - 1]
        except (IndexError, ValueError):
            id, backend_name = self.parse_id(arg)
        else:
            self.format(message)
            self.weboob.do('set_message_read', message, backends=message.backend)
            return

        if not self.interactive:
            print 'Oops, you need to be in interactive mode to read messages'
        else:
            print 'Message not found'
<commit_msg>new xhtml formatter<commit_after># -*- coding: utf-8 -*-

# Copyright(C) 2010-2011  Christophe Benz
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 3 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

import sys

from weboob.core import CallErrors
from weboob.capabilities.messages import ICapMessages, Message, Thread
from weboob.capabilities.account import ICapAccount
from weboob.tools.application.repl import ReplApplication
from weboob.tools.application.formatters.iformatter import IFormatter
from weboob.tools.misc import html2text

__all__ = ['Boobmsg']

class XHtmlFormatter(IFormatter):
    def flush(self):
        pass

    def format_dict(self, item):
        result  = "
\n"
        result += "
%s
" % (item['title'])
        result += "
"
        result += "
Date

%s
" % (item['date'])
        result += "
Sender

%s
" % (item['sender'])
        result += "
Signature

%s
" % (item['signature'])
        result += "
"
        result += "
%s
" % (item['content'])
        result += "
\n"
        return result

class MessageFormatter(IFormatter):
    def flush(self):
        pass

    def format_dict(self, item):
        result = u'%sTitle:%s %s\n' % (self.BOLD,
                                       self.NC, item['title'])
        result += u'%sDate:%s %s\n' % (self.BOLD,
                                       self.NC, item['date'])
        result += u'%sFrom:%s %s\n' % (self.BOLD,
                                       self.NC, item['sender'])
        if item['receivers']:
            result += u'%sTo:%s %s\n' % (self.BOLD,
                                         self.NC,
                                         ', '.join(item['receivers']))

        if item['flags'] & Message.IS_HTML:
            content = html2text(item['content'])
        else:
            content = item['content']

        result += '\n%s' % content
        return result

class MessagesListFormatter(IFormatter):
    MANDATORY_FIELDS = ()
    count = 0
    _list_messages = False

    def flush(self):
        self.count = 0

    def format_dict(self, item):
        if not self._list_messages:
            return self.format_dict_thread(item)
        else:
            return self.format_dict_messages(item)

    def format_dict_thread(self, item):
        self.count += 1
        if item['nb_unread'] and item['nb_unread'] > 0:
            unread = '[N]'
        else:
            unread = '   '
        if self.interactive:
            backend = item['id'].split('@', 1)[1]
            result = u'%s* (%d) %s %s (%s)%s' % (self.BOLD,
                                                 self.count, unread,
                                                 item['title'], backend,
                                                 self.NC)
        else:
            result = u'%s* (%s) %s %s%s' % (self.BOLD, item['id'],
                                            unread, item['title'],
                                            self.NC)
        if item['date']:
            result += u'\n             %s' % item['date']
        return result

    def format_dict_messages(self, item):
        backend = item['id'].split('@', 1)[1]
        if item['flags'] == Thread.IS_THREADS:
            depth = 0
        else:
            depth = -1

        result = self.format_message(backend, item['root'], depth)
        return result

    def format_message(self, backend, message, depth=0):
        if not message:
            return u''
        self.count += 1

        flags = '['
        if message.flags & message.IS_UNREAD:
            flags += 'N'
        else:
            flags += '-'
        if message.flags & message.IS_NOT_ACCUSED:
            flags += 'U'
        elif message.flags & message.IS_ACCUSED:
            flags += 'R'
        else:
            flags += '-'
        flags += ']'

        if self.interactive:
            result = u'%s%s* (%d)%s %s <%s> %s (%s)\n' % (depth * '  ',
                                                          self.BOLD,
                                                          self.count,
                                                          self.NC,
                                                          flags,
                                                          message.sender,
                                                          message.title,
                                                          backend)
        else:
            result = u'%s%s* (%s.%s@%s)%s %s <%s> %s\n' % (depth * '  ',
                                                           self.BOLD,
                                                           message.thread.id,
                                                           message.id,
                                                           backend,
                                                           flags,
                                                           self.NC,
                                                           message.sender,
                                                           message.title)
        if message.children:
            if depth >= 0:
                depth += 1
            for m in message.children:
                result += self.format_message(backend, m, depth)
        return result

class Boobmsg(ReplApplication):
    APPNAME = 'boobmsg'
    VERSION = '0.7'
    COPYRIGHT = 'Copyright(C) 2010-2011 Christophe Benz'
    DESCRIPTION = "Boobmsg is a console application to send messages on " \
                  "supported websites and " \
                  "to display messages threads and contents."
    CAPS = ICapMessages
    EXTRA_FORMATTERS = {'msglist': MessagesListFormatter,
                        'msg':     MessageFormatter,
                        'xhtml':     XHtmlFormatter,
                       }
    COMMANDS_FORMATTERS = {'list':      'msglist',
                           'show':      'msg',
                           'export_thread': 'msg',
                           'export_all': 'msg'
                          }

    def add_application_options(self, group):
        group.add_option('-e', '--skip-empty',  action='store_true',
                         help='Don\'t send messages with an empty body.')
        group.add_option('-t', '--title', action='store',
                         help='For the "post" command, set a title to message',
                         type='string', dest='title')

    def load_default_backends(self):
        self.load_backends(ICapMessages, storage=self.create_storage())

    def do_status(self, line):
        """
        status

        Display status information about a backend.
        """
        if len(line) > 0:
            backend_name = line
        else:
            backend_name = None

        results = {}
        for backend, field in self.do('get_account_status',
                                      backends=backend_name,
                                      caps=ICapAccount):
            if backend.name in results:
                results[backend.name].append(field)
            else:
                results[backend.name] = [field]

        for name, fields in results.iteritems():
            print ':: %s ::' % name
            for f in fields:
                if f.flags & f.FIELD_HTML:
                    value = html2text(f.value)
                else:
                    value = f.value
                print '%s: %s' % (f.label, value)
            print ''

    def do_post(self, line):
        """
        post RECEIVER@BACKEND[,RECEIVER@BACKEND[...]] [TEXT]

        Post a message to the specified receivers.
        Multiple receivers are separated by a comma.

        If no text is supplied on command line, the content of message is read on stdin.
        """
        receivers, text = self.parse_command_args(line, 2, 1)
        if text is None:
            if self.interactive:
                print 'Reading message content from stdin... Type ctrl-D ' \
                      'from an empty line to post message.'
            text = sys.stdin.read()
            if sys.stdin.encoding:
                text = text.decode(sys.stdin.encoding)

        if self.options.skip_empty and not text.strip():
            return

        for receiver in receivers.strip().split(','):
            receiver, backend_name = self.parse_id(receiver.strip(),
                                                   unique_backend=True)
            if not backend_name and len(self.enabled_backends) > 1:
                self.logger.warning(u'No backend specified for receiver "%s": message will be sent with all the '
                    'enabled backends (%s)' % (receiver,
                    ','.join(backend.name for backend in self.enabled_backends)))

            if '.' in receiver:
                # It's a reply
                thread_id, parent_id = receiver.rsplit('.', 1)
            else:
                # It's an original message
                thread_id = receiver
                parent_id = None

            thread = Thread(thread_id)
            message = Message(thread,
                              0,
                              title=self.options.title,
                              parent=Message(thread, parent_id) if parent_id else None,
                              content=text)

            try:
                self.do('post_message', message, backends=backend_name).wait()
            except CallErrors, errors:
                self.bcall_errors_handler(errors)
            else:
                if self.interactive:
                    print 'Message sent sucessfully to %s' % receiver

    threads = []
    messages = []

    def do_list(self, arg):
        """
        list

        Display all threads.
        """
        if len(arg) > 0:
            try:
                thread = self.threads[int(arg) - 1]
            except (IndexError, ValueError):
                id, backend_name = self.parse_id(arg)
            else:
                id = thread.id
                backend_name = thread.backend

            self.messages = []
            cmd = self.do('get_thread', id, backends=backend_name)
            self.formatter._list_messages = True
        else:
            self.threads = []
            cmd = self.do('iter_threads')
            self.formatter._list_messages = False

        for backend, thread in cmd:
            if len(arg) > 0:
                for m in thread.iter_all_messages():
                    if not m.backend:
                        m.backend = thread.backend
                    self.messages.append(m)
            else:
                self.threads.append(thread)
            self.format(thread)
        self.flush()

    def do_export_all(self, arg):
        """
        export_all

        Export All threads
        """

        cmd = self.do('iter_threads')
        for backend, thread in cmd:
            t  = backend.get_thread(thread.id)
            for msg in t.iter_all_messages():
                self.format(msg)

    def do_export_thread(self, arg):
        """
        export_thread

        Export a thread
        """
        _id, backend_name = self.parse_id(arg)
        cmd = self.do('get_thread', _id, backends=backend_name)
        for backend, thread in cmd:
            if thread is not None :
                for msg in thread.iter_all_messages():
                    self.format(msg)

    def do_show(self, arg):
        """
        show MESSAGE

        Read a message
        """
        if len(arg) == 0:
            print 'Please give a message ID.'
            return

        try:
            message = self.messages[int(arg) - 1]
        except (IndexError, ValueError):
            id, backend_name = self.parse_id(arg)
        else:
            self.format(message)
            self.weboob.do('set_message_read', message, backends=message.backend)
            return

        if not self.interactive:
            print 'Oops, you need to be in interactive mode to read messages'
        else:
            print 'Message not found'
<|endoftext|>


<commit_before>#!/usr/bin/env python
import re
from PIL import Image

class Rectangle:
    def __init__(self, width, height, x=0, y=0):
        self.width = width
        self.height = height
        self.x = x
        self.y = y

    @property
    def size(self):
        return self.width, self.height

    @property
    def position(self):
        return self.x, self.y

    @property
    def box(self):
        return self.x, self.y, self.x + self.width, self.y + self.height

    def __and__(self, other):
        """Returns the Rectangle for the area where this and another
        Rectangle overlap.

        :param other: the other Rectangle
        :return: the Rectangle of the overlapping area
        """
        if type(self) != type(other):
            raise TypeError("unsupported operand type(s) for &: "
                            f"'{type(self).__name__}' "
                            f"and '{type(other).__name__}'")
        x = max(self.x, other.x)
        y = max(self.y, other.y)
        width = max(min(self.x + self.width, other.x + other.width) - x, 0)
        height = max(min(self.y + self.height, other.y + other.height) - y, 0)
        return type(self)(width, height, x, y)

    def __or__(self, other):
        """Returns the minimal Rectangle containing both,
        this and another Rectangle

        :param other: the other Rectangle
        :return: the surrounding Rectangle
        """
        if type(self) != type(other):
            raise TypeError("unsupported operand type(s) for |: "
                            f"'{type(self).__name__}' "
                            f"and '{type(other).__name__}'")
        x = min(self.x, other.x)
        y = min(self.y, other.y)
        width = max(self.x + self.width, other.x + other.width) - x
        height = max(self.y + self.height, other.y + other.height) - y
        return type(self)(width, height, x, y)

    def __bool__(self):
        return bool(self.width and self.height)

    def __repr__(self):
        return (f"{type(self).__name__}("
                f"width={self.width}, height={self.height}, "
                f"x={self.x}, y={self.y})")

    def __round__(self, n=None):
        return type(self)(
            round(self.width, n),
            round(self.height, n),
            round(self.x, n),
            round(self.y, n))

class PhysicalRectangle(Rectangle):
    pass

class ScreenRectangle(Rectangle):
    @classmethod
    def from_geometry_string(cls, string):
        geometry = re.match('(\d+)x(\d+)\+(\d+)\+(\d+)', string).groups()
        return cls(*[int(v) for v in geometry])

    def __str__(self):
        return f"{self.width}x{self.height}+{self.x}+{self.y}"

class Viewport:
    def __init__(self, physical, screen, scale=1.0):
        self.physical = physical
        self.screen = screen
        self.scale = scale

    @property
    def dpi(self):
        # for the moment assume square pixels and measurements in mm
        return self.screen.width / self.physical.width * 25.4

    def scale_to(self, viewport):
        self.scale = self.dpi / viewport.dpi

# class VPImage(Image):
#     def __init__(self, rectangle=None, **kwargs):
#         if rectangle is not None:
#             if any(kwargs.get(key, None) is not None
#                    for key in ["width", "height"]):
#                 raise TypeError(
#                     "rectangle is mutually exclusive to width or height")
#             super().__init__(width=rectangle.width, height=rectangle.height,
#                              **kwargs)
#         else:
#             super().__init__(**kwargs)
#
#     def rcomposite(self, image, rectangle):
#         self.composite(image, rectangle.x, rectangle.y)

def dummy_tester():
    with Image.open('sample.png') as orig:
        with Image.new('RGB', (640, 360), color='gray') as img:
            with orig.crop((100, 100, 150, 150)) as a:
                img.paste(a, (30, 70))
            with orig.crop((100, 100, 200, 200)) as b:
                b.resize((50, 50))
                img.paste(b, (300, 70))
            with orig.crop((10, 30, 210, 230)) as c:
                img.paste(c, (round(200 * .75), round(200 * .75)))
            img.show()

# def overlap_tester():
#     import itertools
#     bigrect = ScreenRectangle(1000, 1000)
#     redrect = ScreenRectangle(300, 300, 350, 350)
#     for w, h in itertools.combinations_with_replacement([50, 250, 500], 2):
#         for x, y in itertools.combinations_with_replacement([50, 400, 700], 2):
#             greenrect = ScreenRectangle(w, h, x, y)
#             outerrect = redrect | greenrect
#             innerrect = redrect & greenrect
#             with VPImage(rectangle=bigrect, background=Color("gray")) as img:
#                 if outerrect:
#                     with VPImage(rectangle=outerrect,
#                                  background=Color("#7f7f00")) as n:
#                         img.rcomposite(n, outerrect)
#                 if innerrect:
#                     with VPImage(rectangle=innerrect,
#                                  background=Color("#0000ff")) as n:
#                         img.rcomposite(n, innerrect)
#                 display(img)
#                 with VPImage(rectangle=redrect,
#                              background=Color("#ff00007f")) as m:
#                     img.rcomposite(m, redrect)
#                 with VPImage(rectangle=greenrect,
#                              background=Color("#00ff007f")) as n:
#                     img.rcomposite(n, greenrect)
#                 display(img)
#
#
# sampleLayout = {
#     "Left":
#         Viewport(PhysicalRectangle(518, 324, 0, 86.4),
#                  ScreenRectangle.from_geometry_string('1920x1200+0+320')),
#     "Middle":
#         Viewport(PhysicalRectangle(518, 324, 538, 0),
#                  ScreenRectangle.from_geometry_string('1920x1200+1920+0')),
#     "Right":
#         Viewport(PhysicalRectangle(475, 267, 1096, 28.5),
#                  ScreenRectangle.from_geometry_string('1920x1080+3840+60')),
#     "Laptop":
#         Viewport(PhysicalRectangle(346, 194, 624, 384),
#                  ScreenRectangle.from_geometry_string('1920x1080+1920+1200')),
# }
#
#
# def show_layout(layout):
#     from functools import reduce
#     import operator
#
#     scrv = reduce(operator.or_, [layout[k].screen for k in layout])
#     phyv = reduce(operator.or_, [layout[k].physical for k in layout])
#
#     with VPImage(rectangle=scrv, background=Color("gray")) as img:
#         for p in [round(layout[k].screen) for k in layout]:
#             with VPImage(rectangle=p, background=Color("red")) as s:
#                 img.rcomposite(s, p)
#         img.transform(resize="500")
#         display(img)
#
#     with VPImage(rectangle=phyv, background=Color("gray")) as img:
#         for p in [round(layout[k].physical) for k in layout]:
#             with VPImage(rectangle=p, background=Color("red")) as s:
#                 img.rcomposite(s, p)
#         img.transform(resize="500")
#         display(img)

if __name__ == "__main__":
    dummy_tester()
<commit_msg>Specifiy rectangle by the position of its borders<commit_after>#!/usr/bin/env python
import re
from PIL import Image

class Rectangle:
    def __init__(self, left, top, right, bottom):
        self.left = left
        self.top = top
        # Do not allow "negative" rectangles, assume size 0x0 instead
        self.right = right if right > left else left
        self.bottom = bottom if bottom > top else top

    @property
    def width(self):
        return self.right - self.left

    @property
    def height(self):
        return self.bottom - self.top

    @property
    def size(self):
        return self.width, self.height

    @property
    def position(self):
        return self.left, self.top

    @property
    def box(self):
        return self.left, self.top, self.right, self.bottom

    @classmethod
    def from_size(cls, width, height):
        return cls(0, 0, width, height)

    def __and__(self, other):
        """Returns the Rectangle for the area where this and another
        Rectangle overlap.

        :param other: the other Rectangle
        :return: the Rectangle of the overlapping area
        """
        if type(self) != type(other):
            raise TypeError("unsupported operand type(s) for &: "
                            f"'{type(self).__name__}' "
                            f"and '{type(other).__name__}'")
        left = max(self.left, other.left)
        top = max(self.top, other.top)
        right = min(self.right, other.right)
        bottom = min(self.bottom, other.bottom)
        return type(self)(left, top, right, bottom)

    def __or__(self, other):
        """Returns the minimal Rectangle containing both,
        this and another Rectangle

        :param other: the other Rectangle
        :return: the surrounding Rectangle
        """
        if type(self) != type(other):
            raise TypeError("unsupported operand type(s) for |: "
                            f"'{type(self).__name__}' "
                            f"and '{type(other).__name__}'")
        left = min(self.left, other.left)
        top = min(self.top, other.top)
        right = max(self.right, other.right)
        bottom = max(self.bottom, other.bottom)
        return type(self)(left, top, right, bottom)

    def __bool__(self):
        return bool(self.width and self.height)

    def __repr__(self):
        return (f"{type(self).__name__}("
                f"left={self.left}, top={self.top}, "
                f"right={self.right}, bottom={self.bottom})")

    def __round__(self, n=None):
        return type(self)(*[round(v, n) for v in self.box])

class PhysicalRectangle(Rectangle):
    pass

class ScreenRectangle(Rectangle):
    @classmethod
    def from_geometry_string(cls, string):
        geometry = re.match(
            '(?P<width>\d+)x(?P<height>\d+)\+(?P<left>\d+)\+(?P<top>\d+)',
            string)
        left = int(geometry.group('left'))
        top = int(geometry.group('top'))
        right = left + int(geometry.group('width'))
        bottom = top + int(geometry.group('height'))
        return cls(left, top, right, bottom)

    def __str__(self):
        return f"{self.width}x{self.height}+{self.left}+{self.top}"

class Viewport:
    def __init__(self, physical, screen, scale=1.0):
        self.physical = physical
        self.screen = screen
        self.scale = scale

    @property
    def dpi(self):
        # for the moment assume square pixels and measurements in mm
        return self.screen.width / self.physical.width * 25.4

    def scale_to(self, viewport):
        self.scale = self.dpi / viewport.dpi

# class VPImage(Image):
#     def __init__(self, rectangle=None, **kwargs):
#         if rectangle is not None:
#             if any(kwargs.get(key, None) is not None
#                    for key in ["width", "height"]):
#                 raise TypeError(
#                     "rectangle is mutually exclusive to width or height")
#             super().__init__(width=rectangle.width, height=rectangle.height,
#                              **kwargs)
#         else:
#             super().__init__(**kwargs)
#
#     def rcomposite(self, image, rectangle):
#         self.composite(image, rectangle.x, rectangle.y)

def dummy_tester():
    with Image.open('sample.png') as orig:
        with Image.new('RGB', (640, 360), color='gray') as img:
            with orig.crop((100, 100, 150, 150)) as a:
                img.paste(a, (30, 70))
            with orig.crop((100, 100, 200, 200)) as b:
                b.resize((50, 50))
                img.paste(b, (300, 70))
            with orig.crop((10, 30, 210, 230)) as c:
                img.paste(c, (round(200 * .75), round(200 * .75)))
            img.show()

def overlap_tester():
    import itertools
    bigrect = ScreenRectangle(1000, 1000)
    redrect = ScreenRectangle(400, 400, 300, 300)
    for w, h in itertools.combinations_with_replacement([50, 250, 500], 2):
        for x, y in itertools.combinations_with_replacement([50, 400, 700], 2):
            greenrect = ScreenRectangle(w, h, x, y)
            outerrect = redrect | greenrect
            innerrect = redrect & greenrect
            with VPImage(rectangle=bigrect, background=Color("gray")) as img:
                if outerrect:
                    with VPImage(rectangle=outerrect,
                                 background=Color("#7f7f00")) as n:
                        img.rcomposite(n, outerrect)
                if innerrect:
                    with VPImage(rectangle=innerrect,
                                 background=Color("#0000ff")) as n:
                        img.rcomposite(n, innerrect)
                display(img)
                with VPImage(rectangle=redrect,
                             background=Color("#ff00007f")) as m:
                    img.rcomposite(m, redrect)
                with VPImage(rectangle=greenrect,
                             background=Color("#00ff007f")) as n:
                    img.rcomposite(n, greenrect)
                display(img)

#
#
# sampleLayout = {
#     "Left":
#         Viewport(PhysicalRectangle(518, 324, 0, 86.4),
#                  ScreenRectangle.from_geometry_string('1920x1200+0+320')),
#     "Middle":
#         Viewport(PhysicalRectangle(518, 324, 538, 0),
#                  ScreenRectangle.from_geometry_string('1920x1200+1920+0')),
#     "Right":
#         Viewport(PhysicalRectangle(475, 267, 1096, 28.5),
#                  ScreenRectangle.from_geometry_string('1920x1080+3840+60')),
#     "Laptop":
#         Viewport(PhysicalRectangle(346, 194, 624, 384),
#                  ScreenRectangle.from_geometry_string('1920x1080+1920+1200')),
# }
#
#
# def show_layout(layout):
#     from functools import reduce
#     import operator
#
#     scrv = reduce(operator.or_, [layout[k].screen for k in layout])
#     phyv = reduce(operator.or_, [layout[k].physical for k in layout])
#
#     with VPImage(rectangle=scrv, background=Color("gray")) as img:
#         for p in [round(layout[k].screen) for k in layout]:
#             with VPImage(rectangle=p, background=Color("red")) as s:
#                 img.rcomposite(s, p)
#         img.transform(resize="500")
#         display(img)
#
#     with VPImage(rectangle=phyv, background=Color("gray")) as img:
#         for p in [round(layout[k].physical) for k in layout]:
#             with VPImage(rectangle=p, background=Color("red")) as s:
#                 img.rcomposite(s, p)
#         img.transform(resize="500")
#         display(img)

if __name__ == "__main__":
    dummy_tester()
<|endoftext|>