<commit_before># mk_mlt.py
# Makes a .mlt file
# uses template.mlt which was created using ShotCut GUI NLE

import copy
import os
import xml.etree.ElementTree

from pprint import pprint

def set_text(node, prop_name, value=None):
    print(node, prop_name, value)
    p = node.find("property[@name='{}']".format(prop_name))
    if value is None:
        node.remove(p)
    else:
        if type(value)==int:
            value = "0:{}.0".format(value)
        elif type(value)==float:
            value = "0:{}".format(value)
        p.text = value

def set_attrib(node, attrib_name, value=None):
    if value is None:
        del node.attrib[attrib_name]
    else:
        if type(value)==int:
            value = "0:{}.0".format(value)
        # print(attrib_name, value)
        node.set(attrib_name, value)

def parse_mlt(mlt_file):

    print(mlt_file)

    tree = xml.etree.ElementTree.parse(mlt_file)
    return tree

def grab_nodes(tree, node_names):

    nodes={}
    for id in node_names:
        if id == "spacer":
            # special case because Shotcut steps on the id='spacer'
            # <playlist id="playlist1">
            # <blank id="spacer" length="00:00:00.267"/>
            nodes['spacer'] = tree.find("./playlist[@id='playlist1']blank")
        else:
            node = tree.find(".//*[@id='{}']".format(id))
            # print(id,node)
            nodes[id] = node

    return nodes

def trim_tree(tree, playlist_id):

    mlt = tree.find('.')

    branch = tree.find("./playlist[@id='{}']".format(playlist_id))
    for twig in branch.findall("./entry[@sample]"):
        producer = twig.get('producer')
        producer_node = tree.find("./producer[@id='{}']".format(producer))
        print( producer )
        branch.remove(twig)
        mlt.remove(producer_node)

    return tree

def mk_mlt(template, output, params):

    # parse the template
    tree = parse_mlt(template)

    # grab nodes we are going to store values into
    # pl - play list
    # ti - timeline item
    node_names=[
        'pl_vid0', 'pi_vid0', # Play List and Item
        'tl_vid2', 'ti_vid2', # Time Line and Item
        'pi_title_img', 'ti_title',
        'pi_foot_img',  'ti_foot',
        'spacer',
        'audio_fade_in', 'audio_fade_out',
        'pic_in_pic', 'opacity',
        'channelcopy',
        'mono',
        'normalize',
        'volume',
        'title_fade','foot_fade',
        ]

    nodes = grab_nodes(tree, node_names)

    # remove all placeholder nodes
    tree = trim_tree(tree, 'main bin')
    tree = trim_tree(tree, 'playlist0')

    # remove the filters
    # they may be added back later
    nodes['ti_vid2'].remove(nodes['channelcopy'])
    nodes['ti_vid2'].remove(nodes['mono'])
    nodes['ti_vid2'].remove(nodes['normalize'])
    # nodes['ti_vid2'].remove(nodes['volume'])

    # add real stuff to the tree
    mlt = tree.find('.')

    # add each episode clip to the playlist
    play_list = tree.find("./playlist[@id='main bin']")
    # pprint(params['clips'])
    for i,clip in enumerate(params['clips']):

        pprint(clip)

        node_id = "pi_vid{}".format(clip['id'])
        # print("node_id",node_id)

        # setup and add Play List
        pl = copy.deepcopy( nodes['pl_vid0'] )
        pl.set("id", "pl_vid{}".format(clip['id']))
        pl.set("producer", node_id)
        set_attrib(pl, "in", clip['in'])
        set_attrib(pl, "out", clip['out'])
        play_list.insert(i,pl)

        # setup and add Playlist Item
        pi = copy.deepcopy( nodes['pi_vid0'] )
        pi.set("id", node_id)
        set_attrib(pi, "in", clip['in'])
        set_attrib(pi, "out", clip['out'])
        set_text(pi,'length')
        set_text(pi,'resource',clip['filename'])
        mlt.insert(i,pi)

    # add each cut to the timeline
    time_line = tree.find("./playlist[@id='playlist0']")
    total_length = 0
    for i,cut in enumerate(params['cuts']):
        # print(i,cut)

        node_id = "ti_vid{}".format(cut['id'])

        tl = copy.deepcopy( nodes['tl_vid2'] )
        tl.set("producer", node_id)
        set_attrib(tl, "in", cut['in'])
        set_attrib(tl, "out", cut['out'])
        time_line.insert(i,tl)

        ti = copy.deepcopy( nodes['ti_vid2'] )
        ti.set("id", node_id)
        set_attrib(ti, "in")
        set_attrib(ti, "out")
        set_text(ti,'length')
        set_text(ti,'resource',cut['filename'])
        set_text(ti,'video_delay',cut['video_delay'])

        # apply the filters to the cuts

        if cut['channelcopy']=='00':
            pass
        elif cut['channelcopy']=='m':
            ti.insert(0,nodes['mono'])
        else:
            channelcopy = copy.deepcopy( nodes['channelcopy'] )
            set_text(channelcopy,'from' , cut['channelcopy'][0])
            set_text(channelcopy,'to' , cut['channelcopy'][1])
            ti.insert(0,channelcopy)

        if cut['normalize']!='0':
            normalize = copy.deepcopy( nodes['normalize'] )
            # set_text(normalize,'program' , cut['normalize'])
            set_text(normalize, 'target_loudness' , cut['normalize'])

            ti.insert(0,normalize)

            # volume = copy.deepcopy( nodes['volume'] )
            # set_text(volume, 'gain' , cut['normalize'])
            # ti.insert(0,volume)

        if nodes['pic_in_pic'] is not None:
            # for Node 15
            ti.insert(0,nodes['pic_in_pic'])
            ti.insert(0,nodes['opacity'])

        if i==0:
            # apply audio fade in to first cut
            # ti.insert(0,nodes['audio_fade_in'])

            ti.insert(0,nodes['audio_fade_in'])

            set_attrib( nodes['audio_fade_in'], "in", cut['in'])
            out=float(cut['in'].split(':')[-1])+2
            out="0:{}".format(out)
            set_attrib( nodes['audio_fade_in'], "out", out)

        mlt.insert(i,ti)

        total_length += cut['length']
        # print( total_length )

        # print("transcription: {} - {}".format(
        #    cut['tstart'], cut['tend']))

    # ti and cut is left over from the above loop
    # put the 1.5 fadeout at the end
    # assume m:ss.s (will error if there is H:m:s)
    m,s = cut['out'].split(':')
    n=int(m)*60 + float(s)-1.5
    n="{}:{}".format(int(n/60), n%60)
    set_attrib( nodes['audio_fade_out'], "in", n)
    set_attrib( nodes['audio_fade_out'], "out", cut['out'])
    ti.insert(0,nodes['audio_fade_out'])

    # set title screen image
    set_text(nodes['pi_title_img'],'resource',params['title_img'])
    set_text(nodes['ti_title'],'resource',params['title_img'])

    # set footer image
    set_text(nodes['pi_foot_img'],'resource',params['foot_img'])
    set_text(nodes['ti_foot'],'resource',params['foot_img'])

    # set the lenght of the spacer so it puts the footer image to end-5sec
    # title_img, spacer, foot_img
    # Duration: 27mn 53s
    # nodes['ti_foot'].set("in",str(total_length))
    # nodes['spacer'].set("length","00:27:46.00")
    nodes['spacer'].set("length","0:{}.0".format(total_length-6.0))
    # nodes['spacer'].set("length","0:{}.0".format(total_length-1.0))

    # remove nodes we don't want
    # makes the code cleaner to pretend we are going to use them
    # and then remove them here.
    # import code; code.interact(local=locals())
    for node_name in node_names:
        if nodes[node_name] is not None:
            p = nodes[node_name].find("property[@name='disable']")
            if p is not None and p.text=='1':
                print(node_name)
                del nodes[node_name]

    tree.write(output)

    return True

"""
pl = tree[1]['main bin']
for pi in pl.findall("entry[@sample]"):
    print( pi.tag, pi.get('producer') )
    tree[0].remove(pi)

"""

def test():

    params = {
        'title_img': '/home/carl/Videos/veyepar/dot_net_fringe/dot_net_fringe_2015/titles/On_the_fringe_of_Nodejs_and_NET_with_Edgejs.png',
        'foot_img': 'bling/fosdem_2014_foot.png',
        'clips':[
                {'id':'123',
                'filename':'/home/carl/Videos/veyepar/dot_net_fringe/dot_net_fringe_2015/dv/main_stage/2015-04-14/09_02_51.dv',
                }
            ],
        'cuts':[{'id':'456',
                'filename':'/home/carl/Videos/veyepar/dot_net_fringe/dot_net_fringe_2015/dv/main_stage/2015-04-14/09_02_51.dv',
                'in':None,
                'out':None,
                'length':1673, # Duration: 27mn 53s
                'channelcopy':'01',
                'normalize':'-12.0',
                'video_delay':'0.0',
                },],
        }

    mk_mlt("template.mlt", "test.mlt",  params)
    return

    params = {
        'title_img': '/home/carl/Videos/veyepar/test_client/test_show/titles/Lets_make_a_Test.png',
        'foot_img': 'bling/ndv-169.png',
        'clips':[],
        'cuts':[],
        }

    for i in range(5):
        filename = "00_00_{:02}.dv".format(i*3)
        clip = {'id':str(i),
                'filename':'/home/carl/Videos/veyepar/test_client/test_show/dv/test_loc/2010-05-21/{}'.format(filename),
                'length':2,
                'in':None,
                'out':None,
                }

        if i==0:
            clip['in']=1

        params['clips'].append(clip)

        if i in [1,2,3]:
            params['cuts'].append(
               {'id':str(i),
                'filename':'/home/carl/Videos/veyepar/test_client/test_show/dv/test_loc/2010-05-21/{}'.format(filename),
                'in':None,
                'out':None,
                'length':3,
                'channelcopy':'01',
                'normalize':'-12.0',
                'video_delay':'0.0',
                })

    mk_mlt("template.mlt", "test.mlt",  params)

    return

def add_slides( base_dir, src_file, slide_dir, dst_file ):

    tree = parse_mlt(os.path.join(base_dir,src_file))

    node_names=[
        'tl_png',
        'ti_png',
        "spacer",
        ]
    nodes = grab_nodes(tree, node_names)
    print(nodes)

    # remove all placeholder (sample=) nodes
    tree = trim_tree(tree, 'main_bin')
    tree = trim_tree(tree, 'playlist2')

    # add real stuff to the tree
    mlt = tree.find('.')

    # add each png to the timeline
    slide_dir = os.path.join(base_dir,slide_dir)
    slides = os.listdir( slide_dir )
    slides.sort()

    time_line = tree.find("./playlist[@id='playlist2']")
    start_time = 5
    for i, slide in enumerate(slides):
        # print(i,slide)

        node_id = "ti_png{}".format(i)

        tl = copy.deepcopy( nodes['tl_png'] )
        tl.set("producer", node_id)
        set_attrib(tl, "in", start_time)
        set_attrib(tl, "out", start_time + 120)
        time_line.insert(i*2,tl)

        spacer = copy.deepcopy( nodes['spacer'] )
        spacer.set("length","00:01:00.0")
        time_line.insert(i*2+1,spacer)

        ti = copy.deepcopy( nodes['ti_png'] )
        ti.set("id", node_id)
        set_attrib(ti, "in")
        set_attrib(ti, "out")
        # set_text(ti,'length')
        set_text(ti,'resource', os.path.join(slide_dir, slide))
        mlt.insert(i,ti)

        start_time += 180

    tree.write(os.path.join(base_dir,dst_file))

if __name__ == '__main__':
    # test()
    add_slides( "/home/carl/mnt/gator/media/sda1/veyepar/pyohio/pyohio_2019/custom",
            "Enough_Python_to_Fake_It_start.mlt",
            "enough",
            "Enough_Python_to_Fake_It.mlt",
            )
<commit_msg>tweek add_slides so filters work.<commit_after># mk_mlt.py
# Makes a .mlt file
# uses template.mlt which was created using ShotCut GUI NLE

import copy
import os
import xml.etree.ElementTree

from pprint import pprint

def set_text(node, prop_name, value=None):
    print(node, prop_name, value)
    p = node.find("property[@name='{}']".format(prop_name))
    if value is None:
        node.remove(p)
    else:
        if type(value)==int:
            value = "0:{}.0".format(value)
        elif type(value)==float:
            value = "0:{}".format(value)
        p.text = value

def set_attrib(node, attrib_name, value=None):
    if value is None:
        del node.attrib[attrib_name]
    else:
        if type(value)==int:
            value = "0:{}.0".format(value)
        # print(attrib_name, value)
        node.set(attrib_name, value)

def parse_mlt(mlt_file):

    print(mlt_file)

    tree = xml.etree.ElementTree.parse(mlt_file)
    return tree

def grab_nodes(tree, node_names):

    nodes={}
    for id in node_names:
        if id == "spacer":
            # special case because Shotcut steps on the id='spacer'
            # <playlist id="playlist1">
            # <blank id="spacer" length="00:00:00.267"/>
            nodes['spacer'] = tree.find("./playlist[@id='playlist1']blank")
        else:
            node = tree.find(".//*[@id='{}']".format(id))
            # print(id,node)
            nodes[id] = node

    return nodes

def trim_tree(tree, playlist_id):

    mlt = tree.find('.')

    branch = tree.find("./playlist[@id='{}']".format(playlist_id))
    for twig in branch.findall("./entry[@sample]"):
        producer = twig.get('producer')
        producer_node = tree.find("./producer[@id='{}']".format(producer))
        print( producer )
        branch.remove(twig)
        mlt.remove(producer_node)

    return tree

def mk_mlt(template, output, params):

    # parse the template
    tree = parse_mlt(template)

    # grab nodes we are going to store values into
    # pl - play list
    # ti - timeline item
    node_names=[
        'pl_vid0', 'pi_vid0', # Play List and Item
        'tl_vid2', 'ti_vid2', # Time Line and Item
        'pi_title_img', 'ti_title',
        'pi_foot_img',  'ti_foot',
        'spacer',
        'audio_fade_in', 'audio_fade_out',
        'pic_in_pic', 'opacity',
        'channelcopy',
        'mono',
        'normalize',
        'volume',
        'title_fade','foot_fade',
        ]

    nodes = grab_nodes(tree, node_names)

    # remove all placeholder nodes
    tree = trim_tree(tree, 'main bin')
    tree = trim_tree(tree, 'playlist0')

    # remove the filters
    # they may be added back later
    nodes['ti_vid2'].remove(nodes['channelcopy'])
    nodes['ti_vid2'].remove(nodes['mono'])
    nodes['ti_vid2'].remove(nodes['normalize'])
    # nodes['ti_vid2'].remove(nodes['volume'])

    # add real stuff to the tree
    mlt = tree.find('.')

    # add each episode clip to the playlist
    play_list = tree.find("./playlist[@id='main bin']")
    # pprint(params['clips'])
    for i,clip in enumerate(params['clips']):

        pprint(clip)

        node_id = "pi_vid{}".format(clip['id'])
        # print("node_id",node_id)

        # setup and add Play List
        pl = copy.deepcopy( nodes['pl_vid0'] )
        pl.set("id", "pl_vid{}".format(clip['id']))
        pl.set("producer", node_id)
        set_attrib(pl, "in", clip['in'])
        set_attrib(pl, "out", clip['out'])
        play_list.insert(i,pl)

        # setup and add Playlist Item
        pi = copy.deepcopy( nodes['pi_vid0'] )
        pi.set("id", node_id)
        set_attrib(pi, "in", clip['in'])
        set_attrib(pi, "out", clip['out'])
        set_text(pi,'length')
        set_text(pi,'resource',clip['filename'])
        mlt.insert(i,pi)

    # add each cut to the timeline
    time_line = tree.find("./playlist[@id='playlist0']")
    total_length = 0
    for i,cut in enumerate(params['cuts']):
        # print(i,cut)

        node_id = "ti_vid{}".format(cut['id'])

        tl = copy.deepcopy( nodes['tl_vid2'] )
        tl.set("producer", node_id)
        set_attrib(tl, "in", cut['in'])
        set_attrib(tl, "out", cut['out'])
        time_line.insert(i,tl)

        ti = copy.deepcopy( nodes['ti_vid2'] )
        ti.set("id", node_id)
        set_attrib(ti, "in")
        set_attrib(ti, "out")
        set_text(ti,'length')
        set_text(ti,'resource',cut['filename'])
        set_text(ti,'video_delay',cut['video_delay'])

        # apply the filters to the cuts

        if cut['channelcopy']=='00':
            pass
        elif cut['channelcopy']=='m':
            ti.insert(0,nodes['mono'])
        else:
            channelcopy = copy.deepcopy( nodes['channelcopy'] )
            set_text(channelcopy,'from' , cut['channelcopy'][0])
            set_text(channelcopy,'to' , cut['channelcopy'][1])
            ti.insert(0,channelcopy)

        if cut['normalize']!='0':
            normalize = copy.deepcopy( nodes['normalize'] )
            # set_text(normalize,'program' , cut['normalize'])
            set_text(normalize, 'target_loudness' , cut['normalize'])

            ti.insert(0,normalize)

            # volume = copy.deepcopy( nodes['volume'] )
            # set_text(volume, 'gain' , cut['normalize'])
            # ti.insert(0,volume)

        if nodes['pic_in_pic'] is not None:
            # for Node 15
            ti.insert(0,nodes['pic_in_pic'])
            ti.insert(0,nodes['opacity'])

        if i==0:
            # apply audio fade in to first cut
            # ti.insert(0,nodes['audio_fade_in'])

            ti.insert(0,nodes['audio_fade_in'])

            set_attrib( nodes['audio_fade_in'], "in", cut['in'])
            out=float(cut['in'].split(':')[-1])+2
            out="0:{}".format(out)
            set_attrib( nodes['audio_fade_in'], "out", out)

        mlt.insert(i,ti)

        total_length += cut['length']
        # print( total_length )

        # print("transcription: {} - {}".format(
        #    cut['tstart'], cut['tend']))

    # ti and cut is left over from the above loop
    # put the 1.5 fadeout at the end
    # assume m:ss.s (will error if there is H:m:s)
    m,s = cut['out'].split(':')
    n=int(m)*60 + float(s)-1.5
    n="{}:{}".format(int(n/60), n%60)
    set_attrib( nodes['audio_fade_out'], "in", n)
    set_attrib( nodes['audio_fade_out'], "out", cut['out'])
    ti.insert(0,nodes['audio_fade_out'])

    # set title screen image
    set_text(nodes['pi_title_img'],'resource',params['title_img'])
    set_text(nodes['ti_title'],'resource',params['title_img'])

    # set footer image
    set_text(nodes['pi_foot_img'],'resource',params['foot_img'])
    set_text(nodes['ti_foot'],'resource',params['foot_img'])

    # set the lenght of the spacer so it puts the footer image to end-5sec
    # title_img, spacer, foot_img
    # Duration: 27mn 53s
    # nodes['ti_foot'].set("in",str(total_length))
    # nodes['spacer'].set("length","00:27:46.00")
    nodes['spacer'].set("length","0:{}.0".format(total_length-6.0))
    # nodes['spacer'].set("length","0:{}.0".format(total_length-1.0))

    # remove nodes we don't want
    # makes the code cleaner to pretend we are going to use them
    # and then remove them here.
    # import code; code.interact(local=locals())
    for node_name in node_names:
        if nodes[node_name] is not None:
            p = nodes[node_name].find("property[@name='disable']")
            if p is not None and p.text=='1':
                print(node_name)
                del nodes[node_name]

    tree.write(output)

    return True

"""
pl = tree[1]['main bin']
for pi in pl.findall("entry[@sample]"):
    print( pi.tag, pi.get('producer') )
    tree[0].remove(pi)

"""

def test():

    params = {
        'title_img': '/home/carl/Videos/veyepar/dot_net_fringe/dot_net_fringe_2015/titles/On_the_fringe_of_Nodejs_and_NET_with_Edgejs.png',
        'foot_img': 'bling/fosdem_2014_foot.png',
        'clips':[
                {'id':'123',
                'filename':'/home/carl/Videos/veyepar/dot_net_fringe/dot_net_fringe_2015/dv/main_stage/2015-04-14/09_02_51.dv',
                }
            ],
        'cuts':[{'id':'456',
                'filename':'/home/carl/Videos/veyepar/dot_net_fringe/dot_net_fringe_2015/dv/main_stage/2015-04-14/09_02_51.dv',
                'in':None,
                'out':None,
                'length':1673, # Duration: 27mn 53s
                'channelcopy':'01',
                'normalize':'-12.0',
                'video_delay':'0.0',
                },],
        }

    mk_mlt("template.mlt", "test.mlt",  params)
    return

    params = {
        'title_img': '/home/carl/Videos/veyepar/test_client/test_show/titles/Lets_make_a_Test.png',
        'foot_img': 'bling/ndv-169.png',
        'clips':[],
        'cuts':[],
        }

    for i in range(5):
        filename = "00_00_{:02}.dv".format(i*3)
        clip = {'id':str(i),
                'filename':'/home/carl/Videos/veyepar/test_client/test_show/dv/test_loc/2010-05-21/{}'.format(filename),
                'length':2,
                'in':None,
                'out':None,
                }

        if i==0:
            clip['in']=1

        params['clips'].append(clip)

        if i in [1,2,3]:
            params['cuts'].append(
               {'id':str(i),
                'filename':'/home/carl/Videos/veyepar/test_client/test_show/dv/test_loc/2010-05-21/{}'.format(filename),
                'in':None,
                'out':None,
                'length':3,
                'channelcopy':'01',
                'normalize':'-12.0',
                'video_delay':'0.0',
                })

    mk_mlt("template.mlt", "test.mlt",  params)

    return

def add_slides( base_dir, src_file, slide_dir, dst_file ):

    tree = parse_mlt(os.path.join(base_dir,src_file))

    node_names=[
        'tl_png',
        'ti_png',
        "spacer",
        ]
    nodes = grab_nodes(tree, node_names)
    print(nodes)

    # remove all placeholder (sample=) nodes
    tree = trim_tree(tree, 'main_bin')
    tree = trim_tree(tree, 'playlist2')

    # add real stuff to the tree
    mlt = tree.find('.')

    # add each png to the timeline
    slides = os.listdir( os.path.join(base_dir,slide_dir) )
    slides.sort()

    time_line = tree.find("./playlist[@id='playlist2']")
    # start_time = 5
    for i, slide in enumerate(slides):
        # print(i,slide)

        node_id = "ti_png{}".format(i)

        tl = copy.deepcopy( nodes['tl_png'] )
        tl.set("producer", node_id)
        # set_attrib(tl, "in", start_time)
        # set_attrib(tl, "out", start_time + 20)
        time_line.insert(i*2,tl)

        spacer = copy.deepcopy( nodes['spacer'] )
        spacer.set("length","00:01:00.0")
        time_line.insert(i*2+1,spacer)

        ti = copy.deepcopy( nodes['ti_png'] )
        ti.set("id", node_id)
        # set_attrib(ti, "in")
        # set_attrib(ti, "out")
        # set_text(ti,'length')
        set_text(ti,'resource', os.path.join(slide_dir, slide))
        mlt.insert(i,ti)

        # start_time += 120

    tree.write(os.path.join(base_dir,dst_file))

def find_targets(tree, target):
    # target = ( "playlist0", "avformat"),
    playlist_id, mlt_service = target

    nodes = []
    time_line = tree.find("./playlist[@id='{}']".format(playlist_id))
    _ = time_line.findall('entry[@producer]')
    for tli in _:
        p_id = tli.get('producer')
        producer = tree.find("producer[@id='{}']".format(p_id))
        if producer is not None:
            mlt_service = producer.find("property[@name='{}']".format("mlt_service"))
            if mlt_service.text == "avformat":
                # print(p_id)
                nodes.append(producer)

    return nodes

def add_filters( base_dir, src_file, filters, target, dst_file ):

    tree = parse_mlt(os.path.join(base_dir,src_file))

    filter_nodes = grab_nodes(tree, filters)

    # remove in/out
    for f in filter_nodes:
        node = filter_nodes[f]
        set_attrib(node, "in")
        set_attrib(node, "out")

    targets = find_targets(tree, target)

    for target in targets:
        print(target.get('id'))
        for f in filter_nodes:
            node = filter_nodes[f]
            target.insert(0, node)

    tree.write(os.path.join(base_dir,dst_file))

if __name__ == '__main__':
    # test()

    add_slides( "/home/carl/Videos/veyepar/pyohio/pyohio_2019/custom",
            'How_to_Write_Pytest_Plugins_v1.mlt',
            "pytests/png",
            'How_to_Write_Pytest_Plugins.mlt',
            )

#    add_filters( "/home/carl/Videos/veyepar/pyohio/pyohio_2019.local/custom",
#            "Enough_Python_to_Fake_It_v2.mlt",
#            ["filter9", "filter10"],
#            ("playlist0", "avformat"),
#            "Enough_Python_to_Fake_It.mlt",)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
'''
    A Flask extension integrating relib.
'''
from __future__ import absolute_import

import logging

from flask import current_app
from flask import _app_ctx_stack as stack
from driftconfig.relib import get_store_from_url, create_backend, copy_table_store
from driftconfig.util import get_domains

log = logging.getLogger(__name__)

class FlaskRelib(object):

    def __init__(self, app=None):
        if app is not None:
            self.init_app(app)

    def init_app(self, app):
        app.extensions['relib'] = self

    def refresh(self):
        """Invalidate Redis cache, if in use, and fetch new config from source."""
        ctx = stack.top
        if ctx is not None and hasattr(ctx, 'table_store'):
            delattr(ctx, 'table_store')

    def save(self, table_store=None):
        """Save 'table_store' to source. If 'table_store' is not specified, the default one is used."""
        table_store = table_store or self.table_store
        origin = table_store.get_table('domain')['origin']
        origin_backend = create_backend(origin)
        table_store.save_to_backend(origin_backend)
        self.refresh()

    @property
    def table_store(self):
        ctx = stack.top
        if ctx is not None:
            if not hasattr(ctx, 'table_store'):
                ctx.table_store = self._get_table_store()
            return ctx.table_store

    def _get_table_store(self):
        if 'DRIFT_CONFIG_URL' not in current_app.config:
            domains = get_domains()
            if len(domains) != 1:
                raise RuntimeError("'DRIFT_CONFIG_URL' not in app.config and no single "
                                   "candidate found in ~/.drift/config")
            domain = domains.values()[0]
            return domain['table_store']
        else:
            url = current_app['DRIFT_CONFIG_URL']
            return get_store_from_url(url)

    def get_copy(self):
        """"Return a copy of current table store. Good for editing."""
        return copy_table_store(self.table_store)
<commit_msg>For Flask integration, if app is not in debug mode, turn off all integrity checks for the benefit of speed.<commit_after># -*- coding: utf-8 -*-
'''
    A Flask extension integrating relib.
'''
from __future__ import absolute_import

import logging

from flask import current_app
from flask import _app_ctx_stack as stack
from driftconfig.relib import get_store_from_url, create_backend, copy_table_store, CHECK_INTEGRITY
from driftconfig.util import get_domains

log = logging.getLogger(__name__)

class FlaskRelib(object):

    def __init__(self, app=None):
        if app is not None:
            self.init_app(app)

    def init_app(self, app):
        app.extensions['relib'] = self
        if not app.debug:
            del CHECK_INTEGRITY[:]

    def refresh(self):
        """Invalidate Redis cache, if in use, and fetch new config from source."""
        ctx = stack.top
        if ctx is not None and hasattr(ctx, 'table_store'):
            delattr(ctx, 'table_store')

    def save(self, table_store=None):
        """Save 'table_store' to source. If 'table_store' is not specified, the default one is used."""
        table_store = table_store or self.table_store
        origin = table_store.get_table('domain')['origin']
        origin_backend = create_backend(origin)
        table_store.save_to_backend(origin_backend)
        self.refresh()

    @property
    def table_store(self):
        ctx = stack.top
        if ctx is not None:
            if not hasattr(ctx, 'table_store'):
                ctx.table_store = self._get_table_store()
            return ctx.table_store

    def _get_table_store(self):
        if 'DRIFT_CONFIG_URL' not in current_app.config:
            domains = get_domains()
            if len(domains) != 1:
                raise RuntimeError("'DRIFT_CONFIG_URL' not in app.config and no single "
                                   "candidate found in ~/.drift/config")
            domain = domains.values()[0]
            return domain['table_store']
        else:
            url = current_app['DRIFT_CONFIG_URL']
            return get_store_from_url(url)

    def get_copy(self):
        """"Return a copy of current table store. Good for editing."""
        return copy_table_store(self.table_store)
<|endoftext|>


<commit_before>import os
import importlib
from aiohttp import web
import djaio.core.settings as _settings
from djaio.core import urlconf

def get_settings():
    settings_module = os.environ.get('SETTINGS', 'app.settings')
    settings = None
    try:
        settings = importlib.import_module(settings_module)
    except ImportError:
        print('Settings module not found. Using the default one.')

    if settings:
        for k, v in settings.__dict__.items():
            setattr(_settings, k, v)
    return _settings

def discover_urls(app):
    settings = getattr(app, 'settings', None)
    if settings is None:
        return
    for _app in settings.INSTALLED_APPS:
        importlib.import_module('{}.urls'.format(_app))
    urlconf.setup(app)

def get_middlewares(settings):
    middleware_list = getattr(settings, 'MIDDLEWARES', [])
    out = []
    for item in middleware_list:
        module_name, factory = item.rsplit('.', 1)
        module = importlib.import_module(module_name)
        try:
            out.append(getattr(module, factory))
        except KeyError:
            continue
    return out

def init_app():
    settings = get_settings()
    middlewares = get_middlewares(settings)
    app = web.Application(middlewares=middlewares, debug=settings.DEBUG)
    app.settings = settings
    discover_urls(app)
    return app
<commit_msg>Added the ability to use custom router for your app<commit_after>import os
import importlib
from aiohttp import web
import djaio.core.settings as _settings
from djaio.core import urlconf

def get_settings():
    settings_module = os.environ.get('SETTINGS', 'app.settings')
    settings = None
    try:
        settings = importlib.import_module(settings_module)
    except ImportError:
        print('Settings module not found. Using the default one.')

    if settings:
        for k, v in settings.__dict__.items():
            setattr(_settings, k, v)
    return _settings

def discover_urls(app):
    settings = getattr(app, 'settings', None)
    if settings is None:
        return
    for _app in settings.INSTALLED_APPS:
        importlib.import_module('{}.urls'.format(_app))
    urlconf.setup(app)

def get_middlewares(settings):
    middleware_list = getattr(settings, 'MIDDLEWARES', [])
    out = []
    for item in middleware_list:
        module_name, factory = item.rsplit('.', 1)
        module = importlib.import_module(module_name)
        try:
            out.append(getattr(module, factory))
        except KeyError:
            continue
    return out

def get_router(settings):
    custom_router = getattr(settings, 'CUSTOM_ROUTER', None)
    if custom_router:
        module_name, factory = custom_router.rsplit('.', 1)
        module = importlib.import_module(module_name)
        try:
            return (getattr(module, factory))
        except KeyError:
            pass

def init_app():
    settings = get_settings()
    middlewares = get_middlewares(settings)
    router = get_router(settings)
    app = web.Application(middlewares=middlewares, debug=settings.DEBUG, router=router() if router else None)
    app.settings = settings
    discover_urls(app)
    return app
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
import requests
from django.conf import settings
from django.core.mail import send_mail
from django.db import models
from django.utils.translation import ugettext_lazy as _

class UserEmail(models.Model):
    class Meta:
        verbose_name = _('User Email')
        verbose_name_plural = _('User Emails')

    email = models.EmailField(unique=True)
    verified = models.BooleanField(default=False)
    verification_key = models.CharField(max_length=255, null=True, blank=True, unique=True)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    def __str__(self):
        check = "✓" if self.verified else "×"
        return "%s (%s)" % (self.email, check)

    def mail(self, subject, message):
        send_mail(
            subject=subject,
            message=message,
            recipient_list=[self.email],
            from_email=settings.DEFAULT_FROM_EMAIL
        )

class UserDevice(models.Model):
    class Meta:
        verbose_name = _('User Device')
        verbose_name_plural = _('User Devices')

    device_id = models.CharField(max_length=255, unique=True)
    verified = models.BooleanField(default=False)
    verification_key = models.CharField(max_length=255, null=True, blank=True, unique=True)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    def notify(self, data):
        payload = {
            'app_id': settings.ONE_SIGNAL['APP_ID'],
            'include_player_ids': [self.device_id]
        }
        payload.update(data)
        requests.post(
            url=settings.ONE_SIGNAL['URL'],
            headers={
                'Authorization': 'key=%s' % settings.ONE_SIGNAL['KEY'],
                'Content-Type': 'application/json; charset=utf-8'
            },
            json=payload,
        )

    def __str__(self):
        return self.device_id

class City(models.Model):
    class Meta:
        verbose_name = _('City')
        verbose_name_plural = _('Cities')

    name = models.CharField(max_length=255, unique=True)

    def __str__(self):
        return self.name

class Institution(models.Model):
    class Meta:
        verbose_name = _('Institution')
        verbose_name_plural = _('Institutions')

    name = models.CharField(max_length=255)
    city = models.ForeignKey('City')

    def __str__(self):
        return self.name

class Location(models.Model):
    class Meta:
        verbose_name = _('Location')
        verbose_name_plural = _('Locations')

    name = models.CharField(max_length=255)
    institution = models.ForeignKey('Institution')

    def __str__(self):
        return self.name

class Category(models.Model):
    class Meta:
        verbose_name = _('Category')
        verbose_name_plural = _('Categories')
        ordering = ['name']

    name = models.CharField(max_length=255)
    institution = models.ForeignKey('Institution')

    def __str__(self):
        return self.name

class Performance(models.Model):
    class Meta:
        verbose_name = _('Performance')
        verbose_name_plural = _('Performances')
        ordering = ['begin']

    title = models.CharField(max_length=255)
    begin = models.DateTimeField()
    location = models.ForeignKey('Location')
    category = models.ForeignKey('Category', null=True, blank=True)
    description = models.TextField(null=True, blank=True)

    def __str__(self):
        return "%s (%s)" % (self.title, self.begin)

class PerformanceNotification(models.Model):
    class Meta:
        verbose_name = _('Performance Notification')
        verbose_name_plural = _('Performance Notifications')
        unique_together = ('user', 'performance')

    user = models.ForeignKey('UserEmail')
    performance = models.ForeignKey('Performance')
    interval = models.DurationField()

    def __str__(self):
        return '%s ~> %s ~> %s' % (self.user, self.interval, self.performance.title)

class CategoryNotification(models.Model):
    class Meta:
        verbose_name = _('Category Notification')
        verbose_name_plural = _('Category Notifications')
        unique_together = ('user', 'device', 'category', 'verified')

    user = models.ForeignKey('UserEmail', null=True, blank=True)
    device = models.ForeignKey('UserDevice', null=True, blank=True)
    category = models.ForeignKey('Category')
    interval = models.DurationField()
    verified = models.BooleanField(default=False)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    def __str__(self):
        check = "✓" if self.verified else "×"
        return '%s ~> %s ~> %s (%s)' % (self.user, self.interval, self.category.name, check)
<commit_msg>show userdevice in noticications list<commit_after># -*- coding: utf-8 -*-
import requests
from django.conf import settings
from django.core.mail import send_mail
from django.db import models
from django.utils.translation import ugettext_lazy as _

class UserEmail(models.Model):
    class Meta:
        verbose_name = _('User Email')
        verbose_name_plural = _('User Emails')

    email = models.EmailField(unique=True)
    verified = models.BooleanField(default=False)
    verification_key = models.CharField(max_length=255, null=True, blank=True, unique=True)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    def __str__(self):
        check = "✓" if self.verified else "×"
        return "%s (%s)" % (self.email, check)

    def mail(self, subject, message):
        send_mail(
            subject=subject,
            message=message,
            recipient_list=[self.email],
            from_email=settings.DEFAULT_FROM_EMAIL
        )

class UserDevice(models.Model):
    class Meta:
        verbose_name = _('User Device')
        verbose_name_plural = _('User Devices')

    device_id = models.CharField(max_length=255, unique=True)
    verified = models.BooleanField(default=False)
    verification_key = models.CharField(max_length=255, null=True, blank=True, unique=True)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    def notify(self, data):
        payload = {
            'app_id': settings.ONE_SIGNAL['APP_ID'],
            'include_player_ids': [self.device_id]
        }
        payload.update(data)
        requests.post(
            url=settings.ONE_SIGNAL['URL'],
            headers={
                'Authorization': 'key=%s' % settings.ONE_SIGNAL['KEY'],
                'Content-Type': 'application/json; charset=utf-8'
            },
            json=payload,
        )

    def __str__(self):
        return self.device_id

class City(models.Model):
    class Meta:
        verbose_name = _('City')
        verbose_name_plural = _('Cities')

    name = models.CharField(max_length=255, unique=True)

    def __str__(self):
        return self.name

class Institution(models.Model):
    class Meta:
        verbose_name = _('Institution')
        verbose_name_plural = _('Institutions')

    name = models.CharField(max_length=255)
    city = models.ForeignKey('City')

    def __str__(self):
        return self.name

class Location(models.Model):
    class Meta:
        verbose_name = _('Location')
        verbose_name_plural = _('Locations')

    name = models.CharField(max_length=255)
    institution = models.ForeignKey('Institution')

    def __str__(self):
        return self.name

class Category(models.Model):
    class Meta:
        verbose_name = _('Category')
        verbose_name_plural = _('Categories')
        ordering = ['name']

    name = models.CharField(max_length=255)
    institution = models.ForeignKey('Institution')

    def __str__(self):
        return self.name

class Performance(models.Model):
    class Meta:
        verbose_name = _('Performance')
        verbose_name_plural = _('Performances')
        ordering = ['begin']

    title = models.CharField(max_length=255)
    begin = models.DateTimeField()
    location = models.ForeignKey('Location')
    category = models.ForeignKey('Category', null=True, blank=True)
    description = models.TextField(null=True, blank=True)

    def __str__(self):
        return "%s (%s)" % (self.title, self.begin)

class PerformanceNotification(models.Model):
    class Meta:
        verbose_name = _('Performance Notification')
        verbose_name_plural = _('Performance Notifications')
        unique_together = ('user', 'performance')

    user = models.ForeignKey('UserEmail')
    performance = models.ForeignKey('Performance')
    interval = models.DurationField()

    def __str__(self):
        return '%s ~> %s ~> %s' % (self.user, self.interval, self.performance.title)

class CategoryNotification(models.Model):
    class Meta:
        verbose_name = _('Category Notification')
        verbose_name_plural = _('Category Notifications')
        unique_together = ('user', 'device', 'category', 'verified')

    user = models.ForeignKey('UserEmail', null=True, blank=True)
    device = models.ForeignKey('UserDevice', null=True, blank=True)
    category = models.ForeignKey('Category')
    interval = models.DurationField()
    verified = models.BooleanField(default=False)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    def __str__(self):
        check = "✓" if self.verified else "×"
        u = 'N/A'
        if self.user:
            u = self.user
        elif self.device:
            u = self.device
        return '%s ~> %s ~> %s (%s)' % (u, self.interval, self.category.name, check)
<|endoftext|>


<commit_before>"""
Functions that modify an HTTP request or response in some way.
"""

# This group of functions are run as part of the response handling, after
# everything else, including all response middleware. Think of them as
# "compulsory response middleware". Be careful about what goes here, because
# it's a little fiddly to override this behavior, so they should be truly
# universally applicable.

def fix_location_header(request, response):
    """
    Ensures that we always use an absolute URI in any location header in the
    response. This is required by RFC 2616, section 14.30.

    Code constructing response objects is free to insert relative paths, as
    this function converts them to absolute paths.
    """
    if 'Location' in response and request.get_host():
        response['Location'] = request.build_absolute_uri(response['Location'])
    return response

def conditional_content_removal(request, response):
    """
    Removes the content of responses for HEAD requests, 1xx, 204 and 304
    responses. Ensures compliance with RFC 2616, section 4.3.
    """
    if 100 <= response.status_code < 200 or response.status_code in (204, 304):
       response.content = ''
       response['Content-Length'] = 0
    if request.method == 'HEAD':
        response.content = ''
    return response

def fix_IE_for_attach(request, response):
    """
    This function will prevent Django from serving a Content-Disposition header
    while expecting the browser to cache it (only when the browser is IE). This
    leads to IE not allowing the client to download.
    """
    if 'MSIE' not in request.META.get('HTTP_USER_AGENT', '').upper():
        return response

    offending_headers = ('no-cache', 'no-store')
    if response.has_header('Content-Disposition'):
        try:
            del response['Pragma']
        except KeyError:
            pass
        if response.has_header('Cache-Control'):
            cache_control_values = [value.strip() for value in
                    response['Cache-Control'].split(',')
                    if value.strip().lower() not in offending_headers]

            if not len(cache_control_values):
                del response['Cache-Control']
            else:
                response['Cache-Control'] = ', '.join(cache_control_values)

    return response

def fix_IE_for_vary(request, response):
    """
    This function will fix the bug reported at
    http://support.microsoft.com/kb/824847/en-us?spid=8722&sid=global
    by clearing the Vary header whenever the mime-type is not safe
    enough for Internet Explorer to handle.  Poor thing.
    """
    if 'MSIE' not in request.META.get('HTTP_USER_AGENT', '').upper():
        return response

    # These mime-types that are decreed "Vary-safe" for IE:
    safe_mime_types = ('text/html', 'text/plain', 'text/sgml')

    # The first part of the Content-Type field will be the MIME type,
    # everything after ';', such as character-set, can be ignored.
    if response['Content-Type'].split(';')[0] not in safe_mime_types:
        try:
            del response['Vary']
        except KeyError:
            pass

    return response

<commit_msg>Fixed #15046 -- Added "CHROMEFRAME" as a user agent alias for various MSIE fixes. Thanks to chrj for the report and patch.<commit_after>"""
Functions that modify an HTTP request or response in some way.
"""

# This group of functions are run as part of the response handling, after
# everything else, including all response middleware. Think of them as
# "compulsory response middleware". Be careful about what goes here, because
# it's a little fiddly to override this behavior, so they should be truly
# universally applicable.

def fix_location_header(request, response):
    """
    Ensures that we always use an absolute URI in any location header in the
    response. This is required by RFC 2616, section 14.30.

    Code constructing response objects is free to insert relative paths, as
    this function converts them to absolute paths.
    """
    if 'Location' in response and request.get_host():
        response['Location'] = request.build_absolute_uri(response['Location'])
    return response

def conditional_content_removal(request, response):
    """
    Removes the content of responses for HEAD requests, 1xx, 204 and 304
    responses. Ensures compliance with RFC 2616, section 4.3.
    """
    if 100 <= response.status_code < 200 or response.status_code in (204, 304):
       response.content = ''
       response['Content-Length'] = 0
    if request.method == 'HEAD':
        response.content = ''
    return response

def fix_IE_for_attach(request, response):
    """
    This function will prevent Django from serving a Content-Disposition header
    while expecting the browser to cache it (only when the browser is IE). This
    leads to IE not allowing the client to download.
    """
    useragent = request.META.get('HTTP_USER_AGENT', '').upper()
    if 'MSIE' not in useragent and 'CHROMEFRAME' not in useragent:
        return response

    offending_headers = ('no-cache', 'no-store')
    if response.has_header('Content-Disposition'):
        try:
            del response['Pragma']
        except KeyError:
            pass
        if response.has_header('Cache-Control'):
            cache_control_values = [value.strip() for value in
                    response['Cache-Control'].split(',')
                    if value.strip().lower() not in offending_headers]

            if not len(cache_control_values):
                del response['Cache-Control']
            else:
                response['Cache-Control'] = ', '.join(cache_control_values)

    return response

def fix_IE_for_vary(request, response):
    """
    This function will fix the bug reported at
    http://support.microsoft.com/kb/824847/en-us?spid=8722&sid=global
    by clearing the Vary header whenever the mime-type is not safe
    enough for Internet Explorer to handle.  Poor thing.
    """
    useragent = request.META.get('HTTP_USER_AGENT', '').upper()
    if 'MSIE' not in useragent and 'CHROMEFRAME' not in useragent:
        return response

    # These mime-types that are decreed "Vary-safe" for IE:
    safe_mime_types = ('text/html', 'text/plain', 'text/sgml')

    # The first part of the Content-Type field will be the MIME type,
    # everything after ';', such as character-set, can be ignored.
    if response['Content-Type'].split(';')[0] not in safe_mime_types:
        try:
            del response['Vary']
        except KeyError:
            pass

    return response

<|endoftext|>


<commit_before># Software License Agreement (BSD License)
#
# Copyright (c) 2009-2012, Eucalyptus Systems, Inc.
# All rights reserved.
#
# Redistribution and use of this software in source and binary forms, with or
# without modification, are permitted provided that the following conditions
# are met:
#
#   Redistributions of source code must retain the above
#   copyright notice, this list of conditions and the
#   following disclaimer.
#
#   Redistributions in binary form must reproduce the above
#   copyright notice, this list of conditions and the
#   following disclaimer in the documentation and/or other
#   materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

import glob
import os.path
import platform
import requestbuilder.command
import requestbuilder.request
import requests
import sys
from .. import __version__

class Euca2oolsCommand(requestbuilder.command.BaseCommand):
    def __init__(self, **kwargs):
        self._config_files = None
        requestbuilder.request.BaseCommand.__init__(self, **kwargs)

    @property
    def config_files(self):
        if self._config_files is None:
            self._config_files = ['/etc/euca2ools.ini']
            user_glob = os.path.join(os.path.expanduser('~/.euca'), '*.ini')
            self._config_files.extend(sorted(glob.glob(user_glob)))
        return self._config_files

    @staticmethod
    def print_version_and_exit():
        _print_version_and_exit()

    def __init__(self, **kwargs):
        self._config_files = None
        self.__user_agent = None
        requestbuilder.request.BaseRequest.__init__(self, **kwargs)

    @property
    def config_files(self):
        if self._config_files is None:
            self._config_files = ['/etc/euca2ools.ini']
            user_glob = os.path.join(os.path.expanduser('~/.euca'), '*.ini')
            self._config_files.extend(sorted(glob.glob(user_glob)))
        return self._config_files

    @property
    def user_agent(self):
        if self.__user_agent is None:
            user_agent_bits = ['euca2ools/{0}'.format(__version__)]

            tokens = []
            impl = platform.python_implementation()
            if impl == 'PyPy':
                impl_version = '{0}.{1}.{2}'.format(
                        sys.pypy_version_info.major,
                        sys.pypy_version_info.minor,
                        sys.pypy_version_info.micro)
                if sys.pypy_version_info.releaselevel != 'final':
                    impl_version += sys.pypy_version_info.releaselevel
            else:
                # I'm guessing for non-CPython implementations; feel free to
                # submit patches or the needed implementation-specific API
                # references.
                impl_version = platform.python_version()
            tokens.append('{0} {1}'.format(impl, impl_version))
            plat = []
            try:
                plat.append(platform.system())
                plat.append(platform.release())
            except IOError:
                pass
            if plat:
                tokens.append(' '.join(plat))
            tokens.append(platform.machine())
            user_agent_bits.append('({0})'.format('; '.join(tokens)))

            user_agent_bits.append('requestbuilder/{0}'.format(
                    requestbuilder.__version__))
            user_agent_bits.append('requests/{0}'.format(requests.__version__))
            self.__user_agent = ' '.join(user_agent_bits)
        return self.__user_agent

    @staticmethod
    def print_version_and_exit():
        _print_version_and_exit()

def _print_version_and_exit():
    print >> sys.stderr, 'euca2ools {0} (Sparta)'.format(__version__)
    if os.path.isfile('/etc/eucalyptus/eucalyptus-version'):
        with open('/etc/eucalyptus/eucalyptus-version') as version_file:
            print 'eucalyptus {0}'.format(version_file.readline().strip())
    sys.exit()
<commit_msg>Temporarily change Euca2oolsRequests's base class<commit_after># Software License Agreement (BSD License)
#
# Copyright (c) 2009-2012, Eucalyptus Systems, Inc.
# All rights reserved.
#
# Redistribution and use of this software in source and binary forms, with or
# without modification, are permitted provided that the following conditions
# are met:
#
#   Redistributions of source code must retain the above
#   copyright notice, this list of conditions and the
#   following disclaimer.
#
#   Redistributions in binary form must reproduce the above
#   copyright notice, this list of conditions and the
#   following disclaimer in the documentation and/or other
#   materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

import glob
import os.path
import platform
import requestbuilder.command
import requestbuilder.request
import requests
import sys
from .. import __version__

class Euca2oolsCommand(requestbuilder.command.BaseCommand):
    def __init__(self, **kwargs):
        self._config_files = None
        requestbuilder.request.BaseCommand.__init__(self, **kwargs)

    @property
    def config_files(self):
        if self._config_files is None:
            self._config_files = ['/etc/euca2ools.ini']
            user_glob = os.path.join(os.path.expanduser('~/.euca'), '*.ini')
            self._config_files.extend(sorted(glob.glob(user_glob)))
        return self._config_files

    @staticmethod
    def print_version_and_exit():
        _print_version_and_exit()

# FIXME:  the base class should change
class Euca2oolsRequest(requestbuilder.request.AWSQueryRequest):
    def __init__(self, **kwargs):
        self._config_files = None
        self.__user_agent = None
        requestbuilder.request.BaseRequest.__init__(self, **kwargs)

    @property
    def config_files(self):
        if self._config_files is None:
            self._config_files = ['/etc/euca2ools.ini']
            user_glob = os.path.join(os.path.expanduser('~/.euca'), '*.ini')
            self._config_files.extend(sorted(glob.glob(user_glob)))
        return self._config_files

    @property
    def user_agent(self):
        if self.__user_agent is None:
            user_agent_bits = ['euca2ools/{0}'.format(__version__)]

            tokens = []
            impl = platform.python_implementation()
            if impl == 'PyPy':
                impl_version = '{0}.{1}.{2}'.format(
                        sys.pypy_version_info.major,
                        sys.pypy_version_info.minor,
                        sys.pypy_version_info.micro)
                if sys.pypy_version_info.releaselevel != 'final':
                    impl_version += sys.pypy_version_info.releaselevel
            else:
                # I'm guessing for non-CPython implementations; feel free to
                # submit patches or the needed implementation-specific API
                # references.
                impl_version = platform.python_version()
            tokens.append('{0} {1}'.format(impl, impl_version))
            plat = []
            try:
                plat.append(platform.system())
                plat.append(platform.release())
            except IOError:
                pass
            if plat:
                tokens.append(' '.join(plat))
            tokens.append(platform.machine())
            user_agent_bits.append('({0})'.format('; '.join(tokens)))

            user_agent_bits.append('requestbuilder/{0}'.format(
                    requestbuilder.__version__))
            user_agent_bits.append('requests/{0}'.format(requests.__version__))
            self.__user_agent = ' '.join(user_agent_bits)
        return self.__user_agent

    @staticmethod
    def print_version_and_exit():
        _print_version_and_exit()

def _print_version_and_exit():
    print >> sys.stderr, 'euca2ools {0} (Sparta)'.format(__version__)
    if os.path.isfile('/etc/eucalyptus/eucalyptus-version'):
        with open('/etc/eucalyptus/eucalyptus-version') as version_file:
            print 'eucalyptus {0}'.format(version_file.readline().strip())
    sys.exit()
<|endoftext|>


<commit_before>from django import http
from django.utils.translation import check_for_language, activate, to_locale, get_language
from django.utils.text import javascript_quote
from django.conf import settings
import os
import gettext as gettext_module

def set_language(request):
    """
    Redirect to a given url while setting the chosen language in the
    session or cookie. The url and the language code need to be
    specified in the GET parameters.
    """
    lang_code = request.GET.get('language', None)
    next = request.GET.get('next', None)
    if not next:
        next = request.META.get('HTTP_REFERER', None)
    if not next:
        next = '/'
    response = http.HttpResponseRedirect(next)
    if lang_code and check_for_language(lang_code):
        if hasattr(request, 'session'):
            request.session['django_language'] = lang_code
        else:
            response.set_cookie('django_language', lang_code)
    return response

NullSource = """
/* gettext identity library */

function gettext(msgid) { return msgid; }
function ngettext(singular, plural, count) { return (count == 1) ? singular : plural; }
function gettext_noop(msgid) { return msgid; }
"""

LibHead = """
/* gettext library */

var catalog = new Array();
"""

LibFoot = """

function gettext(msgid) {
  var value = catalog[msgid];
  if (typeof(value) == 'undefined') {
    return msgid;
  } else {
    return (typeof(value) == 'string') ? value : value[0];
  }
}

function ngettext(singular, plural, count) {
  value = catalog[singular];
  if (typeof(value) == 'undefined') {
    return (count == 1) ? singular : plural;
  } else {
    return value[pluralidx(count)];
  }
}

function gettext_noop(msgid) { return msgid; }
"""

SimplePlural = """
function pluralidx(count) { return (count == 1) ? 0 : 1; }
"""

InterPolate = r"""
function interpolate(fmt, obj, named) {
  if (named) {
    return fmt.replace(/%\(\w+\)s/g, function(match){return String(obj[match.slice(2,-2)])});
  } else {
    return fmt.replace(/%s/g, function(match){return String(obj.shift())});
  }
}
"""

def null_javascript_catalog(request, domain=None, packages=None):
    """
    Returns "identity" versions of the JavaScript i18n functions -- i.e.,
    versions that don't actually do anything.
    """
    return http.HttpResponse(NullSource + InterPolate, 'text/javascript')

def javascript_catalog(request, domain='djangojs', packages=None):
    """
    Returns the selected language catalog as a javascript library.

    Receives the list of packages to check for translations in the
    packages parameter either from an infodict or as a +-delimited
    string from the request. Default is 'django.conf'.

    Additionally you can override the gettext domain for this view,
    but usually you don't want to do that, as JavaScript messages
    go to the djangojs domain. But this might be needed if you
    deliver your JavaScript source from Django templates.
    """
    if request.GET:
        if 'language' in request.GET:
            if check_for_language(request.GET['language']):
                activate(request.GET['language'])
    if packages is None:
        packages = ['django.conf']
    if type(packages) in (str, unicode):
        packages = packages.split('+')
    packages = [p for p in packages if p == 'django.conf' or p in settings.INSTALLED_APPS]
    default_locale = to_locale(settings.LANGUAGE_CODE)
    locale = to_locale(get_language())
    t = {}
    paths = []
    # first load all english languages files for defaults
    for package in packages:
        p = __import__(package, {}, {}, [''])
        path = os.path.join(os.path.dirname(p.__file__), 'locale')
        paths.append(path)
        catalog = gettext_module.translation(domain, path, ['en'])
        t.update(catalog._catalog)
    # next load the settings.LANGUAGE_CODE translations if it isn't english
    if default_locale != 'en':
        for path in paths:
            try:
                catalog = gettext_module.translation(domain, path, [default_locale])
            except IOError:
                catalog = None
            if catalog is not None:
                t.update(catalog._catalog)
    # last load the currently selected language, if it isn't identical to the default.
    if locale != default_locale:
        for path in paths:
            try:
                catalog = gettext_module.translation(domain, path, [locale])
            except IOError:
                catalog = None
            if catalog is not None:
                t.update(catalog._catalog)
    src = [LibHead]
    plural = None
    if '' in t:
        for l in t[''].split('\n'):
            if l.startswith('Plural-Forms:'):
                plural = l.split(':',1)[1].strip()
    if plural is not None:
        # this should actually be a compiled function of a typical plural-form:
        # Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;
        plural = [el.strip() for el in plural.split(';') if el.strip().startswith('plural=')][0].split('=',1)[1]
        src.append('function pluralidx(n) {\n    return %s;\n}\n' % plural)
    else:
        src.append(SimplePlural)
    csrc = []
    pdict = {}
    for k, v in t.items():
        if k == '':
            continue
        if type(k) in (str, unicode):
            csrc.append("catalog['%s'] = '%s';\n" % (javascript_quote(k), javascript_quote(v)))
        elif type(k) == tuple:
            if k[0] not in pdict:
                pdict[k[0]] = k[1]
            else:
                pdict[k[0]] = max(k[1], pdict[k[0]])
            csrc.append("catalog['%s'][%d] = '%s';\n" % (javascript_quote(k[0]), k[1], javascript_quote(v)))
        else:
            raise TypeError, k
    csrc.sort()
    for k,v in pdict.items():
        src.append("catalog['%s'] = [%s];\n" % (javascript_quote(k), ','.join(["''"]*(v+1))))
    src.extend(csrc)
    src.append(LibFoot)
    src.append(InterPolate)
    src = ''.join(src)
    return http.HttpResponse(src, 'text/javascript')
<commit_msg>Fixed #3651 -- Changed set_language_view() to require POST request is used, in accordance with the HTTP spec (it changes the user's state). Thanks, Fraser Nevett.<commit_after>from django import http
from django.utils.translation import check_for_language, activate, to_locale, get_language
from django.utils.text import javascript_quote
from django.conf import settings
import os
import gettext as gettext_module

def set_language(request):
    """
    Redirect to a given url while setting the chosen language in the
    session or cookie. The url and the language code need to be
    specified in the request parameters.

    Since this view changes how the user will see the rest of the site, it must
    only be accessed as a POST request. If called as a GET request, it will
    redirect to the page in the request (the 'next' parameter) without changing
    any state.
    """
    next = request.GET.get('next', None)
    if not next:
        next = request.META.get('HTTP_REFERER', None)
    if not next:
        next = '/'
    response = http.HttpResponseRedirect(next)
    if request.method == 'POST':
        lang_code = request.POST.get('language', None)
        if lang_code and check_for_language(lang_code):
            if hasattr(request, 'session'):
                request.session['django_language'] = lang_code
            else:
                response.set_cookie('django_language', lang_code)
    return response

NullSource = """
/* gettext identity library */

function gettext(msgid) { return msgid; }
function ngettext(singular, plural, count) { return (count == 1) ? singular : plural; }
function gettext_noop(msgid) { return msgid; }
"""

LibHead = """
/* gettext library */

var catalog = new Array();
"""

LibFoot = """

function gettext(msgid) {
  var value = catalog[msgid];
  if (typeof(value) == 'undefined') {
    return msgid;
  } else {
    return (typeof(value) == 'string') ? value : value[0];
  }
}

function ngettext(singular, plural, count) {
  value = catalog[singular];
  if (typeof(value) == 'undefined') {
    return (count == 1) ? singular : plural;
  } else {
    return value[pluralidx(count)];
  }
}

function gettext_noop(msgid) { return msgid; }
"""

SimplePlural = """
function pluralidx(count) { return (count == 1) ? 0 : 1; }
"""

InterPolate = r"""
function interpolate(fmt, obj, named) {
  if (named) {
    return fmt.replace(/%\(\w+\)s/g, function(match){return String(obj[match.slice(2,-2)])});
  } else {
    return fmt.replace(/%s/g, function(match){return String(obj.shift())});
  }
}
"""

def null_javascript_catalog(request, domain=None, packages=None):
    """
    Returns "identity" versions of the JavaScript i18n functions -- i.e.,
    versions that don't actually do anything.
    """
    return http.HttpResponse(NullSource + InterPolate, 'text/javascript')

def javascript_catalog(request, domain='djangojs', packages=None):
    """
    Returns the selected language catalog as a javascript library.

    Receives the list of packages to check for translations in the
    packages parameter either from an infodict or as a +-delimited
    string from the request. Default is 'django.conf'.

    Additionally you can override the gettext domain for this view,
    but usually you don't want to do that, as JavaScript messages
    go to the djangojs domain. But this might be needed if you
    deliver your JavaScript source from Django templates.
    """
    if request.GET:
        if 'language' in request.GET:
            if check_for_language(request.GET['language']):
                activate(request.GET['language'])
    if packages is None:
        packages = ['django.conf']
    if type(packages) in (str, unicode):
        packages = packages.split('+')
    packages = [p for p in packages if p == 'django.conf' or p in settings.INSTALLED_APPS]
    default_locale = to_locale(settings.LANGUAGE_CODE)
    locale = to_locale(get_language())
    t = {}
    paths = []
    # first load all english languages files for defaults
    for package in packages:
        p = __import__(package, {}, {}, [''])
        path = os.path.join(os.path.dirname(p.__file__), 'locale')
        paths.append(path)
        catalog = gettext_module.translation(domain, path, ['en'])
        t.update(catalog._catalog)
    # next load the settings.LANGUAGE_CODE translations if it isn't english
    if default_locale != 'en':
        for path in paths:
            try:
                catalog = gettext_module.translation(domain, path, [default_locale])
            except IOError:
                catalog = None
            if catalog is not None:
                t.update(catalog._catalog)
    # last load the currently selected language, if it isn't identical to the default.
    if locale != default_locale:
        for path in paths:
            try:
                catalog = gettext_module.translation(domain, path, [locale])
            except IOError:
                catalog = None
            if catalog is not None:
                t.update(catalog._catalog)
    src = [LibHead]
    plural = None
    if '' in t:
        for l in t[''].split('\n'):
            if l.startswith('Plural-Forms:'):
                plural = l.split(':',1)[1].strip()
    if plural is not None:
        # this should actually be a compiled function of a typical plural-form:
        # Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;
        plural = [el.strip() for el in plural.split(';') if el.strip().startswith('plural=')][0].split('=',1)[1]
        src.append('function pluralidx(n) {\n    return %s;\n}\n' % plural)
    else:
        src.append(SimplePlural)
    csrc = []
    pdict = {}
    for k, v in t.items():
        if k == '':
            continue
        if type(k) in (str, unicode):
            csrc.append("catalog['%s'] = '%s';\n" % (javascript_quote(k), javascript_quote(v)))
        elif type(k) == tuple:
            if k[0] not in pdict:
                pdict[k[0]] = k[1]
            else:
                pdict[k[0]] = max(k[1], pdict[k[0]])
            csrc.append("catalog['%s'][%d] = '%s';\n" % (javascript_quote(k[0]), k[1], javascript_quote(v)))
        else:
            raise TypeError, k
    csrc.sort()
    for k,v in pdict.items():
        src.append("catalog['%s'] = [%s];\n" % (javascript_quote(k), ','.join(["''"]*(v+1))))
    src.extend(csrc)
    src.append(LibFoot)
    src.append(InterPolate)
    src = ''.join(src)
    return http.HttpResponse(src, 'text/javascript')
<|endoftext|>


<commit_before># Software License Agreement (BSD License)
#
# Copyright (c) 2009-2012, Eucalyptus Systems, Inc.
# All rights reserved.
#
# Redistribution and use of this software in source and binary forms, with or
# without modification, are permitted provided that the following conditions
# are met:
#
#   Redistributions of source code must retain the above
#   copyright notice, this list of conditions and the
#   following disclaimer.
#
#   Redistributions in binary form must reproduce the above
#   copyright notice, this list of conditions and the
#   following disclaimer in the documentation and/or other
#   materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

import platform
import requestbuilder.command
import requestbuilder.request
from .. import __version__, __codename__

class Euca2oolsCommand(requestbuilder.command.BaseCommand):
    Version = 'euca2ools {0} ({1})'.format(__version__, __codename__)

class Euca2oolsRequest(Euca2oolsCommand, requestbuilder.request.BaseRequest):
    def __init__(self, **kwargs):
        requestbuilder.request.BaseRequest.__init__(self, **kwargs)
        self.__user_agent = None

    @property
    def user_agent(self):
        if not self.__user_agent:
            template = ('euca2ools/{ver} ({os} {osver}; {python} {pyver}) '
                        'requestbuilder/{rqver}')
            self.__user_agent = template.format(ver=__version__,
                    os=platform.uname()[0], osver=platform.uname()[2],
                    python=platform.python_implementation(),
                    pyver=platform.python_version(),
                    rqver=requestbuilder.__version__)
        return self.__user_agent
<commit_msg>Add /etc/euca2ools.ini and ~/.euca/*.ini as config files<commit_after># Software License Agreement (BSD License)
#
# Copyright (c) 2009-2012, Eucalyptus Systems, Inc.
# All rights reserved.
#
# Redistribution and use of this software in source and binary forms, with or
# without modification, are permitted provided that the following conditions
# are met:
#
#   Redistributions of source code must retain the above
#   copyright notice, this list of conditions and the
#   following disclaimer.
#
#   Redistributions in binary form must reproduce the above
#   copyright notice, this list of conditions and the
#   following disclaimer in the documentation and/or other
#   materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

import glob
import os.path
import platform
import requestbuilder.command
import requestbuilder.request
from .. import __version__, __codename__

class Euca2oolsCommand(requestbuilder.command.BaseCommand):
    Version = 'euca2ools {0} ({1})'.format(__version__, __codename__)

    def __init__(self, **kwargs):
        self.ConfigFiles.append('/etc/euca2ools.ini')
        user_config_glob = os.path.join(os.path.expanduser('~/.euca'), '*.ini')
        for configfile in sorted(glob.glob(user_config_glob)):
            self.ConfigFiles.append(configfile)
        requestbuilder.request.BaseCommand.__init__(self, **kwargs)

class Euca2oolsRequest(Euca2oolsCommand, requestbuilder.request.BaseRequest):
    def __init__(self, **kwargs):
        Euca2oolsCommand.__init__(self, **kwargs)
        requestbuilder.request.BaseRequest.__init__(self, **kwargs)
        self.__user_agent = None

    @property
    def user_agent(self):
        if not self.__user_agent:
            template = ('euca2ools/{ver} ({os} {osver}; {python} {pyver}) '
                        'requestbuilder/{rqver}')
            self.__user_agent = template.format(ver=__version__,
                    os=platform.uname()[0], osver=platform.uname()[2],
                    python=platform.python_implementation(),
                    pyver=platform.python_version(),
                    rqver=requestbuilder.__version__)
        return self.__user_agent
<|endoftext|>


<commit_before>from datetime import datetime

from django.conf import settings
from django.utils.functional import LazyObject
from suds import Client
import pytz

def format_datetime(datetime):
    """
    "Another date formatting function?" you're thinking, eh? Well, this
    actually formats dates in the *exact* format the AFIP's WS expects it,
    which is almost like ISO8601.

    Note that .isoformat() works fine on PROD, but not on TESTING.
    """
    return datetime.strftime("%Y-%m-%dT%H:%M:%S-00:00")

def format_date(date):
    return date.strftime("%Y%m%d")

def parse_datetime(datestring):
    if datestring == 'NULL':
        return None
    return datetime.strptime(datestring, '%Y%m%d%H%M%S') \
        .replace(tzinfo=pytz.timezone(pytz.country_timezones['ar'][0]))

def parse_date(datestring):
    if datestring == 'NULL':
        return None
    return datetime.strptime(datestring, '%Y%m%d').date()

def encode_str(string):
    """
    Re-encodes strings from AFIP's weird encoding to unicode.
    """
    return string.encode('latin-1').decode()

class AfipException(Exception):
    """
    Wraps around errors returned by AFIP's WS.
    """

    def __init__(self, err):
        Exception.__init__(self, "Error {}: {}".format(
            err.Code,
            encode_str(err.Msg),
        ))

class AfipMultiException(Exception):
    """
    Wraps around multiple errors returned by AFIP's WS.
    """

    def __init__(self, errs):
        msg = "".join([
            "Error {}: {}".format(
                err.Code,
                encode_str(err.Msg),
            ) for err in errs
        ])

        Exception.__init__(self, msg)

endpoints = {}
if settings.AFIP_DEBUG:
    endpoints['wsaa'] = "https://wsaahomo.afip.gov.ar/ws/services/LoginCms?wsdl"  # NOQA
    endpoints['wsfe'] = "https://wswhomo.afip.gov.ar/wsfev1/service.asmx?WSDL"
else:
    endpoints['wsaa'] = "https://wsaa.afip.gov.ar/ws/services/LoginCms?wsdl"
    endpoints['wsfe'] = "https://servicios1.afip.gov.ar/wsfev1/service.asmx?WSDL"  # NOQA

class WsaaClient(LazyObject):

    def _setup(self):
        self._wrapped = Client(endpoints['wsaa'])

class WsfeClient(LazyObject):

    def _setup(self):
        self._wrapped = Client(endpoints['wsfe'])

wsaa_client = WsaaClient()
wsfe_client = WsfeClient()
<commit_msg>Handle dates being null properly<commit_after>from datetime import datetime

from django.conf import settings
from django.utils.functional import LazyObject
from suds import Client
import pytz

def format_datetime(datetime):
    """
    "Another date formatting function?" you're thinking, eh? Well, this
    actually formats dates in the *exact* format the AFIP's WS expects it,
    which is almost like ISO8601.

    Note that .isoformat() works fine on PROD, but not on TESTING.
    """
    return datetime.strftime("%Y-%m-%dT%H:%M:%S-00:00")

def format_date(date):
    return date.strftime("%Y%m%d")

def parse_datetime(datestring):
    if datestring == 'NULL' or datestring is None:
        return None
    return datetime.strptime(datestring, '%Y%m%d%H%M%S') \
        .replace(tzinfo=pytz.timezone(pytz.country_timezones['ar'][0]))

def parse_date(datestring):
    if datestring == 'NULL' or datestring is None:
        return None
    return datetime.strptime(datestring, '%Y%m%d').date()

def encode_str(string):
    """
    Re-encodes strings from AFIP's weird encoding to unicode.
    """
    return string.encode('latin-1').decode()

class AfipException(Exception):
    """
    Wraps around errors returned by AFIP's WS.
    """

    def __init__(self, err):
        Exception.__init__(self, "Error {}: {}".format(
            err.Code,
            encode_str(err.Msg),
        ))

class AfipMultiException(Exception):
    """
    Wraps around multiple errors returned by AFIP's WS.
    """

    def __init__(self, errs):
        msg = "".join([
            "Error {}: {}".format(
                err.Code,
                encode_str(err.Msg),
            ) for err in errs
        ])

        Exception.__init__(self, msg)

endpoints = {}
if settings.AFIP_DEBUG:
    endpoints['wsaa'] = "https://wsaahomo.afip.gov.ar/ws/services/LoginCms?wsdl"  # NOQA
    endpoints['wsfe'] = "https://wswhomo.afip.gov.ar/wsfev1/service.asmx?WSDL"
else:
    endpoints['wsaa'] = "https://wsaa.afip.gov.ar/ws/services/LoginCms?wsdl"
    endpoints['wsfe'] = "https://servicios1.afip.gov.ar/wsfev1/service.asmx?WSDL"  # NOQA

class WsaaClient(LazyObject):

    def _setup(self):
        self._wrapped = Client(endpoints['wsaa'])

class WsfeClient(LazyObject):

    def _setup(self):
        self._wrapped = Client(endpoints['wsfe'])

wsaa_client = WsaaClient()
wsfe_client = WsfeClient()
<|endoftext|>


<commit_before>import os
import sys
from django import get_version

myPath = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, myPath)

VERSION = (0, 7, 18)

default_app_config = 'django_q.apps.DjangoQConfig'

# root imports will slowly be deprecated.
# please import from the relevant sub modules
split_version = get_version().split('.')
if split_version[1][0] != '9' and split_version[1][:2] != '10':
    from .tasks import async, schedule, result, result_group, fetch, fetch_group, count_group, delete_group, queue_size
    from .models import Task, Schedule, Success, Failure
    from .cluster import Cluster
    from .status import Stat
    from .brokers import get_broker

__all__ = ['conf', 'cluster', 'models', 'tasks']
<commit_msg>Add django 1.11 to the import check<commit_after>import os
import sys
from django import get_version

myPath = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, myPath)

VERSION = (0, 7, 18)

default_app_config = 'django_q.apps.DjangoQConfig'

# root imports will slowly be deprecated.
# please import from the relevant sub modules
split_version = get_version().split('.')
if split_version[1] not in ('9', '10', '11'):
    from .tasks import async, schedule, result, result_group, fetch, fetch_group, count_group, delete_group, queue_size
    from .models import Task, Schedule, Success, Failure
    from .cluster import Cluster
    from .status import Stat
    from .brokers import get_broker

__all__ = ['conf', 'cluster', 'models', 'tasks']
<|endoftext|>


<commit_before>""" Template tags relating to tickets. """

from django import template

register = template.Library()

@register.filter(name='has_tickets')
def user_has_tickets(user, event):
    """ Return True if the user has tickets for this event. """
    return event.votes.filter(user=user).count() > 0
<commit_msg>Tickets typo<commit_after>""" Template tags relating to tickets. """

from django import template

register = template.Library()

@register.filter(name='has_tickets')
def user_has_tickets(user, event):
    """ Return True if the user has tickets for this event. """
    return event.tickets.filter(user=user).count() > 0
<|endoftext|>


<commit_before>from __future__ import absolute_import

from collections import defaultdict
from datetime import datetime, timedelta
from time import time

from django.db import transaction
from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist

from celery import states
from celery.events.state import Task
from celery.events.snapshot import Polaroid
from celery.utils.timeutils import maybe_iso8601, timezone

from .models import WorkerState, TaskState
from .utils import maybe_make_aware

WORKER_UPDATE_FREQ = 60  # limit worker timestamp write freq.
SUCCESS_STATES = frozenset([states.SUCCESS])

# Expiry can be timedelta or None for never expire.
EXPIRE_SUCCESS = getattr(settings, "CELERYCAM_EXPIRE_SUCCESS",
                         timedelta(days=1))
EXPIRE_ERROR = getattr(settings, "CELERYCAM_EXPIRE_ERROR",
                       timedelta(days=3))
EXPIRE_PENDING = getattr(settings, "CELERYCAM_EXPIRE_PENDING",
                         timedelta(days=5))
NOT_SAVED_ATTRIBUTES = frozenset(['name', 'args', 'kwargs', 'eta'])

def aware_tstamp(secs):
    """Event timestamps uses the local timezone."""
    return timezone.to_local_fallback(datetime.fromtimestamp(secs))

class Camera(Polaroid):
    TaskState = TaskState
    WorkerState = WorkerState

    clear_after = True
    worker_update_freq = WORKER_UPDATE_FREQ
    expire_states = {
            SUCCESS_STATES: EXPIRE_SUCCESS,
            states.EXCEPTION_STATES: EXPIRE_ERROR,
            states.UNREADY_STATES: EXPIRE_PENDING,
    }

    def __init__(self, *args, **kwargs):
        super(Camera, self).__init__(*args, **kwargs)
        self._last_worker_write = defaultdict(lambda: (None, None))

    def get_heartbeat(self, worker):
        try:
            heartbeat = worker.heartbeats[-1]
        except IndexError:
            return
        return aware_tstamp(heartbeat)

    def handle_worker(self, (hostname, worker)):
        last_write, obj = self._last_worker_write[hostname]
        if not last_write or time() - last_write > self.worker_update_freq:
            obj = self.WorkerState.objects.update_or_create(
                        hostname=hostname,
                        defaults={"last_heartbeat":
                            self.get_heartbeat(worker)})
            self._last_worker_write[hostname] = (time(), obj)
        return obj

    def handle_task(self, (uuid, task), worker=None):
        """Handle snapshotted event."""
        if task.worker and task.worker.hostname:
            worker = self.handle_worker((task.worker.hostname, task.worker))

        defaults = {"name": task.name,
                "args": task.args,
                "kwargs": task.kwargs,
                "eta": maybe_make_aware(maybe_iso8601(task.eta)),
                "expires": maybe_make_aware(maybe_iso8601(task.expires)),
                "state": task.state,
                "tstamp": aware_tstamp(task.timestamp),
                "result": task.result or task.exception,
                "traceback": task.traceback,
                "runtime": task.runtime,
                "worker": worker}
        # If RECEIVED event is lost, some data is lost as it is stored
        # only in RECEIVED event for efficiency. In this case we just
        # do not overwrite this fields in TaskState instance row
        [defaults.pop(attr, None) for attr in NOT_SAVED_ATTRIBUTES
                                    if defaults[attr] is None]
        return self.update_task(task.state, task_id=uuid, defaults=defaults)

    def update_task(self, state, **kwargs):
        objects = self.TaskState.objects
        defaults = kwargs.pop("defaults", None) or {}
        try:
            obj = objects.get(**kwargs)
        except ObjectDoesNotExist:
            if not defaults.get("name"):
                return
            obj, created = objects.get_or_create(defaults=defaults, **kwargs)
            return obj
        else:
            if states.state(state) < states.state(obj.state):
                keep = Task.merge_rules[states.RECEIVED]
                defaults = dict((k, v)
                                    for k, v in defaults.items()
                                        if k not in keep)

        for k, v in defaults.items():
            setattr(obj, k, v)
        obj.save()

        return obj

    def _autocommit(self, fun):
        try:
            fun()
        except (KeyboardInterrupt, SystemExit):
            transaction.commit()
            raise
        except Exception:
            transaction.rollback()
            raise
        else:
            transaction.commit()

    @transaction.commit_manually
    def on_shutter(self, state, commit_every=100):
        if not state.event_count:
            transaction.commit()
            return

        def _handle_tasks():
            for i, task in enumerate(state.tasks.items()):
                self.handle_task(task)
                if not i % commit_every:
                    transaction.commit()

        self._autocommit(lambda: map(self.handle_worker,
                                     state.workers.items()))
        self._autocommit(_handle_tasks)

    def on_cleanup(self):
        dirty = sum(self.TaskState.objects.expire_by_states(states, expires)
                        for states, expires in self.expire_states.items())
        if dirty:
            self.logger.debug(
                    "Cleanup: Marked %s objects as dirty." % (dirty, ))
            self.TaskState.objects.purge()
            self.logger.debug("Cleanup: %s objects purged." % (dirty, ))
            return dirty
        return 0
<commit_msg>Maybe fix #183<commit_after>from __future__ import absolute_import

from collections import defaultdict
from datetime import datetime, timedelta
from time import time

from django.db import transaction
from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist

from celery import states
from celery.events.state import Task
from celery.events.snapshot import Polaroid
from celery.utils.timeutils import maybe_iso8601, timezone

from .models import WorkerState, TaskState
from .utils import maybe_make_aware

WORKER_UPDATE_FREQ = 60  # limit worker timestamp write freq.
SUCCESS_STATES = frozenset([states.SUCCESS])

# Expiry can be timedelta or None for never expire.
EXPIRE_SUCCESS = getattr(settings, "CELERYCAM_EXPIRE_SUCCESS",
                         timedelta(days=1))
EXPIRE_ERROR = getattr(settings, "CELERYCAM_EXPIRE_ERROR",
                       timedelta(days=3))
EXPIRE_PENDING = getattr(settings, "CELERYCAM_EXPIRE_PENDING",
                         timedelta(days=5))
NOT_SAVED_ATTRIBUTES = frozenset(['name', 'args', 'kwargs', 'eta'])

def aware_tstamp(secs):
    """Event timestamps uses the local timezone."""
    return timezone.to_local_fallback(datetime.fromtimestamp(secs))

class Camera(Polaroid):
    TaskState = TaskState
    WorkerState = WorkerState

    clear_after = True
    worker_update_freq = WORKER_UPDATE_FREQ
    expire_states = {
            SUCCESS_STATES: EXPIRE_SUCCESS,
            states.EXCEPTION_STATES: EXPIRE_ERROR,
            states.UNREADY_STATES: EXPIRE_PENDING,
    }

    def __init__(self, *args, **kwargs):
        super(Camera, self).__init__(*args, **kwargs)
        self._last_worker_write = defaultdict(lambda: (None, None))

    def get_heartbeat(self, worker):
        try:
            heartbeat = worker.heartbeats[-1]
        except IndexError:
            return
        return aware_tstamp(heartbeat)

    def handle_worker(self, (hostname, worker)):
        last_write, obj = self._last_worker_write[hostname]
        if not last_write or time() - last_write > self.worker_update_freq:
            obj = self.WorkerState.objects.update_or_create(
                        hostname=hostname,
                        defaults={"last_heartbeat":
                            self.get_heartbeat(worker)})
            self._last_worker_write[hostname] = (time(), obj)
        return obj

    def handle_task(self, (uuid, task), worker=None):
        """Handle snapshotted event."""
        if task.worker and task.worker.hostname:
            worker = self.handle_worker((task.worker.hostname, task.worker))

        defaults = {"name": task.name,
                "args": task.args,
                "kwargs": task.kwargs,
                "eta": maybe_make_aware(maybe_iso8601(task.eta)),
                "expires": maybe_make_aware(maybe_iso8601(task.expires)),
                "state": task.state,
                "tstamp": aware_tstamp(task.timestamp),
                "result": task.result or task.exception,
                "traceback": task.traceback,
                "runtime": task.runtime,
                "worker": worker}
        # If RECEIVED event is lost, some data is lost as it is stored
        # only in RECEIVED event for efficiency. In this case we just
        # do not overwrite this fields in TaskState instance row
        [defaults.pop(attr, None) for attr in NOT_SAVED_ATTRIBUTES
                                    if defaults[attr] is None]
        return self.update_task(task.state, task_id=uuid, defaults=defaults)

    def update_task(self, state, **kwargs):
        objects = self.TaskState.objects
        defaults = kwargs.pop("defaults", None) or {}
        try:
            obj = objects.get(**kwargs)
        except ObjectDoesNotExist:
            if not defaults.get("name"):
                return
            obj, created = objects.get_or_create(defaults=defaults, **kwargs)
            return obj
        else:
            if states.state(state) < states.state(obj.state):
                keep = Task.merge_rules[states.RECEIVED]
                defaults = dict((k, v)
                                    for k, v in defaults.items()
                                        if k not in keep)

        for k, v in defaults.items():
            setattr(obj, k, v)
        for datefield in ('eta', 'expires', 'tstamp'):
            # Brute force trying to fix #183
            setattr(obj, datefield, maybe_make_aware(getattr(obj, datefield)))
        obj.save()

        return obj

    def _autocommit(self, fun):
        try:
            fun()
        except (KeyboardInterrupt, SystemExit):
            transaction.commit()
            raise
        except Exception:
            transaction.rollback()
            raise
        else:
            transaction.commit()

    @transaction.commit_manually
    def on_shutter(self, state, commit_every=100):
        if not state.event_count:
            transaction.commit()
            return

        def _handle_tasks():
            for i, task in enumerate(state.tasks.items()):
                self.handle_task(task)
                if not i % commit_every:
                    transaction.commit()

        self._autocommit(lambda: map(self.handle_worker,
                                     state.workers.items()))
        self._autocommit(_handle_tasks)

    def on_cleanup(self):
        dirty = sum(self.TaskState.objects.expire_by_states(states, expires)
                        for states, expires in self.expire_states.items())
        if dirty:
            self.logger.debug(
                    "Cleanup: Marked %s objects as dirty." % (dirty, ))
            self.TaskState.objects.purge()
            self.logger.debug("Cleanup: %s objects purged." % (dirty, ))
            return dirty
        return 0
<|endoftext|>