<commit_before>
from xml.dom.minidom import *

import config
from resources import Slice, VirtualMachine, NetworkInterface, NetworkLink
import utils

def parseRequestRspec(geni_slice, rspec) :
    """ This function parses a request rspec.   SAY MORE...
        Return:
            None if successful.
            An error string if something went wrong.
    """

    # Parse the xml rspec
    rspec_dom = parseString(rspec)

    # Look for DOM elements tagged 'node'.  These are the VMs requested by the
    # experimenter.
    # For each node in the rspec, extract experimenter specified information
    node_list = rspec_dom.getElementsByTagName('node')
    for node in node_list :
        # Create a VirtualMachine object for this node and add it to the list
        # of virtual machines that belong to this slice
        vm_object = VirtualMachine(geni_slice)

        # Get information about the node from the rspec
        node_attributes = node.attributes
        if node_attributes.has_key('client_id') :
            vm_object.setName(node_attributes['client_id'].value)
        else :
            config.logger.error('Malformed rspec: Node name not specified')
            return 'Malformed rspec: Node name not specified'

        # Get interfaces associated with the node
        interface_list = node.getElementsByTagName('interface')
        for interface in interface_list :
            # Create a NetworkInterface object this interface and associate
            # it with the VirtualMachine object for the node
            interface_object = NetworkInterface(geni_slice, vm_object)
            vm_object.addNetworkInterface(interface_object)

            # Get information about this network interface from rspec
            interface_attributes = interface.attributes
            if interface_attributes.has_key('client_id') :
                interface_object.setName(interface_attributes['client_id'].value)
            else :
                config.logger.error('Malformed rspec: Interface name not specified')
                return 'Malformed rspec: Interface name not specified'

        # Get the list of services for this node (install and execute services)
        service_list = node.getElementsByTagName('service')
        # First handle all the install items in the list of services requested
        for service in service_list :
            install_list = service.getElementsByTagName('install')
            for install in install_list :
                install_attributes = install.attributes
                if not (install_attributes.has_key('url') and
                        install_attributes.has_key('install_path')) :
                    config.logger.error('Source URL or destination path missing for install element in request rspec')
                    return 'Source URL or destination path missing for install element in request rspec'

                source_url = install_attributes['url'].value
                destination = install_attribtues['install_path'].value
                if install_attributes.has_key('file_type') :
                    file_type = install_attributes['file_type'].value
                else :
                    file_type = None
                vm_object.addInstallItem(source_url, destination, file_type)

        # Next take care of the execute services requested
        for service in service_list :
            execute_list = service.getElementsByTagName('execute')
            for execute in execute_list :
                execute_attributes = execute.attributes
                if not execute_attributes.has_key('command') :
                    config.logger.error('Command missing for execute element in request rspec')
                    return 'Command missing for execute element in request rspec'

                exec_command = execute_attributes['command'].value
                if execute_attributes.has_key('shell') :
                    exec_shell = execute_attributes['shell'].value
                else :
                    exec_shell = config.default_execute_shell
                vm_object.addExecuteItem(exec_command, exec_shell)

    # Done getting information about nodes in the rspec.  Now get information
    # about links.
    link_list = rspec_dom.getElementsByTagName('link')
    for link in link_list :
        # Create a NetworkLink object for this link
        link_object = NetworkLink(geni_slice)

        # Get information about this link from the rspec
        link_attributes = link.attributes
        if link_attributes.has_key('client_id') :
            link_object.setName(link_attributes['client_id'].value)
        else :
            config.logger.error('Malformed rspec: Link name not specified')
            return 'Malformed rspec: Link name not specified'

        # Get the end-points for this link.  Each end_point is a network
        # interface
        end_points = link.getElementsByTagName('interface_ref')
        for i in range(len(end_points)) :
            end_point_attributes = end_points[i].attributes

            # get the name of the interface at this end_point
            if end_point_attributes.has_key('client_id') :
                interface_name = end_point_attributes['client_id'].value

            # Find the NetworkInterface with this interface_name
            interface_object =  \
                geni_slice.getNetworkInterfaceByName(interface_name)
            if interface_object == None :
                config.logger.error('Malformed rspec: Unknown interface_ref %s specified for link %s' % (interface_name, link_object.getName()))
                return 'Malformed rspec: Unknown interface_ref %s specified for link %s' % (interface_name, link_object.getName())

            # Set the interface to point to this link
            interface_object.setLink(link_object)

            # Associate this end point (NetworkInterface) with this link
            link_object.addEndpoint(interface_object)

    return None  # Success

def generateManifest(geni_slice, req_rspec) :
    """
        Returns a tuple that consists of:
           1. The manifest rspec for the specified request rspec (req_rspec)
           2. A list with information about each of the slivers corresponding
              to resources in the request rspec.
    """
    manifest = Document()                 # Manifest returned by this function
    sliver_stat_list = utils.SliverList() # Sliver status list returned

    # Use the request rspec as a model for the manifest i.e. start with the
    # request and add additional information to it to form the manifest
    request = parseString(req_rspec).childNodes[0]
    manifest.appendChild(request)
    request.setAttribute('type', 'manifest')

    # If the request rspec has a xsi:schemaLocation element in the header
    # set the appropriate value to say "manifest" instead of "request"
    if request.hasAttribute('xsi:schemaLocaton') :
        schema_location = request.attributes['xsi:schemaLocation'].value
        schema_location = schema_location.replace('request.xsd', 'manifest.xsd')
        request.setAttribute('xsi:schemaLocation', schema_location)
    else :
        # No attribute for xsi:schemaLocation in request.  Add it to
        # the manifest
        schema_location = 'http://www.geni.net/resources/rspec/3 http://www.geni.net/resources/rspec/3/manifest.xsd'
        request.setAttribute('xsi:schemaLocation', schema_location)

    # For every child element in the rspec, add manifest related information
    # to the child element.
    for child in request.childNodes :
        if child.nodeName == 'node' :
            # Set node attributes
            child.setAttribute('exclusive', 'false')

            # Find the VM Object for this node by node name ('client_id')
            node_name = child.attributes['client_id'].value
            vm_list = geni_slice.getVMs()
            vm_object = None
            for i in range(len(vm_list)) :
                if node_name == vm_list[i].getName() :
                    vm_object = vm_list[i]
                    break
            if vm_object == None :
                config.logger.error('Cannot find information about VM %s' % \
                                        node_name)
                continue   # Go on to next node

            # Set the sliver URN for the node element
            child.setAttribute('sliver_id', vm_object.getSliverURN())
            child.setAttribute('component_id', vm_object.getSliverURN())

            # For each child element of node, set appropriate attrbutes.
            # Child elements of node include sliver_type, services,
            # interface, etc.
            sliver_type_set=False
            for child_of_node in child.childNodes :
                if child_of_node.nodeName == 'sliver_type' :
                    sliver_type = child_of_node.attributes['name'].value
                    child.setAttribute('name', sliver_type)
                    sliver_type_set = True
                elif child_of_node.nodeName == 'interface' :
                    # Find the NetworkInterface object for this interface
                    nic_name = child_of_node.attributes['client_id'].value
                    nic_list = vm_object.getNetworkInterfaces()
                    for i in range(len(nic_list)) :
                        if nic_name == nic_list[i].getName() :
                            nic_object = nic_list[i]
                            break
                    if nic_object == None :
                        config.logger.error('Cannot find information about network interface %s' % nic_name)
                        continue
                    ip_address = nic_object.getIPAddress()
                    if ip_address != None :
                        ip_addr_elem = manifest.createElement('ip')
                        ip_addr_elem.setAttribute('address', ip_address)
                        child_of_node.appendChild(ip_addr_elem)
                    mac_address = nic_object.getMACAddress()
                    if mac_address != None :
                        child_of_node.setAttribute('mac_address', mac_address)
                    child_of_node.setAttribute('sliver_id',
                                               nic_object.getSliverURN())
            if not sliver_type_set:
                sliver_type = "virtual-machine"
                sliver_type_attribute = Element('sliver_type')
                sliver_type_attribute.setAttribute('name', sliver_type)
                child.appendChild(sliver_type_attribute)

            # Add this node to the list of slivers in this rspec
            sliver_stat_list.addSliver(vm_object)

        elif child.nodeName == 'link' :
            # Find the NetworkLink object for this link
            link_name = child.attributes['client_id'].value
            link_list = geni_slice.getNetworkLinks()
            for i in range(len(link_list)) :
                if link_name == link_list[i].getName() :
                    link_object = link_list[i]
                    break
            child.setAttribute('sliver_id', link_object.getSliverURN())

            # Add this link to the list of slivers in this rspec
            sliver_stat_list.addSliver(link_object)

    manifest = manifest.toprettyxml(indent = '    ')
    config.logger.info('Manifest = %s' % manifest)

    # Create a clean version of the manifest without the extraneous
    # spaces and newlines added my minidom
    clean_manifest = ''
    for line in manifest.split('\n') :
        if line.strip() :
            clean_manifest += line + '\n'

    config.logger.info('Clean manifest = %s' % clean_manifest)

    return clean_manifest, sliver_stat_list.getSliverStatusList()

<commit_msg>Fixed typo in comment.<commit_after>
from xml.dom.minidom import *

import config
from resources import Slice, VirtualMachine, NetworkInterface, NetworkLink
import utils

def parseRequestRspec(geni_slice, rspec) :
    """ This function parses a request rspec.   SAY MORE...
        Return:
            None if successful.
            An error string if something went wrong.
    """

    # Parse the xml rspec
    rspec_dom = parseString(rspec)

    # Look for DOM elements tagged 'node'.  These are the VMs requested by the
    # experimenter.
    # For each node in the rspec, extract experimenter specified information
    node_list = rspec_dom.getElementsByTagName('node')
    for node in node_list :
        # Create a VirtualMachine object for this node and add it to the list
        # of virtual machines that belong to this slice
        vm_object = VirtualMachine(geni_slice)

        # Get information about the node from the rspec
        node_attributes = node.attributes
        if node_attributes.has_key('client_id') :
            vm_object.setName(node_attributes['client_id'].value)
        else :
            config.logger.error('Malformed rspec: Node name not specified')
            return 'Malformed rspec: Node name not specified'

        # Get interfaces associated with the node
        interface_list = node.getElementsByTagName('interface')
        for interface in interface_list :
            # Create a NetworkInterface object this interface and associate
            # it with the VirtualMachine object for the node
            interface_object = NetworkInterface(geni_slice, vm_object)
            vm_object.addNetworkInterface(interface_object)

            # Get information about this network interface from rspec
            interface_attributes = interface.attributes
            if interface_attributes.has_key('client_id') :
                interface_object.setName(interface_attributes['client_id'].value)
            else :
                config.logger.error('Malformed rspec: Interface name not specified')
                return 'Malformed rspec: Interface name not specified'

        # Get the list of services for this node (install and execute services)
        service_list = node.getElementsByTagName('service')
        # First handle all the install items in the list of services requested
        for service in service_list :
            install_list = service.getElementsByTagName('install')
            for install in install_list :
                install_attributes = install.attributes
                if not (install_attributes.has_key('url') and
                        install_attributes.has_key('install_path')) :
                    config.logger.error('Source URL or destination path missing for install element in request rspec')
                    return 'Source URL or destination path missing for install element in request rspec'

                source_url = install_attributes['url'].value
                destination = install_attribtues['install_path'].value
                if install_attributes.has_key('file_type') :
                    file_type = install_attributes['file_type'].value
                else :
                    file_type = None
                vm_object.addInstallItem(source_url, destination, file_type)

        # Next take care of the execute services requested
        for service in service_list :
            execute_list = service.getElementsByTagName('execute')
            for execute in execute_list :
                execute_attributes = execute.attributes
                if not execute_attributes.has_key('command') :
                    config.logger.error('Command missing for execute element in request rspec')
                    return 'Command missing for execute element in request rspec'

                exec_command = execute_attributes['command'].value
                if execute_attributes.has_key('shell') :
                    exec_shell = execute_attributes['shell'].value
                else :
                    exec_shell = config.default_execute_shell
                vm_object.addExecuteItem(exec_command, exec_shell)

    # Done getting information about nodes in the rspec.  Now get information
    # about links.
    link_list = rspec_dom.getElementsByTagName('link')
    for link in link_list :
        # Create a NetworkLink object for this link
        link_object = NetworkLink(geni_slice)

        # Get information about this link from the rspec
        link_attributes = link.attributes
        if link_attributes.has_key('client_id') :
            link_object.setName(link_attributes['client_id'].value)
        else :
            config.logger.error('Malformed rspec: Link name not specified')
            return 'Malformed rspec: Link name not specified'

        # Get the end-points for this link.  Each end_point is a network
        # interface
        end_points = link.getElementsByTagName('interface_ref')
        for i in range(len(end_points)) :
            end_point_attributes = end_points[i].attributes

            # get the name of the interface at this end_point
            if end_point_attributes.has_key('client_id') :
                interface_name = end_point_attributes['client_id'].value

            # Find the NetworkInterface with this interface_name
            interface_object =  \
                geni_slice.getNetworkInterfaceByName(interface_name)
            if interface_object == None :
                config.logger.error('Malformed rspec: Unknown interface_ref %s specified for link %s' % (interface_name, link_object.getName()))
                return 'Malformed rspec: Unknown interface_ref %s specified for link %s' % (interface_name, link_object.getName())

            # Set the interface to point to this link
            interface_object.setLink(link_object)

            # Associate this end point (NetworkInterface) with this link
            link_object.addEndpoint(interface_object)

    return None  # Success

def generateManifest(geni_slice, req_rspec) :
    """
        Returns a tuple that consists of:
           1. The manifest rspec for the specified request rspec (req_rspec)
           2. A list with information about each of the slivers corresponding
              to resources in the request rspec.
    """
    manifest = Document()                 # Manifest returned by this function
    sliver_stat_list = utils.SliverList() # Sliver status list returned

    # Use the request rspec as a model for the manifest i.e. start with the
    # request and add additional information to it to form the manifest
    request = parseString(req_rspec).childNodes[0]
    manifest.appendChild(request)
    request.setAttribute('type', 'manifest')

    # If the request rspec has a xsi:schemaLocation element in the header
    # set the appropriate value to say "manifest" instead of "request"
    if request.hasAttribute('xsi:schemaLocaton') :
        schema_location = request.attributes['xsi:schemaLocation'].value
        schema_location = schema_location.replace('request.xsd', 'manifest.xsd')
        request.setAttribute('xsi:schemaLocation', schema_location)
    else :
        # No attribute for xsi:schemaLocation in request.  Add it to
        # the manifest
        schema_location = 'http://www.geni.net/resources/rspec/3 http://www.geni.net/resources/rspec/3/manifest.xsd'
        request.setAttribute('xsi:schemaLocation', schema_location)

    # For every child element in the rspec, add manifest related information
    # to the child element.
    for child in request.childNodes :
        if child.nodeName == 'node' :
            # Set node attributes
            child.setAttribute('exclusive', 'false')

            # Find the VM Object for this node by node name ('client_id')
            node_name = child.attributes['client_id'].value
            vm_list = geni_slice.getVMs()
            vm_object = None
            for i in range(len(vm_list)) :
                if node_name == vm_list[i].getName() :
                    vm_object = vm_list[i]
                    break
            if vm_object == None :
                config.logger.error('Cannot find information about VM %s' % \
                                        node_name)
                continue   # Go on to next node

            # Set the sliver URN for the node element
            child.setAttribute('sliver_id', vm_object.getSliverURN())
            child.setAttribute('component_id', vm_object.getSliverURN())

            # For each child element of node, set appropriate attrbutes.
            # Child elements of node include sliver_type, services,
            # interface, etc.
            sliver_type_set=False
            for child_of_node in child.childNodes :
                if child_of_node.nodeName == 'sliver_type' :
                    sliver_type = child_of_node.attributes['name'].value
                    child.setAttribute('name', sliver_type)
                    sliver_type_set = True
                elif child_of_node.nodeName == 'interface' :
                    # Find the NetworkInterface object for this interface
                    nic_name = child_of_node.attributes['client_id'].value
                    nic_list = vm_object.getNetworkInterfaces()
                    for i in range(len(nic_list)) :
                        if nic_name == nic_list[i].getName() :
                            nic_object = nic_list[i]
                            break
                    if nic_object == None :
                        config.logger.error('Cannot find information about network interface %s' % nic_name)
                        continue
                    ip_address = nic_object.getIPAddress()
                    if ip_address != None :
                        ip_addr_elem = manifest.createElement('ip')
                        ip_addr_elem.setAttribute('address', ip_address)
                        child_of_node.appendChild(ip_addr_elem)
                    mac_address = nic_object.getMACAddress()
                    if mac_address != None :
                        child_of_node.setAttribute('mac_address', mac_address)
                    child_of_node.setAttribute('sliver_id',
                                               nic_object.getSliverURN())
            if not sliver_type_set:
                sliver_type = "virtual-machine"
                sliver_type_attribute = Element('sliver_type')
                sliver_type_attribute.setAttribute('name', sliver_type)
                child.appendChild(sliver_type_attribute)

            # Add this node to the list of slivers in this rspec
            sliver_stat_list.addSliver(vm_object)

        elif child.nodeName == 'link' :
            # Find the NetworkLink object for this link
            link_name = child.attributes['client_id'].value
            link_list = geni_slice.getNetworkLinks()
            for i in range(len(link_list)) :
                if link_name == link_list[i].getName() :
                    link_object = link_list[i]
                    break
            child.setAttribute('sliver_id', link_object.getSliverURN())

            # Add this link to the list of slivers in this rspec
            sliver_stat_list.addSliver(link_object)

    manifest = manifest.toprettyxml(indent = '    ')
    config.logger.info('Manifest = %s' % manifest)

    # Create a clean version of the manifest without the extraneous
    # spaces and newlines added by minidom
    clean_manifest = ''
    for line in manifest.split('\n') :
        if line.strip() :
            clean_manifest += line + '\n'

    config.logger.info('Clean manifest = %s' % clean_manifest)

    return clean_manifest, sliver_stat_list.getSliverStatusList()

<|endoftext|>


<commit_before>from django.conf.urls import patterns, url

from web import views

urlpatterns = patterns('',
    url(r'^item/(?P<item_id>\d+)/$', views.item, name='item'),
    url(r'^item/gen/$', views.itemgen, name='itemgen'),
    url(r'^item/$', views.itemlist, name='itemlist'),
    url(r'^affixes/g/(?P<affixgroup_id>\d+)/$', views.affixgroup, name='affixgroup'),
    url(r'^affixes/(?P<affix_id>\d+)/$', views.affix, name='affix'),
    url(r'^affixes/$', views.affixlist, name='affixlist'),
    url(r'^$', views.index, name='index')
)

<commit_msg>changed item list view to plural, i.e. "/items/"<commit_after>from django.conf.urls import patterns, url

from web import views

urlpatterns = patterns('',
    url(r'^item/(?P<item_id>\d+)/$', views.item, name='item'),
    url(r'^item/gen/$', views.itemgen, name='itemgen'),
    url(r'^items/$', views.itemlist, name='itemlist'),
    url(r'^affixes/g/(?P<affixgroup_id>\d+)/$', views.affixgroup, name='affixgroup'),
    url(r'^affixes/(?P<affix_id>\d+)/$', views.affix, name='affix'),
    url(r'^affixes/$', views.affixlist, name='affixlist'),
    url(r'^$', views.index, name='index')
)
<|endoftext|>


<commit_before>from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.core import serializers
from django.db import transaction
from django.http import HttpResponse, HttpResponseRedirect
from django.utils import timezone
from django.contrib import auth  # .models.DoesNotExist
import os
import json
import re

from itertools import chain

from forms import NoteForm
from models import Note, Folder, HashTags
from django.contrib.auth.models import User
# Create your views here.
from datetime import datetime
from forms import NewFolderForm, UploadFileForm

import logging

from django.conf import settings
logger = logging.getLogger(__name__)
logging.config.dictConfig(settings.LOGGING)

@login_required()
def hash_tags(request):

    # putting an .exclude(notes__folder__name = 'Trash') will exclude
    # a tag that has *any* tagged note in Trash.  We want to
    # check for *all* !!  Hence the for loop.

    my_hash_tags = HashTags.objects.filter(user=request.user).order_by('hash_tag', 'notes__folder__name').distinct()
    tag_list = []
    for tag in my_hash_tags:
        if tag.notes.exclude(folder__name = 'Trash').count() > 0:
            if tag not in tag_list: tag_list.append(tag)
    context = {'tags':tag_list}
    return render(request, 'cloud_notes/hash_tags.html', context)

@login_required()
def folders(request):
    folders = Folder.objects.filter(user=request.user)
    context = {'folders':folders}
    if request.method == 'POST':
        # changing to a different folder
        if "change_folder" in request.POST:
            request.session['notes_folder'] = request.POST['folder']
            # If we are changing folders we don't
            # want to keep to what page we were on in
            # the other folder.
            if 'page' in request.session:
                del request.session['page']
            return redirect('cloud_notes.views.list')
        if "create_folder" in request.POST:
            form = NewFolderForm(request.POST)
            if form.is_valid():
                folder_name = form.cleaned_data['folder']
                folder = Folder(name = folder_name)
                folder.save()
                return redirect('cloud_notes.views.list')
            else:
                context['form'] = form
                return render(request, 'cloud_notes/folders.html', context)
    else:
        return render(request, 'cloud_notes/folders.html', context)

@login_required()
def list(request):
    if 'notes_folder' in request.session:
        folder = Folder.objects.get(pk = request.session['notes_folder'])
    else:
        folder, _ = Folder.objects.get_or_create(name = "Main", user=request.user)
        trash_folder, _ = Folder.objects.get_or_create(name = "Trash", user=request.user)

    notes_list = Note.objects.filter(folder = folder, user=request.user).\
        order_by('-modified_at')
    paginator = Paginator(notes_list, 10) # Show 10 contacts per page

    page = request.GET.get('page')

    # work with the page in session as we use the session
    # to keep track of what page we were last on.
    if page is None and 'page' in request.session:
        page = request.session['page']

    try:
        notes = paginator.page(page)
        request.session['page'] = page
    except PageNotAnInteger:
        # If page is not an integer, deliver first page.
        notes = paginator.page(1)
    except EmptyPage:
        # If page is out of range (e.g. 9999), deliver last page of results.
        notes = paginator.page(paginator.num_pages)
    context = {'notes':notes, 'folder':folder}
    return render(request, 'cloud_notes/list.html', context)

@login_required()
def preview(request, note_id):
    note = Note.objects.get(pk=note_id)
    if request.method == "POST":
        if "move_folder" in request.POST:
            folder = Folder.objects.get(pk=request.POST['folder'])
            note.folder = folder
            note.save()
            return redirect('cloud_notes.views.list')

    else:
        folders = Folder.objects.filter(user = request.user)
        context = {'note':note, 'folders':folders}
        return render(request, 'cloud_notes/preview.html', context)

@login_required()
def new_note(request):
    if request.method == 'GET':
        context = {'suppress_menu':True}
        return render(request, 'cloud_notes/new.html', context)
    elif request.method == 'POST':
        if "cancel" in request.POST:
            return redirect('cloud_notes.views.list')
        else:
            form = NoteForm(request.POST)
            context = {'form':form}

            if form.is_valid():
                # do stuff
                # ...
                if 'notes_folder' in request.session:
                    fldr = Folder.objects.get(pk=request.session['notes_folder'], user=request.user)
                else:
                    fldr = Folder.objects.get(name="Main", user=request.user)
                obj = Note()
                obj.title = form.cleaned_data['title']
                obj.note = form.cleaned_data['note']
                obj.post_type = 'note'
                obj.created_at = datetime.utcnow()
                obj.modified_at = datetime.utcnow()
                obj.user = request.user
                obj.folder = fldr
                obj.save()

                return redirect('cloud_notes.views.list')
            else:
                print form.errors
                return render(request, 'cloud_notes/new.html', context)

@login_required()
def edit_note(request, note_id):
    if request.method == 'POST':
        if "save" in request.POST:
            note = Note.objects.get(pk=note_id)
            note.title = request.POST['title']
            note.note = request.POST['note']
            note.modified_at = timezone.now()
            note.save()
        else:
            print "note not saved"
        return redirect('cloud_notes.views.preview', note_id)
    else: # GET
        note = Note.objects.get(pk=note_id)
        form = NoteForm(note)
        context = {'form':form, 'suppress_menu':True}
        return render(request, 'cloud_notes/new.html', context)

@login_required()
def trash_note(request, note_id):
    trash = Folder.objects.get(name="Trash", user=request.user)
    note = Note.objects.get(pk=note_id)
    note.folder = trash
    note.save()
    return redirect('cloud_notes.views.list')

@login_required()
def delete_note(request, note_id):
    note = Note.objects.get(pk=note_id)
    note.delete()
    return redirect('cloud_notes.views.list')

@login_required()
def empty_trash(request):
    if request.method == "POST":
        if request.POST.has_key('EmptyTrash'):
            trash = Folder.objects.get(user=request.user, name="Trash")
            trash.note_set.all().delete()
            return redirect("cloud_notes.views.list")
    else: # GET
        return render(request, "cloud_notes/empty_trash.html")

def serialize_notes(notes):
    note_list = []
    for note in notes:
        note_dict = {}

        note_dict['created_at'] = str(note.created_at )
        note_dict['modified_at'] = str(note.modified_at)
        note_dict['post_type'] = note.note_type
        note_dict['title'] = note.title
        note_dict['note'] = note.note
        note_dict['folder'] = note.folder.name
        try:
            note_dict['user']  = note.user.username
        except Exception as e:
            # Convoluted catch of models.DoesNotExist exception because its an
            # instance exception only but is not present in its
            # proper normal class when note.user == None (which is a data violation anyway)
            if 'DoesNotExist' == e.__class__.__name__:
                note_dict['user']  = None
            else:
                raise e
        note_list.append(note_dict)

    data_version = 0.11

    data = [ data_version, note_list ] # data version 0.1
    note_data = json.dumps(data)
    return note_data

@login_required()
def export(request):
    context = {}
    notes = Note.objects.filter(user=request.user)
    all_data = serialize_notes(notes)
    response = HttpResponse(all_data, content_type='application/json')
    response['Content-Disposition'] = 'attachment; filename="notes.json"'
    return response

@login_required()
def export_all(request):
    if request.user.is_superuser:
        note_list = []
        notes = Note.objects.all()
        all_data = serialize_notes(notes)
        response = HttpResponse(all_data, content_type='application/json')
        response['Content-Disposition'] = \
            "attachment; filename=\"all_notes.json\""
        return response

@login_required()
def import_all(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        context = {'form':form}
        if form.is_valid():
            handle_uploaded_json_file(request.FILES['file'], request.user)
            return redirect('cloud_notes.views.list')
    else:
        form = UploadFileForm()
        context = {'form':form}
    return render(request, 'cloud_notes/import_file.html', context)

@login_required()
def import_file(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        context = {'form':form}
        if form.is_valid():
            handle_uploaded_json_file(request.FILES['file'], request.user)
            return redirect('cloud_notes.views.list')
    else:
        form = UploadFileForm()
        context = {'form':form}
    return render(request, 'cloud_notes/import_file.html', context)

@transaction.atomic
def handle_uploaded_json_file(f, user):

    def convert_date(str_date):
        new_str = str_date.replace('+00:00','')
        try:
            new_dt = datetime.strptime(new_str, '%Y-%m-%d %H:%M:%S.%f')
        except ValueError:
            new_dt = datetime.strptime(new_str, '%Y-%m-%d %H:%M:%S')
        return new_dt

    with open('notes.json', 'wb+') as destination:
        for chunk in f.chunks():
            destination.write(chunk)
        f.close()
    with open('notes.json', 'r') as fh:
        json_data = json.load(fh)
        fh.close()

    version, notes = json_data

    # for user in User.objects.all():
        # if not Folder.)objects.filter(user = user, name = "Main").exists():
            # folder = Folder(name="Main", user = user)
            # folder.save()
        # if not Folder.objects.filter(user = user, name = ")Trash").exists():
            # folder = Folder(name="Trash", user = u)ser)
            # folder.save()

    for note in notes:
        created_at = convert_date(note['created_at'])
        title = note['title']
        username = note['user']

        # TODO: If user is blank we need to assign to a default user.  For now just skip.
        # Its technically a database integrity violation anyway.
        if username is None: continue

        user = User.objects.get(username = username)

        if not Note.objects.filter(title = title,
                               created_at = created_at).exists():
            new_note = Note()
            new_note.title =  title
            new_note.created_at = created_at
            new_note.modified_at = convert_date(note['modified_at'])
            new_note.note_type = note['post_type']
            new_note.note = note['note']
            foldr = note['folder']

            try:
                folder = Folder.objects.get(name = foldr, user = user)
            except Folder.DoesNotExist:
                folder = Folder(name = foldr, user = user)
                folder.save()
            new_note.folder = folder
            new_note.user = user
            new_note.save()

@login_required()
def download(request, id):
    context = {}
    # TODO: I am failing to check I own the note here!!
    note = get_object_or_404(Note, pk=id)
    content = note.note
    data = "##> ID : %d\n" % (note.id,)
    data += "##> Title : %s\n" % (note.title,)
    data += "##> Do NOT remove these lines if you plan to re-upload.  \n"
    data += "##> They will be removed automatically upon re-upload\n"
    data += content

    response = HttpResponse(data, content_type='text/plain')
    response['Content-Disposition'] = 'attachment; filename="notes_%d.txt"' % (note.id,)
    return response

def handle_uploaded_file(f, user):
    if f.content_type != 'text/plain':
        raise Exception('Invalid File Type')
    filename = 'notes_%s.txt' % (user.username,)
    with open(filename, 'wb+') as destination:
        for chunk in f.chunks():
            destination.write(chunk)
        f.close()
    with open(filename, 'r') as fh:
        id = None
        s = ""
        for line in fh.readlines():
            print (line)
            if line.startswith('##>'):
                mch = re.search(r"ID :\s+(\d+)", line)
                if mch:
                    id = int(mch.group(1))
            else:
                s += line
        if not id:
            raise Exception('Improperly formatted uploaded file')
        return (id, s)

@login_required()
def upload_note(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        context = {'form':form}
        if form.is_valid():
            id, note_contents = handle_uploaded_file(request.FILES['file'], request.user)
            note = get_object_or_404(Note, pk=id)
            note.note = note_contents
            note.save()
            return redirect('cloud_notes.views.preview', id)
    else:
        form = UploadFileForm()
        context = {'form':form}
    return render(request, 'cloud_notes/import_file.html', context)

<commit_msg>Stop notes from being inadvertently created in Trash folder<commit_after>from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.core import serializers
from django.db import transaction
from django.http import HttpResponse, HttpResponseRedirect
from django.utils import timezone
from django.contrib import auth  # .models.DoesNotExist
import os
import json
import re

from itertools import chain

from forms import NoteForm
from models import Note, Folder, HashTags
from django.contrib.auth.models import User
# Create your views here.
from datetime import datetime
from forms import NewFolderForm, UploadFileForm

import logging

from django.conf import settings
logger = logging.getLogger(__name__)
logging.config.dictConfig(settings.LOGGING)

@login_required()
def hash_tags(request):

    # putting an .exclude(notes__folder__name = 'Trash') will exclude
    # a tag that has *any* tagged note in Trash.  We want to
    # check for *all* !!  Hence the for loop.

    my_hash_tags = HashTags.objects.filter(user=request.user).order_by('hash_tag', 'notes__folder__name').distinct()
    tag_list = []
    for tag in my_hash_tags:
        if tag.notes.exclude(folder__name = 'Trash').count() > 0:
            if tag not in tag_list: tag_list.append(tag)
    context = {'tags':tag_list}
    return render(request, 'cloud_notes/hash_tags.html', context)

@login_required()
def folders(request):
    folders = Folder.objects.filter(user=request.user)
    context = {'folders':folders}
    if request.method == 'POST':
        # changing to a different folder
        if "change_folder" in request.POST:
            request.session['notes_folder'] = request.POST['folder']
            # If we are changing folders we don't
            # want to keep to what page we were on in
            # the other folder.
            if 'page' in request.session:
                del request.session['page']
            return redirect('cloud_notes.views.list')
        if "create_folder" in request.POST:
            form = NewFolderForm(request.POST)
            if form.is_valid():
                folder_name = form.cleaned_data['folder']
                folder = Folder(name = folder_name)
                folder.save()
                return redirect('cloud_notes.views.list')
            else:
                context['form'] = form
                return render(request, 'cloud_notes/folders.html', context)
    else:
        return render(request, 'cloud_notes/folders.html', context)

@login_required()
def list(request):
    if 'notes_folder' in request.session:
        folder = Folder.objects.get(pk = request.session['notes_folder'])
    else:
        folder, _ = Folder.objects.get_or_create(name = "Main", user=request.user)
        trash_folder, _ = Folder.objects.get_or_create(name = "Trash", user=request.user)

    notes_list = Note.objects.filter(folder = folder, user=request.user).\
        order_by('-modified_at')
    paginator = Paginator(notes_list, 10) # Show 10 contacts per page

    page = request.GET.get('page')

    # work with the page in session as we use the session
    # to keep track of what page we were last on.
    if page is None and 'page' in request.session:
        page = request.session['page']

    try:
        notes = paginator.page(page)
        request.session['page'] = page
    except PageNotAnInteger:
        # If page is not an integer, deliver first page.
        notes = paginator.page(1)
    except EmptyPage:
        # If page is out of range (e.g. 9999), deliver last page of results.
        notes = paginator.page(paginator.num_pages)
    context = {'notes':notes, 'folder':folder}
    return render(request, 'cloud_notes/list.html', context)

@login_required()
def preview(request, note_id):
    note = Note.objects.get(pk=note_id)
    if request.method == "POST":
        if "move_folder" in request.POST:
            folder = Folder.objects.get(pk=request.POST['folder'])
            note.folder = folder
            note.save()
            return redirect('cloud_notes.views.list')

    else:
        folders = Folder.objects.filter(user = request.user)
        context = {'note':note, 'folders':folders}
        return render(request, 'cloud_notes/preview.html', context)

@login_required()
def new_note(request):
    if request.method == 'GET':
        context = {'suppress_menu':True}
        return render(request, 'cloud_notes/new.html', context)
    elif request.method == 'POST':
        if "cancel" in request.POST:
            return redirect('cloud_notes.views.list')
        else:
            form = NoteForm(request.POST)
            context = {'form':form}

            if form.is_valid():
                # do stuff
                # ...
                if 'notes_folder' in request.session:
                    fldr = Folder.objects.get(pk=request.session['notes_folder'], user=request.user)
                else:
                    fldr = Folder.objects.get(name="Main", user=request.user)

                # Don't allow user to inadvertently create note in Trash
                if fldr.name == 'Trash':
                    fldr = Folder.objects.get(name="Main", user=request.user)

                obj = Note()
                obj.title = form.cleaned_data['title']
                obj.note = form.cleaned_data['note']
                obj.post_type = 'note'
                obj.created_at = datetime.utcnow()
                obj.modified_at = datetime.utcnow()
                obj.user = request.user
                obj.folder = fldr
                obj.save()

                return redirect('cloud_notes.views.list')
            else:
                print form.errors
                return render(request, 'cloud_notes/new.html', context)

@login_required()
def edit_note(request, note_id):
    if request.method == 'POST':
        if "save" in request.POST:
            note = Note.objects.get(pk=note_id)
            note.title = request.POST['title']
            note.note = request.POST['note']
            note.modified_at = timezone.now()
            note.save()
        else:
            print "note not saved"
        return redirect('cloud_notes.views.preview', note_id)
    else: # GET
        note = Note.objects.get(pk=note_id)
        form = NoteForm(note)
        context = {'form':form, 'suppress_menu':True}
        return render(request, 'cloud_notes/new.html', context)

@login_required()
def trash_note(request, note_id):
    trash = Folder.objects.get(name="Trash", user=request.user)
    note = Note.objects.get(pk=note_id)
    note.folder = trash
    note.save()
    return redirect('cloud_notes.views.list')

@login_required()
def delete_note(request, note_id):
    note = Note.objects.get(pk=note_id)
    note.delete()
    return redirect('cloud_notes.views.list')

@login_required()
def empty_trash(request):
    if request.method == "POST":
        if request.POST.has_key('EmptyTrash'):
            trash = Folder.objects.get(user=request.user, name="Trash")
            trash.note_set.all().delete()
            return redirect("cloud_notes.views.list")
    else: # GET
        return render(request, "cloud_notes/empty_trash.html")

def serialize_notes(notes):
    note_list = []
    for note in notes:
        note_dict = {}

        note_dict['created_at'] = str(note.created_at )
        note_dict['modified_at'] = str(note.modified_at)
        note_dict['post_type'] = note.note_type
        note_dict['title'] = note.title
        note_dict['note'] = note.note
        note_dict['folder'] = note.folder.name
        try:
            note_dict['user']  = note.user.username
        except Exception as e:
            # Convoluted catch of models.DoesNotExist exception because its an
            # instance exception only but is not present in its
            # proper normal class when note.user == None (which is a data violation anyway)
            if 'DoesNotExist' == e.__class__.__name__:
                note_dict['user']  = None
            else:
                raise e
        note_list.append(note_dict)

    data_version = 0.11

    data = [ data_version, note_list ] # data version 0.1
    note_data = json.dumps(data)
    return note_data

@login_required()
def export(request):
    context = {}
    notes = Note.objects.filter(user=request.user)
    all_data = serialize_notes(notes)
    response = HttpResponse(all_data, content_type='application/json')
    response['Content-Disposition'] = 'attachment; filename="notes.json"'
    return response

@login_required()
def export_all(request):
    if request.user.is_superuser:
        note_list = []
        notes = Note.objects.all()
        all_data = serialize_notes(notes)
        response = HttpResponse(all_data, content_type='application/json')
        response['Content-Disposition'] = \
            "attachment; filename=\"all_notes.json\""
        return response

@login_required()
def import_all(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        context = {'form':form}
        if form.is_valid():
            handle_uploaded_json_file(request.FILES['file'], request.user)
            return redirect('cloud_notes.views.list')
    else:
        form = UploadFileForm()
        context = {'form':form}
    return render(request, 'cloud_notes/import_file.html', context)

@login_required()
def import_file(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        context = {'form':form}
        if form.is_valid():
            handle_uploaded_json_file(request.FILES['file'], request.user)
            return redirect('cloud_notes.views.list')
    else:
        form = UploadFileForm()
        context = {'form':form}
    return render(request, 'cloud_notes/import_file.html', context)

@transaction.atomic
def handle_uploaded_json_file(f, user):

    def convert_date(str_date):
        new_str = str_date.replace('+00:00','')
        try:
            new_dt = datetime.strptime(new_str, '%Y-%m-%d %H:%M:%S.%f')
        except ValueError:
            new_dt = datetime.strptime(new_str, '%Y-%m-%d %H:%M:%S')
        return new_dt

    with open('notes.json', 'wb+') as destination:
        for chunk in f.chunks():
            destination.write(chunk)
        f.close()
    with open('notes.json', 'r') as fh:
        json_data = json.load(fh)
        fh.close()

    version, notes = json_data

    # for user in User.objects.all():
        # if not Folder.)objects.filter(user = user, name = "Main").exists():
            # folder = Folder(name="Main", user = user)
            # folder.save()
        # if not Folder.objects.filter(user = user, name = ")Trash").exists():
            # folder = Folder(name="Trash", user = u)ser)
            # folder.save()

    for note in notes:
        created_at = convert_date(note['created_at'])
        title = note['title']
        username = note['user']

        # TODO: If user is blank we need to assign to a default user.  For now just skip.
        # Its technically a database integrity violation anyway.
        if username is None: continue

        user = User.objects.get(username = username)

        if not Note.objects.filter(title = title,
                               created_at = created_at).exists():
            new_note = Note()
            new_note.title =  title
            new_note.created_at = created_at
            new_note.modified_at = convert_date(note['modified_at'])
            new_note.note_type = note['post_type']
            new_note.note = note['note']
            foldr = note['folder']

            try:
                folder = Folder.objects.get(name = foldr, user = user)
            except Folder.DoesNotExist:
                folder = Folder(name = foldr, user = user)
                folder.save()
            new_note.folder = folder
            new_note.user = user
            new_note.save()

@login_required()
def download(request, id):
    context = {}
    # TODO: I am failing to check I own the note here!!
    note = get_object_or_404(Note, pk=id)
    content = note.note
    data = "##> ID : %d\n" % (note.id,)
    data += "##> Title : %s\n" % (note.title,)
    data += "##> Do NOT remove these lines if you plan to re-upload.  \n"
    data += "##> They will be removed automatically upon re-upload\n"
    data += content

    response = HttpResponse(data, content_type='text/plain')
    response['Content-Disposition'] = 'attachment; filename="notes_%d.txt"' % (note.id,)
    return response

def handle_uploaded_file(f, user):
    if f.content_type != 'text/plain':
        raise Exception('Invalid File Type')
    filename = 'notes_%s.txt' % (user.username,)
    with open(filename, 'wb+') as destination:
        for chunk in f.chunks():
            destination.write(chunk)
        f.close()
    with open(filename, 'r') as fh:
        id = None
        s = ""
        for line in fh.readlines():
            print (line)
            if line.startswith('##>'):
                mch = re.search(r"ID :\s+(\d+)", line)
                if mch:
                    id = int(mch.group(1))
            else:
                s += line
        if not id:
            raise Exception('Improperly formatted uploaded file')
        return (id, s)

@login_required()
def upload_note(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        context = {'form':form}
        if form.is_valid():
            id, note_contents = handle_uploaded_file(request.FILES['file'], request.user)
            note = get_object_or_404(Note, pk=id)
            note.note = note_contents
            note.save()
            return redirect('cloud_notes.views.preview', id)
    else:
        form = UploadFileForm()
        context = {'form':form}
    return render(request, 'cloud_notes/import_file.html', context)

<|endoftext|>


<commit_before>#!/usr/bin/python

import ConfigParser
import commands
import telebot
from telebot import types
import time
import unicodedata

knownUsers = []
userStep = {}

commandsbot = {
              'ayuda': 'Informacion de comandos disponibles',
              'mensaje': 'Enviar mensaje para reproducir en el repetidor',
              'sonido': 'Ultimo mensaje que se envio a traves del repetidor',
              'sstv': 'Ultima fotografia que se decodifico por SSTV',
              'estado': 'Estado del sistema'
}

user_dict = {}

class User:
    def __init__(self, callsign):
        self.callsign = callsign
        self.announcement = None

hideBoard = types.ReplyKeyboardHide()

def listener(messages):
    for m in messages:
        if m.content_type == 'text':
            print str(m.chat.first_name) + " [" + str(m.chat.id) + "]: " + m.text

configuration = ConfigParser.ConfigParser()
configuration.read('configuration/services.config')
token = configuration.get('telegram','token')
bot = telebot.TeleBot(token)
bot.set_update_listener(listener)

@bot.message_handler(commands=['ayuda'])
def command_help(m):
    cid = m.chat.id
    help_text = "Los siguientes comandos estan disponibles: \n"
    for key in commandsbot:
        help_text += "/" + key + ": "
        help_text += commandsbot[key] + "\n"
    bot.send_message(cid, help_text)

@bot.message_handler(commands=["mensaje"])
def command_message(m):
    msg = bot.reply_to(m, "Hola, cual es tu indicativo?")
    bot.register_next_step_handler(msg, process_message)

def process_message(m):
    try:
        chat_id = m.chat.id
        callsign = m.text
        user = User(callsign)
        user_dict[chat_id] = user
        msg = bot.reply_to(m, 'Que anuncio quieres enviar?')
        bot.register_next_step_handler(msg, process_message_repeater)
    except Exception as e:
        bot.reply_to(m, 'Algo no esta funcionando!')

def process_message_repeater(m):
    try:
        chat_id = m.chat.id
        announcement = m.text
        user = user_dict[chat_id]
        user.announcement = announcement
        bot.send_message(chat_id, 'Gracias *' + user.callsign + \
                                  '*!\nAnuncio: _' + user.announcement + '_', \
                                  parse_mode="Markdown")
        repeater = 'python nuupxe.py -v \"Anuncio recibido desde Telegram\"'
        status, output = commands.getstatusoutput(repeater)
        repeater = 'python nuupxe.py -p \"' + user.callsign + '\"'
        status, output = commands.getstatusoutput(repeater)
        repeater = 'python nuupxe.py -v \"' + user.announcement + '\"'
        status, output = commands.getstatusoutput(repeater)
    except Exception as e:
        bot.reply_to(m, 'Algo no esta funcionando!')

@bot.message_handler(commands=["sonido"])
def command_sound(m):
    cid =  m.chat.id
    audio = open('output/voicerss.mp3', 'rb')
    bot.send_audio(cid, audio)

@bot.message_handler(commands=['sstv'])
def command_sstv(m):
    cid = m.chat.id
    bot.send_photo(cid, open('output/bing.jpg', 'rb'),
                   reply_markup=hideBoard)

@bot.message_handler(commands=["estado"])
def command_status(m):
    bot.reply_to(m, "Estoy vivo!")

#@bot.message_handler(func=lambda message: True, content_types=['text'])
#def command_default(m):
#    bot.send_message(m.chat.id, "Hola! No creo conocer tu comando \"" + m.text + "\"\nQue tal si pides ayuda con /help")

bot.polling()
<commit_msg>Core: Telegram Bot Accents<commit_after>#!/usr/bin/python

import ConfigParser
import commands
import telebot
from telebot import types
import time
import unicodedata

knownUsers = []
userStep = {}

commandsbot = {
              'ayuda': 'Informacion de comandos disponibles',
              'mensaje': 'Enviar mensaje para reproducir en el repetidor',
              'sonido': 'Ultimo mensaje que se envio a traves del repetidor',
              'sstv': 'Ultima fotografia que se decodifico por SSTV',
              'estado': 'Estado del sistema'
}

user_dict = {}

class User:
    def __init__(self, callsign):
        self.callsign = callsign
        self.announcement = None

hideBoard = types.ReplyKeyboardHide()

def remove_accents(input_str):
    nfkd_form = unicodedata.normalize('NFKD', input_str)
    return u"".join([c for c in nfkd_form if not unicodedata.combining(c)])

def listener(messages):
    for m in messages:
        if m.content_type == 'text':
            print str(m.chat.first_name) + " [" + str(m.chat.id) + "]: " + m.text

configuration = ConfigParser.ConfigParser()
configuration.read('configuration/services.config')
token = configuration.get('telegram','token')
bot = telebot.TeleBot(token)
bot.set_update_listener(listener)

@bot.message_handler(commands=['ayuda'])
def command_help(m):
    cid = m.chat.id
    help_text = "Los siguientes comandos estan disponibles: \n"
    for key in commandsbot:
        help_text += "/" + key + ": "
        help_text += commandsbot[key] + "\n"
    bot.send_message(cid, help_text)

@bot.message_handler(commands=["mensaje"])
def command_message(m):
    msg = bot.reply_to(m, "Hola, cual es tu indicativo?")
    bot.register_next_step_handler(msg, process_message)

def process_message(m):
    try:
        chat_id = m.chat.id
        callsign = m.text
        user = User(callsign)
        user_dict[chat_id] = user
        msg = bot.reply_to(m, 'Que anuncio quieres enviar?')
        bot.register_next_step_handler(msg, process_message_repeater)
    except Exception as e:
        bot.reply_to(m, 'Algo no esta funcionando!')

def process_message_repeater(m):
    try:
        chat_id = m.chat.id
        announcement = remove_accents(m.text)
        user = user_dict[chat_id]
        user.announcement = announcement
        bot.send_message(chat_id, 'Gracias *' + user.callsign + \
                                  '*!\nAnuncio: _' + user.announcement + '_', \
                                  parse_mode="Markdown")
        repeater = 'python nuupxe.py -v \"Anuncio recibido desde Telegram\"'
        status, output = commands.getstatusoutput(repeater)
        repeater = 'python nuupxe.py -p \"' + user.callsign + '\"'
        status, output = commands.getstatusoutput(repeater)
        repeater = 'python nuupxe.py -v \"' + user.announcement + '\"'
        status, output = commands.getstatusoutput(repeater)
    except Exception as e:
        bot.reply_to(m, 'Algo no esta funcionando!')

@bot.message_handler(commands=["sonido"])
def command_sound(m):
    cid =  m.chat.id
    audio = open('output/voicerss.mp3', 'rb')
    bot.send_audio(cid, audio)

@bot.message_handler(commands=['sstv'])
def command_sstv(m):
    cid = m.chat.id
    bot.send_photo(cid, open('output/bing.jpg', 'rb'),
                   reply_markup=hideBoard)

@bot.message_handler(commands=["estado"])
def command_status(m):
    bot.reply_to(m, "Estoy vivo!")

#@bot.message_handler(func=lambda message: True, content_types=['text'])
#def command_default(m):
#    bot.send_message(m.chat.id, "Hola! No creo conocer tu comando \"" + m.text + "\"\nQue tal si pides ayuda con /help")

bot.polling()
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
#
# weestats.py, version 0.2 for WeeChat version 0.3
# Latest development version: https://github.com/FiXato/weechat_scripts
#
# Inserts some statistics into your input field about the buffers/windows
#  you have open.
# Example: 9 windows used. 70 (of which 12 merged) buffers open: 1 core,
#  1 xfer, 2 python, 3 perl, 47 irc channels, 7 irc servers, 9 irc queries
#
## History:
### 2012-03-29: FiXato:
#
# * version 0.1: initial release.
#     * Display a count of all the different buffers you have open.
#     * Display a count of all the open windows.
# * version 0.2: Getting the splits.
#     * Displays the how many vertical and horizontal windows.
#       (not quite sure if my approximation is correct though..)
#
## Acknowledgements:
# * Sebastien "Flashcode" Helleu, for developing the kick-ass chat/IRC
#    client WeeChat
#
## TODO:
#   - Add more statistics, such as:
#     - average and total history lines.
#     - average and total topic/title lengths
#     - how many are displayed in a window
#
## Copyright (c) 2012 Filip H.F. "FiXato" Slagter,
#   <FiXato+WeeChat [at] Gmail [dot] com>
#   https://google.com/profiles/FiXato
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
SCRIPT_NAME     = "weestats"
SCRIPT_AUTHOR   = "Filip H.F. 'FiXato' Slagter <fixato [at] gmail [dot] com>"
SCRIPT_VERSION  = "0.2"
SCRIPT_LICENSE  = "MIT"
SCRIPT_DESC     = "Useless statistics about your open buffers and windows"
SCRIPT_COMMAND  = "weestats"
SCRIPT_CLOSE_CB = "close_cb"

import_ok = True

try:
  import weechat as w
except ImportError:
  print "This script must be run under WeeChat."
  import_ok = False

def close_cb(*kwargs):
  return w.WEECHAT_RC_OK

def command_main(data, buffer, args):
  infolist = w.infolist_get("buffer", "", "")
  buffer_groups = {}
  results = []
  buffer_count = 0
  merge_count = 0
  numbers = set()
  while w.infolist_next(infolist):
    bplugin = w.infolist_string(infolist, "plugin_name")
    bname = w.infolist_string(infolist, "name")
    bpointer = w.infolist_pointer(infolist, "pointer")
    bnumber = w.infolist_integer(infolist, "number")
    if not bnumber in numbers:
      numbers.add(bnumber)
    else:
      merge_count += 1
    btype = bplugin
    if bplugin == 'irc':
      if  'server.' in bname:
        btype = '%s servers' % btype
      elif '#' in bname:
        btype = '%s channels' % btype
      else:
        btype = '%s queries' % btype

    buffer_groups.setdefault(btype,[]).append({'name': bname, 'pointer': bpointer})

  w.infolist_free(infolist)

  infolist = w.infolist_get("window", "", "")
  windows_v = set()
  windows_h = set()
  windows = set()
  while w.infolist_next(infolist):
    window = w.infolist_pointer(infolist, "pointer")
    window_w = w.infolist_integer(infolist, "width_pct")
    window_h = w.infolist_integer(infolist, "height_pct")
    windows.add(window)
    if window_h == 100 and window_w != 100:
      windows_v.add(window)
    elif window_w == 100 and window_h != 100:
      windows_h.add(window)
    #else: #both 100%, thus no splits

  window_count = len(windows)

  for bplugin, buffers in buffer_groups.iteritems():
    buffer_count += len(buffers)
    results.append('%i %s' % (len(buffers), bplugin))

  buffer_stats = ', '.join(sorted(results))
  stats_string = '%i windows used (%i vertically / %i horizontally split). %i (of which %i merged) buffers open: %s' % (window_count, len(windows_v), len(windows_h), buffer_count, merge_count, buffer_stats)
  w.command("", "/input insert %s" % stats_string)
  return w.WEECHAT_RC_OK

if __name__ == "__main__" and import_ok:
  if w.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION,
                      SCRIPT_LICENSE, SCRIPT_DESC, SCRIPT_CLOSE_CB, ""):

    w.hook_command(SCRIPT_COMMAND,
                          SCRIPT_DESC,
                          "",
                          "Inserts useless statistics about your open windows and buffers into your input line.\n",

                          "",

                          "command_main", "")
<commit_msg>[weestats.py] Bugfix: forgot to release the second infolist.<commit_after># -*- coding: utf-8 -*-
#
# weestats.py, version 0.2 for WeeChat version 0.3
# Latest development version: https://github.com/FiXato/weechat_scripts
#
# Inserts some statistics into your input field about the buffers/windows
#  you have open.
# Example: 9 windows used. 70 (of which 12 merged) buffers open: 1 core,
#  1 xfer, 2 python, 3 perl, 47 irc channels, 7 irc servers, 9 irc queries
#
## History:
### 2012-03-29: FiXato:
#
# * version 0.1: initial release.
#     * Display a count of all the different buffers you have open.
#     * Display a count of all the open windows.
# * version 0.2: Getting the splits.
#     * Displays the how many vertical and horizontal windows.
#       (not quite sure if my approximation is correct though..)
#     * Fixed possible memleak (forgot to free an infolist)
#
## Acknowledgements:
# * Sebastien "Flashcode" Helleu, for developing the kick-ass chat/IRC
#    client WeeChat
#
## TODO:
#   - Add more statistics, such as:
#     - average and total history lines.
#     - average and total topic/title lengths
#     - how many are displayed in a window
#
## Copyright (c) 2012 Filip H.F. "FiXato" Slagter,
#   <FiXato+WeeChat [at] Gmail [dot] com>
#   https://google.com/profiles/FiXato
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
SCRIPT_NAME     = "weestats"
SCRIPT_AUTHOR   = "Filip H.F. 'FiXato' Slagter <fixato [at] gmail [dot] com>"
SCRIPT_VERSION  = "0.2"
SCRIPT_LICENSE  = "MIT"
SCRIPT_DESC     = "Useless statistics about your open buffers and windows"
SCRIPT_COMMAND  = "weestats"
SCRIPT_CLOSE_CB = "close_cb"

import_ok = True

try:
  import weechat as w
except ImportError:
  print "This script must be run under WeeChat."
  import_ok = False

def close_cb(*kwargs):
  return w.WEECHAT_RC_OK

def command_main(data, buffer, args):
  infolist = w.infolist_get("buffer", "", "")
  buffer_groups = {}
  results = []
  buffer_count = 0
  merge_count = 0
  numbers = set()
  while w.infolist_next(infolist):
    bplugin = w.infolist_string(infolist, "plugin_name")
    bname = w.infolist_string(infolist, "name")
    bpointer = w.infolist_pointer(infolist, "pointer")
    bnumber = w.infolist_integer(infolist, "number")
    if not bnumber in numbers:
      numbers.add(bnumber)
    else:
      merge_count += 1
    btype = bplugin
    if bplugin == 'irc':
      if  'server.' in bname:
        btype = '%s servers' % btype
      elif '#' in bname:
        btype = '%s channels' % btype
      else:
        btype = '%s queries' % btype

    buffer_groups.setdefault(btype,[]).append({'name': bname, 'pointer': bpointer})

  w.infolist_free(infolist)

  infolist = w.infolist_get("window", "", "")
  windows_v = set()
  windows_h = set()
  windows = set()
  while w.infolist_next(infolist):
    window = w.infolist_pointer(infolist, "pointer")
    window_w = w.infolist_integer(infolist, "width_pct")
    window_h = w.infolist_integer(infolist, "height_pct")
    windows.add(window)
    if window_h == 100 and window_w != 100:
      windows_v.add(window)
    elif window_w == 100 and window_h != 100:
      windows_h.add(window)
    #else: #both 100%, thus no splits
  w.infolist_free(infolist)

  window_count = len(windows)

  for bplugin, buffers in buffer_groups.iteritems():
    buffer_count += len(buffers)
    results.append('%i %s' % (len(buffers), bplugin))

  buffer_stats = ', '.join(sorted(results))
  stats_string = '%i windows used (%i vertically / %i horizontally split). %i (of which %i merged) buffers open: %s' % (window_count, len(windows_v), len(windows_h), buffer_count, merge_count, buffer_stats)
  w.command("", "/input insert %s" % stats_string)
  return w.WEECHAT_RC_OK

if __name__ == "__main__" and import_ok:
  if w.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION,
                      SCRIPT_LICENSE, SCRIPT_DESC, SCRIPT_CLOSE_CB, ""):

    w.hook_command(SCRIPT_COMMAND,
                          SCRIPT_DESC,
                          "",
                          "Inserts useless statistics about your open windows and buffers into your input line.\n",

                          "",

                          "command_main", "")
<|endoftext|>


<commit_before>"""Utilities to generalize usage of fabric for local and remote builds.

Handles:
  - Providing a local equivalent of standard functions that avoid
    the need to ssh to a local machine.
    Adds generalized targets to the global `env` object which cleanly
    handle local and remote execution:
    - safe_run: Run a command
    - safe_run_output: Run a command, capturing the output
    - safe_sudo: Run a command as sudo user
    - safe_exists: Check for existence of a file.
    - safe_sed: Run sed command.
"""
import hashlib
import re
import shutil

from fabric.api import env, run, sudo, local, settings, hide
from fabric.contrib.files import exists, sed, contains, append, comment

# ## Local non-ssh access

def local_exists(path, use_sudo=False):
    func = env.safe_sudo if use_sudo else env.safe_run
    cmd = 'test -e "$(echo %s)"' % path
    with settings(hide('everything'), warn_only=True):
        env.lcwd = env.cwd
        return not func(cmd).failed

def run_local(use_sudo=False, capture=False):
    def _run(command, *args, **kwags):
        if use_sudo:
            command = "sudo bash -i -c " + '"%s"' % command.replace('"', '\\"')
        env.lcwd = env.cwd
        return local(command, capture=capture)
    return _run

def local_put(orig_file, new_file):
    shutil.copyfile(orig_file, new_file)

def local_sed(filename, before, after, limit='', use_sudo=False, backup='.bak',
              flags='', shell=False):
    """ Run a search-and-replace on ``filename`` with given regex patterns.

    From main fabric contrib, modified to handle local.
    """
    func = env.safe_sudo if use_sudo else env.safe_run
    # Characters to be escaped in both
    for char in "/'":
        before = before.replace(char, r'\%s' % char)
        after = after.replace(char, r'\%s' % char)
    # Characters to be escaped in replacement only (they're useful in regexen
    # in the 'before' part)
    for char in "()":
        after = after.replace(char, r'\%s' % char)
    if limit:
        limit = r'/%s/ ' % limit
    context = {
        'script': r"'%ss/%s/%s/%sg'" % (limit, before, after, flags),
        'filename': '"$(echo %s)"' % filename,
        'backup': backup
    }
    # Test the OS because of differences between sed versions

    with hide('running', 'stdout'):
        platform = env.safe_run("uname")
    if platform in ('NetBSD', 'OpenBSD', 'QNX'):
        # Attempt to protect against failures/collisions
        hasher = hashlib.sha1()
        hasher.update(env.host_string)
        hasher.update(filename)
        context['tmp'] = "/tmp/%s" % hasher.hexdigest()
        # Use temp file to work around lack of -i
        expr = r"""cp -p %(filename)s %(tmp)s \
&& sed -r -e %(script)s %(filename)s > %(tmp)s \
&& cp -p %(filename)s %(filename)s%(backup)s \
&& mv %(tmp)s %(filename)s"""
    else:
        context['extended_regex'] = '-E' if platform == 'Darwin' else '-r'
        expr = r"sed -i%(backup)s %(extended_regex)s -e %(script)s %(filename)s"
    command = expr % context
    return func(command, shell=shell)

def local_comment(filename, regex, use_sudo=False, char='#', backup='.bak', shell=False):
    carot, dollar = '', ''
    if regex.startswith('^'):
        carot = '^'
        regex = regex[1:]
    if regex.endswith('$'):
        dollar = '$'
        regex = regex[:-1]
    regex = "%s(%s)%s" % (carot, regex, dollar)
    return local_sed(
        filename,
        before=regex,
        after=r'%s\1' % char,
        use_sudo=use_sudo,
        backup=backup,
        shell=shell
    )

def _escape_for_regex(text):
    """Escape ``text`` to allow literal matching using egrep"""
    regex = re.escape(text)
    # Seems like double escaping is needed for \
    regex = regex.replace('\\\\', '\\\\\\')
    # Triple-escaping seems to be required for $ signs
    regex = regex.replace(r'\$', r'\\\$')
    # Whereas single quotes should not be escaped
    regex = regex.replace(r"\'", "'")
    return regex

def _expand_path(path):
    return '"$(echo %s)"' % path

def local_contains(filename, text, exact=False, use_sudo=False, escape=True,
    shell=False):
    func = use_sudo and env.safe_sudo or env.safe_run
    if escape:
        text = _escape_for_regex(text)
        if exact:
            text = "^%s$" % text
    with settings(hide('everything'), warn_only=True):
        egrep_cmd = 'egrep "%s" %s' % (text, _expand_path(filename))
        return func(egrep_cmd, shell=shell).succeeded

def local_append(filename, text, use_sudo=False, partial=False, escape=True, shell=False):
    func = use_sudo and env.safe_sudo or env.safe_run
    # Normalize non-list input to be a list
    if isinstance(text, basestring):
        text = [text]
    for line in text:
        regex = '^' + _escape_for_regex(line)  + ('' if partial else '$')
        if (env.safe_exists(filename, use_sudo=use_sudo) and line
            and env.safe_contains(filename, regex, use_sudo=use_sudo, escape=False,
                                  shell=shell)):
            continue
        line = line.replace("'", r"'\\''") if escape else line
        func("echo '%s' >> %s" % (line, _expand_path(filename)))

def configure_runsudo(env):
    """Setup env variable with safe_sudo and safe_run,
    supporting non-privileged users and local execution.
    """
    env.is_local = env.hosts == ["localhost"]
    if env.is_local:
        env.safe_put = local_put
        env.safe_sed = local_sed
        env.safe_comment = local_comment
        env.safe_contains = local_contains
        env.safe_append = local_append
        env.safe_exists = local_exists
        env.safe_run = run_local()
        env.safe_run_output = run_local(capture=True)
    else:
        env.safe_put = put
        env.safe_sed = sed
        env.safe_comment = comment
        env.safe_contains = contains
        env.safe_append = append
        env.safe_exists = exists
        env.safe_run = run
        env.safe_run_output = run
    if getattr(env, "use_sudo", "true").lower() in ["true", "yes"]:
        env.use_sudo = True
        if env.is_local:
            env.safe_sudo = run_local(True)
        else:
            env.safe_sudo = sudo
    else:
        env.use_sudo = False
        if env.is_local:
            env.safe_sudo = run_local()
        else:
            env.safe_sudo = run
<commit_msg>Avoid making sudo commands interactive: bad idea<commit_after>"""Utilities to generalize usage of fabric for local and remote builds.

Handles:
  - Providing a local equivalent of standard functions that avoid
    the need to ssh to a local machine.
    Adds generalized targets to the global `env` object which cleanly
    handle local and remote execution:
    - safe_run: Run a command
    - safe_run_output: Run a command, capturing the output
    - safe_sudo: Run a command as sudo user
    - safe_exists: Check for existence of a file.
    - safe_sed: Run sed command.
"""
import hashlib
import re
import shutil

from fabric.api import env, run, sudo, local, settings, hide
from fabric.contrib.files import exists, sed, contains, append, comment

# ## Local non-ssh access

def local_exists(path, use_sudo=False):
    func = env.safe_sudo if use_sudo else env.safe_run
    cmd = 'test -e "$(echo %s)"' % path
    with settings(hide('everything'), warn_only=True):
        env.lcwd = env.cwd
        return not func(cmd).failed

def run_local(use_sudo=False, capture=False):
    def _run(command, *args, **kwags):
        if use_sudo:
            command = "sudo bash -c " + '"%s"' % command.replace('"', '\\"')
        env.lcwd = env.cwd
        return local(command, capture=capture)
    return _run

def local_put(orig_file, new_file):
    shutil.copyfile(orig_file, new_file)

def local_sed(filename, before, after, limit='', use_sudo=False, backup='.bak',
              flags='', shell=False):
    """ Run a search-and-replace on ``filename`` with given regex patterns.

    From main fabric contrib, modified to handle local.
    """
    func = env.safe_sudo if use_sudo else env.safe_run
    # Characters to be escaped in both
    for char in "/'":
        before = before.replace(char, r'\%s' % char)
        after = after.replace(char, r'\%s' % char)
    # Characters to be escaped in replacement only (they're useful in regexen
    # in the 'before' part)
    for char in "()":
        after = after.replace(char, r'\%s' % char)
    if limit:
        limit = r'/%s/ ' % limit
    context = {
        'script': r"'%ss/%s/%s/%sg'" % (limit, before, after, flags),
        'filename': '"$(echo %s)"' % filename,
        'backup': backup
    }
    # Test the OS because of differences between sed versions

    with hide('running', 'stdout'):
        platform = env.safe_run("uname")
    if platform in ('NetBSD', 'OpenBSD', 'QNX'):
        # Attempt to protect against failures/collisions
        hasher = hashlib.sha1()
        hasher.update(env.host_string)
        hasher.update(filename)
        context['tmp'] = "/tmp/%s" % hasher.hexdigest()
        # Use temp file to work around lack of -i
        expr = r"""cp -p %(filename)s %(tmp)s \
&& sed -r -e %(script)s %(filename)s > %(tmp)s \
&& cp -p %(filename)s %(filename)s%(backup)s \
&& mv %(tmp)s %(filename)s"""
    else:
        context['extended_regex'] = '-E' if platform == 'Darwin' else '-r'
        expr = r"sed -i%(backup)s %(extended_regex)s -e %(script)s %(filename)s"
    command = expr % context
    return func(command, shell=shell)

def local_comment(filename, regex, use_sudo=False, char='#', backup='.bak', shell=False):
    carot, dollar = '', ''
    if regex.startswith('^'):
        carot = '^'
        regex = regex[1:]
    if regex.endswith('$'):
        dollar = '$'
        regex = regex[:-1]
    regex = "%s(%s)%s" % (carot, regex, dollar)
    return local_sed(
        filename,
        before=regex,
        after=r'%s\1' % char,
        use_sudo=use_sudo,
        backup=backup,
        shell=shell
    )

def _escape_for_regex(text):
    """Escape ``text`` to allow literal matching using egrep"""
    regex = re.escape(text)
    # Seems like double escaping is needed for \
    regex = regex.replace('\\\\', '\\\\\\')
    # Triple-escaping seems to be required for $ signs
    regex = regex.replace(r'\$', r'\\\$')
    # Whereas single quotes should not be escaped
    regex = regex.replace(r"\'", "'")
    return regex

def _expand_path(path):
    return '"$(echo %s)"' % path

def local_contains(filename, text, exact=False, use_sudo=False, escape=True,
    shell=False):
    func = use_sudo and env.safe_sudo or env.safe_run
    if escape:
        text = _escape_for_regex(text)
        if exact:
            text = "^%s$" % text
    with settings(hide('everything'), warn_only=True):
        egrep_cmd = 'egrep "%s" %s' % (text, _expand_path(filename))
        return func(egrep_cmd, shell=shell).succeeded

def local_append(filename, text, use_sudo=False, partial=False, escape=True, shell=False):
    func = use_sudo and env.safe_sudo or env.safe_run
    # Normalize non-list input to be a list
    if isinstance(text, basestring):
        text = [text]
    for line in text:
        regex = '^' + _escape_for_regex(line)  + ('' if partial else '$')
        if (env.safe_exists(filename, use_sudo=use_sudo) and line
            and env.safe_contains(filename, regex, use_sudo=use_sudo, escape=False,
                                  shell=shell)):
            continue
        line = line.replace("'", r"'\\''") if escape else line
        func("echo '%s' >> %s" % (line, _expand_path(filename)))

def configure_runsudo(env):
    """Setup env variable with safe_sudo and safe_run,
    supporting non-privileged users and local execution.
    """
    env.is_local = env.hosts == ["localhost"]
    if env.is_local:
        env.safe_put = local_put
        env.safe_sed = local_sed
        env.safe_comment = local_comment
        env.safe_contains = local_contains
        env.safe_append = local_append
        env.safe_exists = local_exists
        env.safe_run = run_local()
        env.safe_run_output = run_local(capture=True)
    else:
        env.safe_put = put
        env.safe_sed = sed
        env.safe_comment = comment
        env.safe_contains = contains
        env.safe_append = append
        env.safe_exists = exists
        env.safe_run = run
        env.safe_run_output = run
    if getattr(env, "use_sudo", "true").lower() in ["true", "yes"]:
        env.use_sudo = True
        if env.is_local:
            env.safe_sudo = run_local(True)
        else:
            env.safe_sudo = sudo
    else:
        env.use_sudo = False
        if env.is_local:
            env.safe_sudo = run_local()
        else:
            env.safe_sudo = run
<|endoftext|>