<commit_before>"""
OCL Collection views
"""
import requests
import logging

from django.utils.translation import ugettext as _
from django.core.urlresolvers import reverse
from django.http import (HttpResponseRedirect, Http404)
from django.views.generic import TemplateView
from django.views.generic.edit import FormView
from django.contrib import messages
from django.core.paginator import Paginator

from libs.ocl import OclApi, OclSearch, OclConstants
from .forms import (CollectionCreateForm, CollectionEditForm, CollectionDeleteForm, CollectionAddReferenceForm)
from apps.core.views import UserOrOrgMixin

logger = logging.getLogger('oclweb')

class CollectionReferencesView(UserOrOrgMixin, TemplateView):
    """ collection concept view. """
    template_name = "collections/collection_references.html"
    def get_context_data(self, *args, **kwargs):
        context = super(CollectionReferencesView, self).get_context_data(*args, **kwargs)

        self.get_args()
        api = OclApi(self.request, debug=True)
        results = api.get(self.owner_type, self.owner_id, 'collections', self.collection_id)
        collection = results.json()

        # Set the context
        context['kwargs'] = self.kwargs
        context['url_params'] = self.request.GET
        context['selected_tab'] = 'References'
        context['collection'] = collection

        return context
class CollectionMappingsView(UserOrOrgMixin, TemplateView):
    """ collection concept view. """
    template_name = "collections/collection_mappings.html"
    def get_context_data(self, *args, **kwargs):
        context = super(CollectionMappingsView, self).get_context_data(*args, **kwargs)

        self.get_args()
        api = OclApi(self.request, debug=True)
        results = api.get(self.owner_type, self.owner_id, 'collections', self.collection_id)
        collection = results.json()

        # Set the context
        context['kwargs'] = self.kwargs
        context['url_params'] = self.request.GET
        context['selected_tab'] = 'Mappings'
        context['collection'] = collection

        return context

class CollectionConceptsView(UserOrOrgMixin, TemplateView):
    """ collection concept view. """
    template_name = "collections/collection_concepts.html"
    def get_context_data(self, *args, **kwargs):
        context = super(CollectionConceptsView, self).get_context_data(*args, **kwargs)

        self.get_args()
        api = OclApi(self.request, debug=True)
        results = api.get(self.owner_type, self.owner_id, 'collections', self.collection_id)
        collection = results.json()

        # Set the context
        context['kwargs'] = self.kwargs
        context['url_params'] = self.request.GET
        context['selected_tab'] = 'Concepts'
        context['collection'] = collection

        return context

class CollectionVersionsView(UserOrOrgMixin, TemplateView):
    """ collection About view. """
    template_name = "collections/collection_versions.html"
    def get_context_data(self, *args, **kwargs):
        context = super(CollectionVersionsView, self).get_context_data(*args, **kwargs)

        self.get_args()
        api = OclApi(self.request, debug=True)
        results = api.get(self.owner_type, self.owner_id, 'collections', self.collection_id)
        collection = results.json()

        # Set the context
        context['kwargs'] = self.kwargs
        context['url_params'] = self.request.GET
        context['selected_tab'] = 'Versions'
        context['collection'] = collection

        return context

class CollectionAboutView(UserOrOrgMixin, TemplateView):
    """ Collection About view. """
    template_name = "collections/collection_about.html"
    def get_context_data(self, *args, **kwargs):
        context = super(CollectionAboutView, self).get_context_data(*args, **kwargs)

        self.get_args()
        api = OclApi(self.request, debug=True)
        results = api.get(self.owner_type, self.owner_id, 'collections', self.collection_id)
        collection = results.json()
        about = None
        if ('extras' in collection and isinstance(collection['extras'], dict) and
                    'about' in collection['extras']):
            about = collection['extras'].get('about')

        # Set the context
        context['kwargs'] = self.kwargs
        context['url_params'] = self.request.GET
        context['selected_tab'] = 'About'
        context['collection'] = collection
        context['about'] = about

        return context

class CollectionDetailView(UserOrOrgMixin, TemplateView):
    """ Collection detail views """

    template_name = "collections/collection_details.html"

    def get_context_data(self, *args, **kwargs):
        context = super(CollectionDetailView, self).get_context_data(*args, **kwargs)

        self.get_args()

        searcher = OclSearch(OclConstants.RESOURCE_NAME_COLLECTIONS, params=self.request.GET)

        api = OclApi(self.request, debug=True)
        results = api.get(self.owner_type, self.owner_id, 'collections', self.collection_id)

        if results.status_code != 200:
            if results.status_code == 404:
                raise Http404
            else:
                results.raise_for_status()
        collection = results.json()

        context['kwargs'] = self.kwargs
        context['collection'] = collection
        context['selected_tab'] = 'Details'
        return context

class CollectionCreateView(UserOrOrgMixin, FormView):
    """
        Create new Collection, either for an org or a user.
    """
    form_class = CollectionCreateForm
    template_name = "collections/collection_create.html"

    def get_initial(self):
        """ Load some useful data, not really for form display but internal use """
        self.get_args()

        data = {
            'org_id': self.org_id,
            'user_id': self.user_id,
            'from_org': self.from_org,
            'from_user': self.from_user,
            'request': self.request,
        }
        return data

    def get_context_data(self, *args, **kwargs):
        context = super(CollectionCreateView, self).get_context_data(*args, **kwargs)

        self.get_args()

        api = OclApi(self.request, debug=True)
        org = ocl_user = None

        if self.from_org:
            org = api.get('orgs', self.org_id).json()
        else:
            ocl_user = api.get('users', self.user_id).json()
        # Set the context
        context['org'] = org
        context['ocl_user'] = ocl_user
        context['from_user'] = self.from_user
        context['from_org'] = self.from_org

        return context

    def form_valid(self, form):
        """
            collection input is good, update API backend.
        """
        print form.cleaned_data

        self.get_args()

        data = form.cleaned_data
        short_code = data.pop('short_code')
        data['id'] = short_code

        api = OclApi(self.request, debug=True)
        result = api.post(self.owner_type, self.owner_id, 'collections', **data)
        if not result.status_code == requests.codes.created:
            emsg = result.json().get('detail', 'Error')
            messages.add_message(self.request, messages.ERROR, emsg)
            return HttpResponseRedirect(self.request.path)

        messages.add_message(self.request, messages.INFO, _('Collection created'))

        if self.from_org:
            return HttpResponseRedirect(reverse("collection-home",
                                                kwargs={"org": self.org_id,
                                                        'collection': short_code}))
        else:
            return HttpResponseRedirect(reverse("collection-home",
                                                kwargs={"user": self.user_id,
                                                        'collection': short_code}))

class CollectionAddReferenceView(UserOrOrgMixin, FormView):
    template_name = "collections/collection_add_reference.html"
    form_class = CollectionAddReferenceForm

    def get_context_data(self, *args, **kwargs):
        context = super(CollectionAddReferenceView, self).get_context_data(*args, **kwargs)

        self.get_args()
        api = OclApi(self.request, debug=True)
        results = api.get(self.owner_type, self.owner_id, 'collections', self.collection_id)
        collection = results.json()
        # Set the context
        context['kwargs'] = self.kwargs
        context['url_params'] = self.request.GET
        context['collection'] = collection

        return context

    def get_success_url(self):
        """ Return URL for redirecting browser """
        if self.from_org:
            return reverse('collection-references',
                           kwargs={'org': self.org_id,'collection':self.collection_id})

        else:
            return reverse('collection-references',
                           kwargs={"username": self.request.user.username,'collection':self.collection_id})

    def form_valid(self, form, *args, **kwargs):
        """ Use validated form data to delete the collection"""

        self.get_args()

        api = OclApi(self.request, debug=True)
        return HttpResponseRedirect(self.request.path)

class CollectionDeleteView(UserOrOrgMixin, FormView):
    """
    View for deleting Collection.
    """

    template_name = "collections/collection_delete.html"
    form_class = CollectionDeleteForm

    def get_context_data(self, *args, **kwargs):
        context = super(CollectionDeleteView, self).get_context_data(*args, **kwargs)

        self.get_args()
        api = OclApi(self.request, debug=True)
        results = api.get(self.owner_type, self.owner_id, 'collections', self.collection_id)
        collection = results.json()
        # Set the context
        context['kwargs'] = self.kwargs
        context['url_params'] = self.request.GET
        context['collection'] = collection

        return context

    def get_success_url(self):
        """ Return URL for redirecting browser """
        if self.from_org:
            return reverse('org-collections',
                           kwargs={'org': self.org_id})

        else:
            return reverse('users:detail',
                           kwargs={"username": self.request.user.username})

    def form_valid(self, form, *args, **kwargs):
        """ Use validated form data to delete the collection"""

        self.get_args()

        api = OclApi(self.request, debug=True)
        result = api.delete(
            self.owner_type, self.owner_id, 'collections', self.collection_id, **kwargs)

        if result.status_code != 204:
            emsg = result.json().get('detail', 'Error')
            messages.add_message(self.request, messages.ERROR, emsg)
            return HttpResponseRedirect(self.request.path)

        else:
            messages.add_message(self.request, messages.INFO, _('Collection Deleted'))
            return HttpResponseRedirect(self.get_success_url())

class CollectionEditView(UserOrOrgMixin, FormView):
    """ Edit collection, either for an org or a user. """
    template_name = "collections/collection_edit.html"

    def get_form_class(self):
        """ Trick to load initial data """
        self.get_args()
        api = OclApi(self.request, debug=True)
        self.collection = api.get(self.owner_type, self.owner_id, 'collections', self.collection_id).json()
        return CollectionEditForm

    def get_initial(self):
        """ Load some useful data, not really for form display but internal use """
        data = {
            'org_id': self.org_id,
            'user_id': self.user_id,
            'from_org': self.from_org,
            'from_user': self.from_user,
            'request': self.request,
        }
        data.update(self.collection)
        # convert supported locales to string
        supported_locale_list = self.collection.get('supported_locales')
        if supported_locale_list is None:
            data['supported_locales'] = ''
        else:
            data['supported_locales'] = ','.join(supported_locale_list)

        return data

    def get_context_data(self, *args, **kwargs):
        """ Get collection details for the edit form """
        context = super(CollectionEditView, self).get_context_data(*args, **kwargs)
        self.get_args()

        api = OclApi(self.request, debug=True)
        org = ocl_user = None
        if self.from_org:
            org = api.get('orgs', self.org_id).json()
        else:
            ocl_user = api.get('users', self.user_id).json()

        # Set the context
        context['kwargs'] = self.kwargs
        context['org'] = org
        context['ocl_user'] = ocl_user
        context['from_user'] = self.from_user
        context['from_org'] = self.from_org
        context['collection'] = self.collection

        return context

    def form_valid(self, form):
        """ If Collection input is valid, then update API backend. """
        self.get_args()

        # Submit updated collection data to the API
        data = form.cleaned_data
        api = OclApi(self.request, debug=True)
        result = api.update_collection(self.owner_type, self.owner_id, self.collection_id, data)
        print result
        if len(result.text) > 0:
            print result.json()

        messages.add_message(self.request, messages.INFO, _('Collection updated'))
        if self.from_org:
            return HttpResponseRedirect(reverse('collection-details',
                                                kwargs={'org': self.org_id,
                                                        'collection': self.collection_id}))
        else:
            return HttpResponseRedirect(reverse('collection-details',
                                                kwargs={'user': self.user_id,
                                                        'collection': self.collection_id}))
<commit_msg>[Anshu, Ravinder] web hook to api for collection references . wip<commit_after>"""
OCL Collection views
"""
import requests
import logging

from django.utils.translation import ugettext as _
from django.core.urlresolvers import reverse,resolve, Resolver404
from django.http import (HttpResponseRedirect, Http404)
from django.views.generic import TemplateView
from django.views.generic.edit import FormView
from django.contrib import messages
from django.core.paginator import Paginator

from libs.ocl import OclApi, OclSearch, OclConstants
from .forms import (CollectionCreateForm, CollectionEditForm, CollectionDeleteForm, CollectionAddReferenceForm)
from apps.core.views import UserOrOrgMixin

logger = logging.getLogger('oclweb')

class CollectionReferencesView(UserOrOrgMixin, TemplateView):
    """ collection concept view. """
    template_name = "collections/collection_references.html"
    def get_context_data(self, *args, **kwargs):
        context = super(CollectionReferencesView, self).get_context_data(*args, **kwargs)

        self.get_args()
        api = OclApi(self.request, debug=True)
        results = api.get(self.owner_type, self.owner_id, 'collections', self.collection_id)
        collection = results.json()

        # Set the context
        context['kwargs'] = self.kwargs
        context['url_params'] = self.request.GET
        context['selected_tab'] = 'References'
        context['collection'] = collection

        return context

class CollectionMappingsView(UserOrOrgMixin, TemplateView):
    """ collection concept view. """
    template_name = "collections/collection_mappings.html"
    def get_context_data(self, *args, **kwargs):
        context = super(CollectionMappingsView, self).get_context_data(*args, **kwargs)

        self.get_args()
        api = OclApi(self.request, debug=True)
        results = api.get(self.owner_type, self.owner_id, 'collections', self.collection_id)
        collection = results.json()

        # Set the context
        context['kwargs'] = self.kwargs
        context['url_params'] = self.request.GET
        context['selected_tab'] = 'Mappings'
        context['collection'] = collection

        return context

class CollectionConceptsView(UserOrOrgMixin, TemplateView):
    """ collection concept view. """
    template_name = "collections/collection_concepts.html"
    def get_context_data(self, *args, **kwargs):
        context = super(CollectionConceptsView, self).get_context_data(*args, **kwargs)

        self.get_args()
        api = OclApi(self.request, debug=True)
        results = api.get(self.owner_type, self.owner_id, 'collections', self.collection_id)
        collection = results.json()

        # Set the context
        context['kwargs'] = self.kwargs
        context['url_params'] = self.request.GET
        context['selected_tab'] = 'Concepts'
        context['collection'] = collection

        return context

class CollectionVersionsView(UserOrOrgMixin, TemplateView):
    """ collection About view. """
    template_name = "collections/collection_versions.html"
    def get_context_data(self, *args, **kwargs):
        context = super(CollectionVersionsView, self).get_context_data(*args, **kwargs)

        self.get_args()
        api = OclApi(self.request, debug=True)
        results = api.get(self.owner_type, self.owner_id, 'collections', self.collection_id)
        collection = results.json()

        # Set the context
        context['kwargs'] = self.kwargs
        context['url_params'] = self.request.GET
        context['selected_tab'] = 'Versions'
        context['collection'] = collection

        return context

class CollectionAboutView(UserOrOrgMixin, TemplateView):
    """ Collection About view. """
    template_name = "collections/collection_about.html"
    def get_context_data(self, *args, **kwargs):
        context = super(CollectionAboutView, self).get_context_data(*args, **kwargs)

        self.get_args()
        api = OclApi(self.request, debug=True)
        results = api.get(self.owner_type, self.owner_id, 'collections', self.collection_id)
        collection = results.json()
        about = None
        if ('extras' in collection and isinstance(collection['extras'], dict) and
                    'about' in collection['extras']):
            about = collection['extras'].get('about')

        # Set the context
        context['kwargs'] = self.kwargs
        context['url_params'] = self.request.GET
        context['selected_tab'] = 'About'
        context['collection'] = collection
        context['about'] = about

        return context

class CollectionDetailView(UserOrOrgMixin, TemplateView):
    """ Collection detail views """

    template_name = "collections/collection_details.html"

    def get_context_data(self, *args, **kwargs):
        context = super(CollectionDetailView, self).get_context_data(*args, **kwargs)

        self.get_args()

        api = OclApi(self.request, debug=True)
        results = api.get(self.owner_type, self.owner_id, 'collections', self.collection_id)

        if results.status_code != 200:
            if results.status_code == 404:
                raise Http404
            else:
                results.raise_for_status()
        collection = results.json()

        context['kwargs'] = self.kwargs
        context['collection'] = collection
        context['selected_tab'] = 'Details'
        return context

class CollectionCreateView(UserOrOrgMixin, FormView):
    """
        Create new Collection, either for an org or a user.
    """
    form_class = CollectionCreateForm
    template_name = "collections/collection_create.html"

    def get_initial(self):
        """ Load some useful data, not really for form display but internal use """
        self.get_args()

        data = {
            'org_id': self.org_id,
            'user_id': self.user_id,
            'from_org': self.from_org,
            'from_user': self.from_user,
            'request': self.request,
        }
        return data

    def get_context_data(self, *args, **kwargs):
        context = super(CollectionCreateView, self).get_context_data(*args, **kwargs)

        self.get_args()

        api = OclApi(self.request, debug=True)
        org = ocl_user = None

        if self.from_org:
            org = api.get('orgs', self.org_id).json()
        else:
            ocl_user = api.get('users', self.user_id).json()
        # Set the context
        context['org'] = org
        context['ocl_user'] = ocl_user
        context['from_user'] = self.from_user
        context['from_org'] = self.from_org

        return context

    def form_valid(self, form):
        """
            collection input is good, update API backend.
        """
        print form.cleaned_data

        self.get_args()

        data = form.cleaned_data
        short_code = data.pop('short_code')
        data['id'] = short_code

        api = OclApi(self.request, debug=True)
        result = api.post(self.owner_type, self.owner_id, 'collections', **data)
        if not result.status_code == requests.codes.created:
            emsg = result.json().get('detail', 'Error')
            messages.add_message(self.request, messages.ERROR, emsg)
            return HttpResponseRedirect(self.request.path)

        messages.add_message(self.request, messages.INFO, _('Collection created'))

        if self.from_org:
            return HttpResponseRedirect(reverse("collection-home",
                                                kwargs={"org": self.org_id,
                                                        'collection': short_code}))
        else:
            return HttpResponseRedirect(reverse("collection-home",
                                                kwargs={"user": self.user_id,
                                                        'collection': short_code}))

class CollectionAddReferenceView(UserOrOrgMixin, FormView):
    template_name = "collections/collection_add_reference.html"
    form_class = CollectionAddReferenceForm

    def get_context_data(self, *args, **kwargs):
        context = super(CollectionAddReferenceView, self).get_context_data(*args, **kwargs)

        self.get_args()
        api = OclApi(self.request, debug=True)
        results = api.get(self.owner_type, self.owner_id, 'collections', self.collection_id)
        collection = results.json()
        # Set the context
        context['kwargs'] = self.kwargs
        context['url_params'] = self.request.GET
        context['collection'] = collection

        return context

    def get_success_url(self):
        """ Return URL for redirecting browser """
        if self.from_org:
            return reverse('collection-references',
                           kwargs={'org': self.org_id,'collection':self.collection_id})

        else:
            return reverse('collection-references',
                           kwargs={"username": self.request.user.username,'collection':self.collection_id})

    def form_valid(self, form, *args, **kwargs):
        """ Use validated form data to delete the collection"""

        self.get_args()
        data = form.cleaned_data
        # resolver = resolve(data)
        api = OclApi(self.request, debug=True)
        result = api.put(self.owner_type, self.owner_id, 'collections', self.collection_id, 'references', **data)
        print "after sending request to api...."
        # messages.add_message(self.request, messages.INFO, "Functionality not implemented yet.. WIP..")

        return HttpResponseRedirect(self.request.path)

class CollectionDeleteView(UserOrOrgMixin, FormView):
    """
    View for deleting Collection.
    """

    template_name = "collections/collection_delete.html"
    form_class = CollectionDeleteForm

    def get_context_data(self, *args, **kwargs):
        context = super(CollectionDeleteView, self).get_context_data(*args, **kwargs)

        self.get_args()
        api = OclApi(self.request, debug=True)
        results = api.get(self.owner_type, self.owner_id, 'collections', self.collection_id)
        collection = results.json()
        # Set the context
        context['kwargs'] = self.kwargs
        context['url_params'] = self.request.GET
        context['collection'] = collection

        return context

    def get_success_url(self):
        """ Return URL for redirecting browser """
        if self.from_org:
            return reverse('org-collections',
                           kwargs={'org': self.org_id})

        else:
            return reverse('users:detail',
                           kwargs={"username": self.request.user.username})

    def form_valid(self, form, *args, **kwargs):
        """ Use validated form data to delete the collection"""

        self.get_args()

        api = OclApi(self.request, debug=True)
        result = api.delete(
            self.owner_type, self.owner_id, 'collections', self.collection_id, **kwargs)

        if result.status_code != 204:
            emsg = result.json().get('detail', 'Error')
            messages.add_message(self.request, messages.ERROR, emsg)
            return HttpResponseRedirect(self.request.path)

        else:
            messages.add_message(self.request, messages.INFO, _('Collection Deleted'))
            return HttpResponseRedirect(self.get_success_url())

class CollectionEditView(UserOrOrgMixin, FormView):
    """ Edit collection, either for an org or a user. """
    template_name = "collections/collection_edit.html"

    def get_form_class(self):
        """ Trick to load initial data """
        self.get_args()
        api = OclApi(self.request, debug=True)
        self.collection = api.get(self.owner_type, self.owner_id, 'collections', self.collection_id).json()
        return CollectionEditForm

    def get_initial(self):
        """ Load some useful data, not really for form display but internal use """
        data = {
            'org_id': self.org_id,
            'user_id': self.user_id,
            'from_org': self.from_org,
            'from_user': self.from_user,
            'request': self.request,
        }
        data.update(self.collection)
        # convert supported locales to string
        supported_locale_list = self.collection.get('supported_locales')
        if supported_locale_list is None:
            data['supported_locales'] = ''
        else:
            data['supported_locales'] = ','.join(supported_locale_list)

        return data

    def get_context_data(self, *args, **kwargs):
        """ Get collection details for the edit form """
        context = super(CollectionEditView, self).get_context_data(*args, **kwargs)
        self.get_args()

        api = OclApi(self.request, debug=True)
        org = ocl_user = None
        if self.from_org:
            org = api.get('orgs', self.org_id).json()
        else:
            ocl_user = api.get('users', self.user_id).json()

        # Set the context
        context['kwargs'] = self.kwargs
        context['org'] = org
        context['ocl_user'] = ocl_user
        context['from_user'] = self.from_user
        context['from_org'] = self.from_org
        context['collection'] = self.collection

        return context

    def form_valid(self, form):
        """ If Collection input is valid, then update API backend. """
        self.get_args()

        # Submit updated collection data to the API
        data = form.cleaned_data
        api = OclApi(self.request, debug=True)
        result = api.update_collection(self.owner_type, self.owner_id, self.collection_id, data)
        print result
        if len(result.text) > 0:
            print result.json()

        messages.add_message(self.request, messages.INFO, _('Collection updated'))
        if self.from_org:
            return HttpResponseRedirect(reverse('collection-details',
                                                kwargs={'org': self.org_id,
                                                        'collection': self.collection_id}))
        else:
            return HttpResponseRedirect(reverse('collection-details',
                                                kwargs={'user': self.user_id,
                                                        'collection': self.collection_id}))
<|endoftext|>


<commit_before>from django.core.management.base import BaseCommand, CommandError
from reeltalk.models import *

class Command(BaseCommand):
    def handle(self, *args, **options):
        userlist = UserProfile.objects.all() # list

        def findSimilarUsers( currentUser, userList):
            similarityList = []
            currentUserReviews = Review.objects.filter(user = currentUser)
            for u in userList:
                if(u.id != currentUser.id):
                    matches = 0
                    totalDifference = 0
                    reviews = Review.objects.filter(user=u)
                    for r in reviews:
                        if currentUserReviews.filter(show__id=r.show.id).exists():
                            totalDifference += abs(currentUserReviews.get(show__id = r.show.id).score - r.score)
                            matches+=1
                    if(matches>0):
                        similarityList.append((u.id, 2 - totalDifference / matches))
            similarityList = [user[1] for user in similarityList if user[1] > 0]
            return similarityList

        print(findSimilarUsers(userlist.first(), userlist))
<commit_msg>Finished possibleMovieDict generation<commit_after>from django.core.management.base import BaseCommand, CommandError
from reeltalk.models import *

class Command(BaseCommand):
    def handle(self, *args, **options):
        userlist = UserProfile.objects.all() # list

        def findSimilarUsers( currentUser, userList):
            similarityList = []
            currentUserReviews = Review.objects.filter(user = currentUser)
            for u in userList:
                if(u.id != currentUser.id):
                    matches = 0
                    totalDifference = 0
                    reviews = Review.objects.filter(user=u)
                    for r in reviews:
                        if currentUserReviews.filter(show__id=r.show.id).exists():
                            totalDifference += abs(currentUserReviews.get(show__id = r.show.id).score - r.score)
                            matches+=1
                    if(matches>0):
                        similarityList.append((u.id, 2 - totalDifference / matches))
            similarityList = [user for user in similarityList if user[1] > 0]
            return similarityList

        def findMovieRecommendations( currentUser, similarUsers):
            currentUserReviews = Review.objects.filter(user = currentUser)
            possibleMovieDict = {}
            for u in similarUsers:
                reviewedMovies = Review.objects.filter(user__id = u[0])
                for r in reviewedMovies:
                    if(!currentUserReviews.filter(show__id=r.show.id).exists()):
                        weightedScore = (r.score - 3)*u[1]
                    if(possibleMovieMap.has_key(r.show.id)):
                        totalWeightedScore = possibleMovieMap[r.show.id] + weightedScore
                        possibleMovieMap[r.show.id] = totalWeightedScore
                    else:
                        possibleMovieMap[r.show.id] = weightedScore
            return possibleMovieMap

        similarUsers = findSimilarUsers(userlist.first(), userlist)
        print(findMovieRecommendations(userlist.first(), similarUsers))

        # print(findSimilarUsers(userlist.first(), userlist))
<|endoftext|>


<commit_before>#!/usr/bin/env python
#
# Desc     : Simple HKP server for collecting PGP keys for keysigning parties
# Author   : Vladimir vitkov <vvitkov@linux-bg.org>
# License  : Apache 2.0
# Version  : 1.0
# Changelog: 2014.11.05 - Initial version

from flask import Flask, request, render_template
import os

app = Flask(__name__)

## Some vars
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
GPG_HOME = os.path.join(BASE_DIR, 'keysigning', 'gpg-home')
KEY_STORE = os.path.join(BASE_DIR, 'keysigning', 'keys')

# check and fix
if not os.path.exists(GPG_HOME):
	print '%s does not exist. Creating...' % GPG_HOME
	os.makedirs(GPG_HOME, 0700)

if not os.path.exists(KEY_STORE):
	print '%s does not exist. Creating...' % KEY_STORE
	os.makedirs(KEY_STORE, 0700)

def get_file_path(keyid=u''):
	"""
	return the full path to a file containing the key
	"""
	return os.path.join(KEY_STORE, str(keyid[0:4]), str(keyid[4:8]), keyid).lower()

@app.route('/pks/lookup', methods=['GET'])
def search_key():
	machine_readable = False

	operation = request.args.get('op')
	# valid operations
	# get - send the keys (html wrapping possible) or 404
	# index - list matching keys or 501 if not supported
	# vindex - verbose list or 501
	# x-<...> - custom
	if operation == 'get':
		pass
	elif operation == 'index' or operation == 'vindex':
		return render_template(
				'50x.html',
				error_num = 501,
				error_txt = 'Operation not supported. Only get and x-get-bundle supported.',
				), 501
	elif operation == 'x-get-bundle':
		pass
	else:
		pass

	search = request.args.get('search')
	# valid keyid's (spacing added for readability)
	# 0x12345678 - 32bit keyid
	# 0x12345678 12345678 - 64bit
	# 0x12345678 12345678 12345678 12345678 - v3 fingerprint
	# 0x12345678 12345678 12345678 12345678 12345678 - v4 fingerprint
	if search.startswith('0x'):
		search = search[2:]
		if len(search) in (8, 16, 40):
			try:
				int(search, 16)
			except:
				return render_template(
						'50x.html',
						error_num = 404,
						error_txt = 'ID/Fingerprint incomplete',
						), 404

			# now get the key and dump it
			if len(search) == 40:
				# v4 fingerprint - keyid is last 16 digits
				search = search[-16:]

			keyfile = get_file_path(search)

			# now dump it
			fp = open(keyfile, 'r')
			return fp.read(), 200, {'Content-Type': 'application/pgp-keys'}
			#return keyfile
		else:
			return render_template(
					'50x.html',
					error_num = 404,
					error_txt = 'ID/Fingerprint incomplete',
					), 404
	else:
		return render_template(
				'50x.html',
				error_num = 501,
				error_txt = 'Search type not suported. Only ID or V4 fingerprint supported',
				), 501

	options = request.args.get('options')
	# valid options (comma separated list
	# mr - machine readable
	# nm - no modify - usefull for adding keys
	# x-<...> - site speciffic
	#for opt in split(options):
	#	if opt == 'mr':
	#		machine_readable=True
	#	else:
	#		pass

	fingerprint = request.args.get('fingerprint')
	# on/off - display fingerprint on index/vindex

	exact = request.args.get('exact')
	# on/off - exact matches

	# x- ... - local

	#sample http://keys.example.com:11371/pks/lookup?op=get&search=0x99242560

@app.route('/pks/add', methods=['POST'])
def add_key():
	"""
	Add keys that we were sent
	"""

	import gnupg
	from tempfile import mkdtemp
	from shutil import rmtree

	# build a temporary place for empty keyring
	_gpghome = mkdtemp(prefix = os.path.join(GPG_HOME, 'ksp'))

	# Init the GPG
	gpg = gnupg.GPG(gnupghome = _gpghome)

	# Blindly try to import and check result. If we have count we are fine
	import_result = gpg.import_keys(request.form['keytext'])
	if import_result.count <= 0:
		return render_template(
				'50x.html',
				error_num = 501,
				error_txt = 'Invalid key sent'
				), 501

	# Now list the keys in the keyring and store it on the FS
	imported_keys = gpg.list_keys()
	for key in imported_keys:
		# Create a keypath (and dirs if needed)
		_path = get_file_path(key['keyid'])
		import subprocess
		subprocess.Popen("ls %s"%os.path.dirname(_path), shell=True)
		if not os.path.exists(_path):
			print _path
			os.makedirs(os.path.dirname(_path), 0700)

		# Store the file in path/12/1234567812345678
		fp = open(_path, 'w')
		fp.write(gpg.export_keys(key['keyid']))
		fp.close()

	# Nuke the temp gpg home
	rmtree(_gpghome)

	return '101'

@app.route('/', methods=['GET'])
@app.route('/about', methods=['GET'])
def show_about_page():
	return render_template('about.html')

if __name__ == '__main__':
	app.run(debug=True)
<commit_msg>HKP Keyserver<commit_after>#!/usr/bin/env python
#
# Desc     : Simple HKP server for collecting PGP keys for keysigning parties
# Author   : Vladimir vitkov <vvitkov@linux-bg.org>
# License  : Apache 2.0
# Version  : 1.0
# Changelog: 2014.11.05 - Initial version

from flask import Flask, request, render_template
import os, sys

app = Flask(__name__)

## Some vars
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
GPG_HOME = os.path.join(BASE_DIR, 'keysigning', 'gpg-home')
KEY_STORE = os.path.join(BASE_DIR, 'keysigning', 'keys')

# check and fix
if not os.path.exists(GPG_HOME):
	print '%s does not exist. Creating...' % GPG_HOME
	os.makedirs(GPG_HOME, 0700)

if not os.path.exists(KEY_STORE):
	print '%s does not exist. Creating...' % KEY_STORE
	os.makedirs(KEY_STORE, 0700)

def get_file_path(keyid=''):
	"""
	return the full path to a file containing the key
	"""
	keyid = keyid.lower()
	return str(os.path.join(KEY_STORE, keyid[0:4], keyid[4:8], keyid))

def return_error(code = 501, text = 'Not supported'):
	return render_template(
			'50x.html',
			error_num = code,
			error_txt = text,
			), code

@app.route('/pks/lookup', methods=['GET'])
def search_key():
	machine_readable = False

	operation = request.args.get('op')
	# valid operations
	# get - send the keys (html wrapping possible) or 404
	# index - list matching keys or 501 if not supported
	# vindex - verbose list or 501
	# x-<...> - custom
	if operation == 'get':
		pass
	else:
		return return_error(501, 'Operation not supported. Only get and x-get-bundle supported.')

	search = request.args.get('search')
	# valid keyid's (spacing added for readability)
	# 0x12345678 - 32bit keyid
	# 0x12345678 12345678 - 64bit
	# 0x12345678 12345678 12345678 12345678 - v3 fingerprint
	# 0x12345678 12345678 12345678 12345678 12345678 - v4 fingerprint
	if search.startswith('0x'):
		search = search[2:]
		if len(search) in (8, 16, 40):
			try:
				int(search, 16)
			except:
				return return_error(404, 'ID/Fingerprint incomplete')

			# now get the key and dump it
			if len(search) == 40:
				# v4 fingerprint - keyid is last 16 digits
				search = search[-16:]

			keyfile = get_file_path(search)

			# now dump it
			fp = open(keyfile, 'r')
			return fp.read(), 200, {'Content-Type': 'application/pgp-keys'}
			#return keyfile
		else:
			return return_error(404, 'ID/Fingerprint incomplete')
	else:
		return return_error(501, 'Search type not suported. Only ID or V4 fingerprint supported')

	options = request.args.get('options')
	# valid options (comma separated list
	# mr - machine readable
	# nm - no modify - usefull for adding keys
	# x-<...> - site speciffic
	#for opt in split(options):
	#	if opt == 'mr':
	#		machine_readable=True
	#	else:
	#		pass

	fingerprint = request.args.get('fingerprint')
	# on/off - display fingerprint on index/vindex

	exact = request.args.get('exact')
	# on/off - exact matches

	# x- ... - local

	#sample http://keys.example.com:11371/pks/lookup?op=get&search=0x99242560

	# now we have the op and search .. let's boogie

@app.route('/pks/add', methods=['POST'])
def add_key():
	"""
	Add keys that we were sent
	"""

	import gnupg
	from tempfile import mkdtemp
	from shutil import rmtree

	# build a temporary place for empty keyring
	_gpghome = mkdtemp(prefix = os.path.join(GPG_HOME, 'ksp'))

	# Init the GPG
	gpg = gnupg.GPG(gnupghome = _gpghome, options = ['--with-colons', '--keyid-format=LONG'], verbose = False)

	# Blindly try to import and check result. If we have count we are fine
	import_result = gpg.import_keys(request.form['keytext'])
	if import_result.count <= 0:
		return return_error(501, 'Invalid key sent')

	# Now list the keys in the keyring and store it on the FS
	imported_keys = gpg.list_keys()
	for key in imported_keys:
		# Create a keypath (and dirs if needed)
		_path = get_file_path(key['keyid'])
		if not os.path.exists(os.path.dirname(_path)):
			os.makedirs(os.path.dirname(_path), 0700)

		if not os.path.exists(os.path.dirname(get_file_path(key['keyid'][-8:]))):
			os.makedirs(os.path.dirname(get_file_path(key['keyid'][-8:])), 0700)

		# Store the file in path/1234/5678/1234567812345678
		if not os.path.exists(o_path):
			fp = open(_path, 'w')
			fp.write(gpg.export_keys(key['keyid']))
			fp.close()

			# and symlink it to the short ID
			if not os.path.exists(get_file_path(key['keyid'][-8:])):
				os.symlink(_path, get_file_path(key['keyid'][-8:]))

	# Nuke the temp gpg home
	rmtree(_gpghome)
	return '101'

@app.route('/', methods=['GET'])
@app.route('/about', methods=['GET'])
def show_about_page():
	return render_template('about.html')

if __name__ == '__main__':
	app.run(debug=True)
<|endoftext|>


<commit_before>import argparse
import boto
import json
import logging
import logging.config
import os
import sendgrid
import StringIO

from boto.s3.key import Key
from bing_geocoder import BingGeocoder
from csv import DictReader, DictWriter
from datetime import date, datetime, timedelta
from os.path import expanduser

# Set up logging
logging.config.dictConfig({
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'standard': {
            'format': '%(asctime)s - %(levelname)s - line: %(lineno)d - %(message)s'
        }
    },
    'handlers': {
        'default': {
            'level': 'INFO',
            'class': 'logging.FileHandler',
            'filename': '%s/logs/geocode_service.log' % expanduser('~'),
            'formatter': 'standard'
        }
    },
    'loggers': {
        '': {
            'handlers': ['default'],
            'level': 'INFO',
            'propagate': True
        }
    }
})

GEO_BUCKET = 'geo.tribapps.com'

def download_jobs(geocoder):
    """
    Download and submit jobs from S3.
    """
    logging.info('Downloading jobs')
    awaiting_folder = 'geocode_awaiting_submission'
    pending_folder = 'geocode_pending_jobs'
    connection = boto.connect_s3()
    bucket = connection.get_bucket(GEO_BUCKET)
    files = bucket.list('%s' % awaiting_folder)
    for f in files:
        try:
            name = f.name.replace('%s/' % awaiting_folder, '')
            fkey = bucket.get_key(f.name)
            email_address = fkey.get_metadata('email')
            if name:
                logging.info('Uploading %s to Bing' % name)
                job_id = geocoder.upload_address_batch(fkey.get_contents_as_string())
                if job_id:
                    logging.info('Moving batch with old id %s to new id %s in %s' % (
                        name, job_id, pending_folder))
                    new_key = bucket.get_key('%s/%s' % (pending_folder, job_id))
                    new_key.set_contents_from_string(name)
                    if email_address:
                        logging.info('Setting metadata to %s' % email_address)
                        new_key.set_metadata('email', email_address)
                        send_email_notification(email_address, {}, name, 'pending')
                    old_key = Key(bucket)
                    old_key.key = '%s/%s' % (awaiting_folder, name)
                    old_key.delete()
                else:
                    send_email_notification(email_address, {}, name, 'error')
        except Exception, e:
            logging.warning('Error uploading %s to Bing: %s' % (name, e))

def check_pending_jobs(geocoder):
    """
    Get list of pending jobs, look up their statuses and save the completed ones.
    """
    logging.info('Checking pending job')
    pending_folder = 'geocode_pending_jobs'
    connection = boto.connect_s3()
    bucket = connection.get_bucket(GEO_BUCKET)
    files = bucket.list('%s' % pending_folder)
    for f in files:
        job_id = f.name.replace('%s/' % pending_folder, '')
        if job_id:
            results = geocoder.get_job_statuses(job_id=job_id)
            if results[0]['status'] == 'Completed':
                k = bucket.get_key('%s/%s' % (pending_folder, job_id))
                settings = k.get_contents_as_string()
                save_job_results(geocoder, job_id)

def save_job_results(geocoder, job_id):
    """
    Download and save to S3 results for completed jobs.
    """
    logging.info('Saving results for %s to S3' % job_id)
    finished_folder = 'geocode_finished_jobs'
    pending_folder = 'geocode_pending_jobs'

    connection = boto.connect_s3()
    bucket = connection.get_bucket(GEO_BUCKET)
    old_key = bucket.get_key('%s/%s' % (pending_folder, job_id))

    new_name = old_key.get_contents_as_string()
    new_key = Key(bucket)
    new_key.key = '%s/%s' % (finished_folder, new_name)

    results = geocoder.get_job_results(job_id)
    result_string = StringIO.StringIO()
    writer = DictWriter(result_string, fieldnames=results[0].keys())
    writer.writeheader()
    writer.writerows(results)
    result_string.seek(0)

    email_address = old_key.get_metadata('email')
    if email_address:
        new_key.set_metadata('email', email_address)
        send_email_notification(email_address, results, new_name, 'finished')

    new_key.set_contents_from_string(result_string.getvalue())
    new_key.make_public()
    old_key.delete()

def send_email_notification(address, results, settings, status):
    """
    Send an email notification when a job has been created or is finished.
    """
    finished_url = 'http://geo.tribapps.com/geocode_finished_jobs/%s' % settings
    if status == 'finished':
        subject = 'Finished geocoding job %s' % settings
        template = """
        Finished geocoding. Download results at {0}

        Had trouble processing {1:,d} addresses out of {2:,d} submitted.
        """.format(finished_url, results['failedEntityCount'], results['processedEntityCount'])
    elif status == 'pending':
        subject = 'Began processing geocode job %s' % settings
        template = """
        Just submitted job for geocoding.

        We'll email you when it's done, but the results will be available at %s
        """ % finished_url
    elif status == 'error':
        subject = 'Error processing geocode job %s' % settings
        template = """
        It looks like Bing had trouble processing the file you uploaded.

        Was it a CSV with column headings as described at http://geo.tribapps.com?
        """
    sg = sendgrid.SendGridClient(
        os.environ.get('SENDGRID_USERNAME', ''), os.environ.get('SENDGRID_PASSWORD', ''))
    message = sendgrid.Mail(subject=subject, from_email='noreply@tribpub.com')
    message.add_to(address)
    message.set_html(template)
    message.set_text(template)
    logging.info('Sending email report to %s' % ', '.join(message.to))
    status, msg = sg.send(message)
    if status != 200:
        logging.warning('Error sending email, got status %s: %s' % (status, msg))

def main():
    env_var = 'BING_MAPS_API_KEY'
    if env_var in os.environ:
        geocoder = BingGeocoder(os.environ[env_var])
    else:
        logging.error('Error: Need to provide Bing Maps API key')
        return

    parser = argparse.ArgumentParser()
    parser.add_argument('task')
    args = parser.parse_args()
    commands = ['download', 'statuses']
    if args.task in commands:
        logging.info('Running %s' % args.task)
        if args.task == 'download':
            download_jobs(geocoder)
        elif args.task == 'statuses':
            check_pending_jobs(geocoder)
    else:
        logging.error('%s is an unsupported task' % args.task)
        return

if __name__ == '__main__':
    main()
<commit_msg>Fixing s3 bug<commit_after>import argparse
import boto
import json
import logging
import logging.config
import os
import sendgrid
import StringIO

from boto.s3.key import Key
from bing_geocoder import BingGeocoder
from csv import DictReader, DictWriter
from datetime import date, datetime, timedelta
from os.path import expanduser

# Set up logging
logging.config.dictConfig({
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'standard': {
            'format': '%(asctime)s - %(levelname)s - line: %(lineno)d - %(message)s'
        }
    },
    'handlers': {
        'default': {
            'level': 'INFO',
            'class': 'logging.FileHandler',
            'filename': '%s/logs/geocode_service.log' % expanduser('~'),
            'formatter': 'standard'
        }
    },
    'loggers': {
        '': {
            'handlers': ['default'],
            'level': 'INFO',
            'propagate': True
        }
    }
})

GEO_BUCKET = 'geo.tribapps.com'

def download_jobs(geocoder):
    """
    Download and submit jobs from S3.
    """
    logging.info('Downloading jobs')
    awaiting_folder = 'geocode_awaiting_submission'
    pending_folder = 'geocode_pending_jobs'
    connection = boto.connect_s3()
    bucket = connection.get_bucket(GEO_BUCKET)
    files = bucket.list('%s' % awaiting_folder)
    for f in files:
        try:
            name = f.name.replace('%s/' % awaiting_folder, '')
            fkey = bucket.get_key(f.name)
            email_address = fkey.get_metadata('email')
            if name:
                logging.info('Uploading %s to Bing' % name)
                job_id = geocoder.upload_address_batch(fkey.get_contents_as_string())
                if job_id:
                    logging.info('Moving batch with old id %s to new id %s in %s' % (
                        name, job_id, pending_folder))
                    new_key = Key(bucket)
                    new_key.key = '%s/%s' % (pending_folder, job_id)
                    if email_address:
                        logging.info('Setting metadata to %s' % email_address)
                        new_key.set_metadata('email', email_address)
                        send_email_notification(email_address, {}, name, 'pending')
                    new_key.set_contents_from_string(name)
                    old_key = Key(bucket)
                    old_key.key = '%s/%s' % (awaiting_folder, name)
                    old_key.delete()
                else:
                    send_email_notification(email_address, {}, name, 'error')
        except Exception, e:
            logging.warning('Error uploading %s to Bing: %s' % (name, e))

def check_pending_jobs(geocoder):
    """
    Get list of pending jobs, look up their statuses and save the completed ones.
    """
    logging.info('Checking pending job')
    pending_folder = 'geocode_pending_jobs'
    connection = boto.connect_s3()
    bucket = connection.get_bucket(GEO_BUCKET)
    files = bucket.list('%s' % pending_folder)
    for f in files:
        job_id = f.name.replace('%s/' % pending_folder, '')
        if job_id:
            results = geocoder.get_job_statuses(job_id=job_id)
            if results[0]['status'] == 'Completed':
                k = bucket.get_key('%s/%s' % (pending_folder, job_id))
                settings = k.get_contents_as_string()
                save_job_results(geocoder, job_id)

def save_job_results(geocoder, job_id):
    """
    Download and save to S3 results for completed jobs.
    """
    logging.info('Saving results for %s to S3' % job_id)
    finished_folder = 'geocode_finished_jobs'
    pending_folder = 'geocode_pending_jobs'

    connection = boto.connect_s3()
    bucket = connection.get_bucket(GEO_BUCKET)
    old_key = bucket.get_key('%s/%s' % (pending_folder, job_id))

    new_name = old_key.get_contents_as_string()
    new_key = Key(bucket)
    new_key.key = '%s/%s' % (finished_folder, new_name)

    results = geocoder.get_job_results(job_id)
    result_string = StringIO.StringIO()
    writer = DictWriter(result_string, fieldnames=results[0].keys())
    writer.writeheader()
    writer.writerows(results)
    result_string.seek(0)

    email_address = old_key.get_metadata('email')
    if email_address:
        new_key.set_metadata('email', email_address)
        send_email_notification(email_address, results, new_name, 'finished')

    new_key.set_contents_from_string(result_string.getvalue())
    new_key.make_public()
    old_key.delete()

def send_email_notification(address, results, settings, status):
    """
    Send an email notification when a job has been created or is finished.
    """
    finished_url = 'http://geo.tribapps.com/geocode_finished_jobs/%s' % settings
    if status == 'finished':
        subject = 'Finished geocoding job %s' % settings
        template = """
        Finished geocoding. Download results at {0}

        Had trouble processing {1:,d} addresses out of {2:,d} submitted.
        """.format(finished_url, results['failedEntityCount'], results['processedEntityCount'])
    elif status == 'pending':
        subject = 'Began processing geocode job %s' % settings
        template = """
        Just submitted job for geocoding.

        We'll email you when it's done, but the results will be available at %s
        """ % finished_url
    elif status == 'error':
        subject = 'Error processing geocode job %s' % settings
        template = """
        It looks like Bing had trouble processing the file you uploaded.

        Was it a CSV with column headings as described at http://geo.tribapps.com?
        """
    sg = sendgrid.SendGridClient(
        os.environ.get('SENDGRID_USERNAME', ''), os.environ.get('SENDGRID_PASSWORD', ''))
    message = sendgrid.Mail(subject=subject, from_email='noreply@tribpub.com')
    message.add_to(address)
    message.set_html(template)
    message.set_text(template)
    logging.info('Sending email report to %s' % ', '.join(message.to))
    status, msg = sg.send(message)
    if status != 200:
        logging.warning('Error sending email, got status %s: %s' % (status, msg))

def main():
    env_var = 'BING_MAPS_API_KEY'
    if env_var in os.environ:
        geocoder = BingGeocoder(os.environ[env_var])
    else:
        logging.error('Error: Need to provide Bing Maps API key')
        return

    parser = argparse.ArgumentParser()
    parser.add_argument('task')
    args = parser.parse_args()
    commands = ['download', 'statuses']
    if args.task in commands:
        logging.info('Running %s' % args.task)
        if args.task == 'download':
            download_jobs(geocoder)
        elif args.task == 'statuses':
            check_pending_jobs(geocoder)
    else:
        logging.error('%s is an unsupported task' % args.task)
        return

if __name__ == '__main__':
    main()
<|endoftext|>


<commit_before>import yaml
import os
import re
import argparse

BRIDGES = ('br-ex', 'br-mgmt')

def get_parser():
    parser = argparse.ArgumentParser(description="Remove patch ports from "
                                                 "deployment configuration "
                                                 "of environment")
    parser.add_argument("dirname",
                        help="Name of directory that contains deployment "
                             "configuration of environment.")
    subparsers = parser.add_subparsers()

    parser_a = subparsers.add_parser("remove_patch_ports",
                                     help="Remove patch ports.")
    parser_a.set_defaults(action=remove_patch_ports)

    parser_b = subparsers.add_parser("remove_predefined_nets",
                                     help="Remove predefined networks.")
    parser_b.set_defaults(action=remove_predefined_nets)

    parser_c = subparsers.add_parser("remove_physical_ports",
                                     help="Remove physical ports from linux "
                                     "bridge.")
    parser_c.set_defaults(action=remove_physical_ports)

    parser_d = subparsers.add_parser("reset_gw_admin",
                                     help="Move gateway from external net to "
                                     "admin net.")
    parser_d.set_defaults(action=reset_gw_admin)

    return parser

def load_yaml_file(filename):
    with open(filename) as f:
        return yaml.safe_load(f)

def dump_yaml_file(dict_obj, filename):
    with open(filename, 'w') as f:
        yaml.dump(dict_obj, f, default_flow_style=False)

def remove_patch_port(host_config, bridge_name):
    transformations = host_config['network_scheme']['transformations']
    for action in transformations:
        if (action['action'] == 'add-patch') and (bridge_name
                in action['bridges']):
            transformations.remove(action)
    return host_config

def remove_physical_port(host_config, bridge_name):
    transformations = host_config['network_scheme']['transformations']
    for action in transformations:
        if (action['action'] == 'add-port') and (bridge_name
                in action['bridge']):
            transformations.remove(action)
    return host_config

def remove_patch_ports(host_config):
    for bridge_name in BRIDGES:
        host_config = remove_patch_port(host_config, bridge_name)
    return host_config

def remove_physical_ports(host_config):
    for bridge_name in BRIDGES:
        host_config = remove_physical_port(host_config, bridge_name)
    return host_config

def remove_predefined_nets(host_config):
    host_config["quantum_settings"]["predefined_networks"] = {}
    return host_config

def reset_gw_admin(host_config):
    gw = host_config["master_ip"]
    if host_config["network_scheme"]["endpoints"]["br-ex"].get("gateway"):
        host_config["network_scheme"]["endpoints"]["br-ex"]["gateway"] = 'none'
        host_config["network_scheme"]["endpoints"]["br-fw-admin"]["gateway"] = gw
    return host_config

def update_env_deployment_info(dirname, action):
    pattern = "^[-\w]+_\d+.yaml$"
    host_files = os.listdir(dirname)
    for filename in host_files:
        if re.match(pattern, filename):
            host_file = os.path.join(dirname, filename)
            host_config = load_yaml_file(host_file)
            host_config = action(host_config)
            dump_yaml_file(host_config, host_file)

def get_bridge_provider(actions, bridge):
    add_br_actions = [action for action in actions
                      if action.get("action") == "add-br"]
    providers = [action.get("provider") for action in add_br_actions
                 if action.get("name") == bridge]
    if len(providers):
        return providers[-1]
    else:
        return None

def lnx_add_port(actions, bridge):
    for action in actions:
        if (action.get("action") == "add-port" and
                action.get("bridge") == bridge):
            port = action.get("name")
    if port:
        return ["brctl addif {0} {1}; ip link set up dev {1}"
                .format(bridge, port)]

def ovs_add_patch_ports(actions, bridge):
    for action in actions:
        if (action.get("action") == "add-patch" and
                bridge in action.get("bridges", [])):
            bridges = action.get("bridges", [])
            tags = action.get("tags", ["", ""])
            trunks = action.get("trunks", [])
    for tag in tags:
        tag = "tag={0}".format(str(tag)) if tag
    trunk_str = ",".join(trunks)
    if trunk_str:
        trunk_param = "trunks=[{0}]".format(trunk_str)
    if bridges:
        return ["ovs-vsctl add-port {0} {0}--{1} {3} {4}"
                "-- set interface {0}--{1} type=patch "
                "options:peer={1}--{0}"
                .format(bridges[0], bridges[1], tags[0], trunk_param),
                "ovs-vsctl add-port {1} {1}--{0} {3} {4}"
                "-- set interface {1}--{0} type=patch "
                "options:peer={0}--{1}"
                .format(bridges[0], bridges[1], tags[1], trunk_param)]

def main():
    args = get_parser().parse_args()

    update_env_deployment_info(args.dirname, args.action)

if __name__ == "__main__":
    main()
<commit_msg>Syntax error in if statement<commit_after>import yaml
import os
import re
import argparse

BRIDGES = ('br-ex', 'br-mgmt')

def get_parser():
    parser = argparse.ArgumentParser(description="Remove patch ports from "
                                                 "deployment configuration "
                                                 "of environment")
    parser.add_argument("dirname",
                        help="Name of directory that contains deployment "
                             "configuration of environment.")
    subparsers = parser.add_subparsers()

    parser_a = subparsers.add_parser("remove_patch_ports",
                                     help="Remove patch ports.")
    parser_a.set_defaults(action=remove_patch_ports)

    parser_b = subparsers.add_parser("remove_predefined_nets",
                                     help="Remove predefined networks.")
    parser_b.set_defaults(action=remove_predefined_nets)

    parser_c = subparsers.add_parser("remove_physical_ports",
                                     help="Remove physical ports from linux "
                                     "bridge.")
    parser_c.set_defaults(action=remove_physical_ports)

    parser_d = subparsers.add_parser("reset_gw_admin",
                                     help="Move gateway from external net to "
                                     "admin net.")
    parser_d.set_defaults(action=reset_gw_admin)

    return parser

def load_yaml_file(filename):
    with open(filename) as f:
        return yaml.safe_load(f)

def dump_yaml_file(dict_obj, filename):
    with open(filename, 'w') as f:
        yaml.dump(dict_obj, f, default_flow_style=False)

def remove_patch_port(host_config, bridge_name):
    transformations = host_config['network_scheme']['transformations']
    for action in transformations:
        if (action['action'] == 'add-patch') and (bridge_name
                in action['bridges']):
            transformations.remove(action)
    return host_config

def remove_physical_port(host_config, bridge_name):
    transformations = host_config['network_scheme']['transformations']
    for action in transformations:
        if (action['action'] == 'add-port') and (bridge_name
                in action['bridge']):
            transformations.remove(action)
    return host_config

def remove_patch_ports(host_config):
    for bridge_name in BRIDGES:
        host_config = remove_patch_port(host_config, bridge_name)
    return host_config

def remove_physical_ports(host_config):
    for bridge_name in BRIDGES:
        host_config = remove_physical_port(host_config, bridge_name)
    return host_config

def remove_predefined_nets(host_config):
    host_config["quantum_settings"]["predefined_networks"] = {}
    return host_config

def reset_gw_admin(host_config):
    gw = host_config["master_ip"]
    if host_config["network_scheme"]["endpoints"]["br-ex"].get("gateway"):
        host_config["network_scheme"]["endpoints"]["br-ex"]["gateway"] = 'none'
        host_config["network_scheme"]["endpoints"]["br-fw-admin"]["gateway"] = gw
    return host_config

def update_env_deployment_info(dirname, action):
    pattern = "^[-\w]+_\d+.yaml$"
    host_files = os.listdir(dirname)
    for filename in host_files:
        if re.match(pattern, filename):
            host_file = os.path.join(dirname, filename)
            host_config = load_yaml_file(host_file)
            host_config = action(host_config)
            dump_yaml_file(host_config, host_file)

def get_bridge_provider(actions, bridge):
    add_br_actions = [action for action in actions
                      if action.get("action") == "add-br"]
    providers = [action.get("provider") for action in add_br_actions
                 if action.get("name") == bridge]
    if len(providers):
        return providers[-1]
    else:
        return None

def lnx_add_port(actions, bridge):
    for action in actions:
        if (action.get("action") == "add-port" and
                action.get("bridge") == bridge):
            port = action.get("name")
    if port:
        return ["brctl addif {0} {1}; ip link set up dev {1}"
                .format(bridge, port)]

def ovs_add_patch_ports(actions, bridge):
    for action in actions:
        if (action.get("action") == "add-patch" and
                bridge in action.get("bridges", [])):
            bridges = action.get("bridges", [])
            tags = action.get("tags", ["", ""])
            trunks = action.get("trunks", [])
    for tag in tags:
        if tag:
            tag = "tag={0}".format(str(tag))
    trunk_str = ",".join(trunks)
    if trunk_str:
        trunk_param = "trunks=[{0}]".format(trunk_str)
    if bridges:
        return ["ovs-vsctl add-port {0} {0}--{1} {3} {4}"
                "-- set interface {0}--{1} type=patch "
                "options:peer={1}--{0}"
                .format(bridges[0], bridges[1], tags[0], trunk_param),
                "ovs-vsctl add-port {1} {1}--{0} {3} {4}"
                "-- set interface {1}--{0} type=patch "
                "options:peer={0}--{1}"
                .format(bridges[0], bridges[1], tags[1], trunk_param)]

def main():
    args = get_parser().parse_args()

    update_env_deployment_info(args.dirname, args.action)

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


<commit_before>import argparse
import datetime

import logging
import os

# If the tzlocal package is installed, then we will help the user out
# and print things out in the local timezone
LOCAL_TIMEZONE = None
try:
    import tzlocal
    LOCAL_TIMEZONE = tzlocal.get_localzone()
except ImportError:
    pass

from wanikani.core import WaniKani, Radical, Kanji, Vocabulary

CONFIG_PATH = os.path.join(os.path.expanduser('~'), '.wanikani')

logger = logging.getLogger(__name__)

# Setup tomorrow for use in filtering
tomorrow = datetime.datetime.today().replace(
    hour=0, minute=0, second=0, microsecond=0) + datetime.timedelta(days=1)
if LOCAL_TIMEZONE:
    tomorrow.replace(tzinfo=LOCAL_TIMEZONE)

def config():
    if os.path.exists(CONFIG_PATH):
        logger.debug('Loading config from %s', CONFIG_PATH)
        with open(CONFIG_PATH) as f:
            return f.read().strip()
    return ''

class Subcommand(object):
    def __init__(self, subparser):
        self.parser = subparser.add_parser(self.name, help=self.help)
        self.parser.set_defaults(func=self.execute)
        self.add_parsers()

    def add_parsers(self):
        pass

    def execute(self, client, args):
        raise NotImplementedError

class Profile(Subcommand):
    name = 'profile'
    help = 'Show simple profile information'

    def execute(self, client, args):
        p = client.profile()
        print 'Username:', p['username']
        print 'Level:', p['level']

class LevelProgress(Subcommand):
    name = 'progress'
    help = 'Show level progress'

    def execute(self, client, args):
        p = client.level_progress()
        print p['user_information']['username'], 'level', p['user_information']['level']
        print 'Radicals: {0}/{1}'.format(p['radicals_progress'], p['radicals_total'])
        print 'Kanji: {0}/{1}'.format(p['kanji_progress'], p['kanji_total'])

class RecentUnlocks(Subcommand):
    name = 'unlocks'
    help = 'Show recently unlocked items'
    formatter = '{0:<10} {1:<5} {2}'

    def execute(self, client, args):
        print self.formatter.format('type', 'level', 'character')
        for item in client.recent_unlocks():
            print self.formatter.format(item['type'], item['level'], item)

class Upcoming(Subcommand):
    name = 'upcoming'
    help = 'Show report of upcoming reviews'
    formatter = '{0:<20} {1:>10} {2:>10} {3:>10} {4:>10}'

    def add_parsers(self):
        self.parser.add_argument('-r', '--rollup', action='store_true')
        self.parser.add_argument('-c', '--current', action='store_true')
        self.parser.add_argument('-s', '--show', action='store_true')
        self.parser.add_argument('-l', '--limit', type=int)
        self.parser.add_argument('-b', '--blocker', action='store_true')
        self.parser.add_argument('-t', '--today', action='store_true')

    def execute(self, client, args):
        level = None
        if args.current or args.blocker:
            level = client.profile()['level']

        queue = client.upcoming(level)

        if args.current or args.blocker:
            print 'Showing upcoming items for level', level
            logger.info('Filtering out items that are not level %s', level)
            for ts in queue.keys():
                keep = []
                for item in queue[ts]:
                    if args.blocker and isinstance(item, Vocabulary):
                        logger.debug('Filtered out %s (Vocabulary)', item)
                        continue

                    if args.blocker and item.srs != u'apprentice':
                        logger.debug('Filtered out %s (srs %s)', str(item), str(item.srs))
                        continue

                    if item['level'] != level:
                        logger.debug('Filtered out %s (level %d)', item, item['level'])
                        continue

                    keep.append(item)

                queue[ts] = keep

        if args.rollup:
            now = datetime.datetime.now().replace(microsecond=0)
            # now += datetime.timedelta(hours=5) #  Future date for testing
            rollup = []
            for ts in queue.keys():
                if ts < now:
                    rollup += queue.pop(ts)
            if rollup:
                queue[now] = rollup
                print 'Rolled up reviews'

        counter = 0
        print self.formatter.format('Timestamp', 'Radicals', 'Kanji', 'Vocab', 'Total')
        totals = {
            Radical: 0,
            Kanji: 0,
            Vocabulary: 0,
            'total': 0,
        }
        for ts in sorted(queue):
            if args.today:
                if ts >= tomorrow:
                    logger.debug('Skipping future dates %s', ts)
                    continue
            if args.limit and counter == args.limit:
                break
            if len(queue[ts]):
                counter += 1
                counts = {
                    Radical: 0,
                    Kanji: 0,
                    Vocabulary: 0,
                }

                for obj in queue[ts]:
                    totals['total'] += 1
                    if isinstance(obj, Radical):
                        counts[Radical] += 1
                        totals[Radical] += 1
                    if isinstance(obj, Kanji):
                        counts[Kanji] += 1
                        totals[Kanji] += 1
                    if isinstance(obj, Vocabulary):
                        counts[Vocabulary] += 1
                        totals[Vocabulary] += 1

                if LOCAL_TIMEZONE:
                    ts.replace(tzinfo=LOCAL_TIMEZONE)
                # Note the trailing commas,
                # We only want a newline for the last one
                print self.formatter.format(
                    str(ts),
                    counts[Radical],
                    counts[Kanji],
                    counts[Vocabulary],
                    len(queue[ts]),
                )

                if args.show:
                    print '\t',
                    print ', '.join([str(x) for x in queue[ts]])
        print self.formatter.format(
            'Totals',
            totals[Radical],
            totals[Kanji],
            totals[Vocabulary],
            totals['total']
        )

class SetAPIKey(Subcommand):
    name = 'set_key'
    help = 'Set API Key'

    def add_parsers(self):
        self.parser.add_argument('api_key', help="New API Key")

    def execute(self, client, args):
        with open(CONFIG_PATH, 'w') as f:
            f.write(args.api_key)
        print 'Wrote {0} to {1}'.format(args.api_key, CONFIG_PATH)

class Gourse(Subcommand):
    name = 'gource'
    help = 'Generate log for rendering with gource'

    def add_parsers(self):
        self.parser.add_argument(
            '-l', '--levels',
            help="Show level in path",
        )

    colors = {
        'Vocabulary': '882D9E',
        'Radical': '0093DD',
        'Kanji': 'DD0093',
    }

    burned = '434343'

    def execute(self, client, args):
        log = []
        profile = client.profile()
        queue = client.upcoming(args.levels)
        for ts in queue:
            for item in queue[ts]:
                try:
                    string = '{0}|{1}|{2}|{3}/{4}|{5}'.format(
                        item.unlocked,
                        profile['username'],
                        'A',
                        item.__class__.__name__,
                        item,
                        self.colors[item.__class__.__name__],
                    )
                    log.append(string)
                except UnicodeDecodeError:
                    pass

        for item in sorted(log):
            print item

def main():
    parser = argparse.ArgumentParser()
    subparsers = parser.add_subparsers()

    # Global Options
    parser.add_argument('-a', '--api-key', default=config())
    parser.add_argument(
        '-d', '--debug',
        action='store_const',
        const=logging.DEBUG,
        default=logging.WARNING
    )

    # Add our sub commands
    Profile(subparsers)
    LevelProgress(subparsers)
    RecentUnlocks(subparsers)
    Upcoming(subparsers)
    SetAPIKey(subparsers)
    Gourse(subparsers)

    args = parser.parse_args()
    logging.basicConfig(level=args.debug)
    client = WaniKani(args.api_key)
    args.func(client, args)
<commit_msg>Support for grouping source output by level and fixing bug with excluding burned items.<commit_after>import argparse
import datetime

import logging
import os

# If the tzlocal package is installed, then we will help the user out
# and print things out in the local timezone
LOCAL_TIMEZONE = None
try:
    import tzlocal
    LOCAL_TIMEZONE = tzlocal.get_localzone()
except ImportError:
    pass

from wanikani.core import WaniKani, Radical, Kanji, Vocabulary

CONFIG_PATH = os.path.join(os.path.expanduser('~'), '.wanikani')

logger = logging.getLogger(__name__)

# Setup tomorrow for use in filtering
tomorrow = datetime.datetime.today().replace(
    hour=0, minute=0, second=0, microsecond=0) + datetime.timedelta(days=1)
if LOCAL_TIMEZONE:
    tomorrow.replace(tzinfo=LOCAL_TIMEZONE)

def config():
    if os.path.exists(CONFIG_PATH):
        logger.debug('Loading config from %s', CONFIG_PATH)
        with open(CONFIG_PATH) as f:
            return f.read().strip()
    return ''

class Subcommand(object):
    def __init__(self, subparser):
        self.parser = subparser.add_parser(self.name, help=self.help)
        self.parser.set_defaults(func=self.execute)
        self.add_parsers()

    def add_parsers(self):
        pass

    def execute(self, client, args):
        raise NotImplementedError

class Profile(Subcommand):
    name = 'profile'
    help = 'Show simple profile information'

    def execute(self, client, args):
        p = client.profile()
        print 'Username:', p['username']
        print 'Level:', p['level']

class LevelProgress(Subcommand):
    name = 'progress'
    help = 'Show level progress'

    def execute(self, client, args):
        p = client.level_progress()
        print p['user_information']['username'], 'level', p['user_information']['level']
        print 'Radicals: {0}/{1}'.format(p['radicals_progress'], p['radicals_total'])
        print 'Kanji: {0}/{1}'.format(p['kanji_progress'], p['kanji_total'])

class RecentUnlocks(Subcommand):
    name = 'unlocks'
    help = 'Show recently unlocked items'
    formatter = '{0:<10} {1:<5} {2}'

    def execute(self, client, args):
        print self.formatter.format('type', 'level', 'character')
        for item in client.recent_unlocks():
            print self.formatter.format(item['type'], item['level'], item)

class Upcoming(Subcommand):
    name = 'upcoming'
    help = 'Show report of upcoming reviews'
    formatter = '{0:<20} {1:>10} {2:>10} {3:>10} {4:>10}'

    def add_parsers(self):
        self.parser.add_argument('-r', '--rollup', action='store_true')
        self.parser.add_argument('-c', '--current', action='store_true')
        self.parser.add_argument('-s', '--show', action='store_true')
        self.parser.add_argument('-l', '--limit', type=int)
        self.parser.add_argument('-b', '--blocker', action='store_true')
        self.parser.add_argument('-t', '--today', action='store_true')

    def execute(self, client, args):
        level = None
        if args.current or args.blocker:
            level = client.profile()['level']

        queue = client.upcoming(level)

        if args.current or args.blocker:
            print 'Showing upcoming items for level', level
            logger.info('Filtering out items that are not level %s', level)
            for ts in queue.keys():
                keep = []
                for item in queue[ts]:
                    if args.blocker and isinstance(item, Vocabulary):
                        logger.debug('Filtered out %s (Vocabulary)', item)
                        continue

                    if args.blocker and item.srs != u'apprentice':
                        logger.debug('Filtered out %s (srs %s)', str(item), str(item.srs))
                        continue

                    if item['level'] != level:
                        logger.debug('Filtered out %s (level %d)', item, item['level'])
                        continue

                    keep.append(item)

                queue[ts] = keep

        if args.rollup:
            now = datetime.datetime.now().replace(microsecond=0)
            # now += datetime.timedelta(hours=5) #  Future date for testing
            rollup = []
            for ts in queue.keys():
                if ts < now:
                    rollup += queue.pop(ts)
            if rollup:
                queue[now] = rollup
                print 'Rolled up reviews'

        counter = 0
        print self.formatter.format('Timestamp', 'Radicals', 'Kanji', 'Vocab', 'Total')
        totals = {
            Radical: 0,
            Kanji: 0,
            Vocabulary: 0,
            'total': 0,
        }
        for ts in sorted(queue):
            if args.today:
                if ts >= tomorrow:
                    logger.debug('Skipping future dates %s', ts)
                    continue
            if args.limit and counter == args.limit:
                break
            if len(queue[ts]):
                counter += 1
                counts = {
                    Radical: 0,
                    Kanji: 0,
                    Vocabulary: 0,
                }

                for obj in queue[ts]:
                    totals['total'] += 1
                    if isinstance(obj, Radical):
                        counts[Radical] += 1
                        totals[Radical] += 1
                    if isinstance(obj, Kanji):
                        counts[Kanji] += 1
                        totals[Kanji] += 1
                    if isinstance(obj, Vocabulary):
                        counts[Vocabulary] += 1
                        totals[Vocabulary] += 1

                if LOCAL_TIMEZONE:
                    ts.replace(tzinfo=LOCAL_TIMEZONE)
                # Note the trailing commas,
                # We only want a newline for the last one
                print self.formatter.format(
                    str(ts),
                    counts[Radical],
                    counts[Kanji],
                    counts[Vocabulary],
                    len(queue[ts]),
                )

                if args.show:
                    print '\t',
                    print ', '.join([str(x) for x in queue[ts]])
        print self.formatter.format(
            'Totals',
            totals[Radical],
            totals[Kanji],
            totals[Vocabulary],
            totals['total']
        )

class SetAPIKey(Subcommand):
    name = 'set_key'
    help = 'Set API Key'

    def add_parsers(self):
        self.parser.add_argument('api_key', help="New API Key")

    def execute(self, client, args):
        with open(CONFIG_PATH, 'w') as f:
            f.write(args.api_key)
        print 'Wrote {0} to {1}'.format(args.api_key, CONFIG_PATH)

class Gourse(Subcommand):
    name = 'gource'
    help = 'Generate log for rendering with gource'

    def add_parsers(self):
        self.parser.add_argument(
            '-l', '--levels',
            help="Show level in path",
        )
        self.parser.add_argument(
            '-g', '--group',
            help="Group by level",
            action='store_true',
        )

    colors = {
        'Vocabulary': '882D9E',
        'Radical': '0093DD',
        'Kanji': 'DD0093',
    }

    burned = '434343'

    def execute(self, client, args):
        log = []
        profile = client.profile()

        mapping = {
            Radical: client.radicals,
            Kanji: client.kanji,
            Vocabulary: client.vocabulary
        }

        for klass in mapping:
            for item in mapping[klass](args.levels):
                try:
                    string = '{0}|{1}|{2}|{3}/{4}|{5}'.format(
                        item.unlocked,
                        profile['username'],
                        'A',
                        item['level'] if args.group else item.__class__.__name__,
                        item,
                        self.colors[item.__class__.__name__],
                    )
                    log.append(string)

                    if item.srs == u'burned':
                        string = '{0}|{1}|{2}|{3}/{4}|{5}'.format(
                            item.burned,
                            profile['username'],
                            'M',
                            item['level'] if args.group else item.__class__.__name__,
                            item,
                            self.burned,
                        )
                        log.append(string)
                except UnicodeDecodeError:
                    pass
                except TypeError:
                    pass

        for item in sorted(log):
            print item

def main():
    parser = argparse.ArgumentParser()
    subparsers = parser.add_subparsers()

    # Global Options
    parser.add_argument('-a', '--api-key', default=config())
    parser.add_argument(
        '-d', '--debug',
        action='store_const',
        const=logging.DEBUG,
        default=logging.WARNING
    )

    # Add our sub commands
    Profile(subparsers)
    LevelProgress(subparsers)
    RecentUnlocks(subparsers)
    Upcoming(subparsers)
    SetAPIKey(subparsers)
    Gourse(subparsers)

    args = parser.parse_args()
    logging.basicConfig(level=args.debug)
    client = WaniKani(args.api_key)
    args.func(client, args)
<|endoftext|>


<commit_before>"""Plot posterior traces as violin plot."""
from ..data import convert_to_dataset
from ..labels import BaseLabeller
from ..sel_utils import xarray_var_iter
from ..utils import _var_names
from ..rcparams import rcParams
from .plot_utils import default_grid, filter_plotters_list, get_plotting_function

def plot_violin(
    data,
    var_names=None,
    filter_vars=None,
    transform=None,
    quartiles=True,
    rug=False,
    hdi_prob=None,
    shade=0.35,
    bw="default",
    circular=False,
    sharex=True,
    sharey=True,
    grid=None,
    figsize=None,
    textsize=None,
    labeller=None,
    ax=None,
    shade_kwargs=None,
    rug_kwargs=None,
    backend=None,
    backend_kwargs=None,
    show=None,
):
    """Plot posterior of traces as violin plot.

    Notes
    -----
    If multiple chains are provided for a variable they will be combined

    Parameters
    ----------
    data: obj
        Any object that can be converted to an az.InferenceData object
        Refer to documentation of az.convert_to_dataset for details
    var_names: list of variable names, optional
        Variables to be plotted, if None all variable are plotted. Prefix the
        variables by `~` when you want to exclude them from the plot.
    filter_vars: {None, "like", "regex"}, optional, default=None
        If `None` (default), interpret var_names as the real variables names. If "like",
        interpret var_names as substrings of the real variables names. If "regex",
        interpret var_names as regular expressions on the real variables names. A la
        `pandas.filter`.
    transform: callable
        Function to transform data (defaults to None i.e. the identity function)
    quartiles: bool, optional
        Flag for plotting the interquartile range, in addition to the hdi_prob*100%
        intervals. Defaults to True
    rug: bool
        If True adds a jittered rugplot. Defaults to False.
    hdi_prob: float, optional
        Plots highest posterior density interval for chosen percentage of density. Defaults to 0.94.
    shade: float
        Alpha blending value for the shaded area under the curve, between 0
        (no shade) and 1 (opaque). Defaults to 0
    bw: float or str, optional
        If numeric, indicates the bandwidth and must be positive.
        If str, indicates the method to estimate the bandwidth and must be
        one of "scott", "silverman", "isj" or "experimental" when `circular` is False
        and "taylor" (for now) when `circular` is True.
        Defaults to "default" which means "experimental" when variable is not circular
        and "taylor" when it is.
    circular: bool, optional.
        If True, it interprets `values` is a circular variable measured in radians
        and a circular KDE is used. Defaults to False.
    grid : tuple
        Number of rows and columns. Defaults to None, the rows and columns are
        automatically inferred.
    figsize: tuple
        Figure size. If None it will be defined automatically.
    textsize: int
        Text size of the point_estimates, axis ticks, and highest density interval. If None it will
        be autoscaled based on figsize.
    labeller : labeller instance, optional
        Class providing the method `make_label_vert` to generate the labels in the plot titles.
        Read the :ref:`label_guide` for more details and usage examples.
    sharex: bool
        Defaults to True, violinplots share a common x-axis scale.
    sharey: bool
        Defaults to True, violinplots share a common y-axis scale.
    ax: numpy array-like of matplotlib axes or bokeh figures, optional
        A 2D array of locations into which to plot the densities. If not supplied, Arviz will create
        its own array of plot areas (and return it).
    shade_kwargs: dicts, optional
        Additional keywords passed to `fill_between`, or `barh` to control the shade.
    rug_kwargs: dict
        Keywords passed to the rug plot. If true only the righ half side of the violin will be
        plotted.
    backend: str, optional
        Select plotting backend {"matplotlib","bokeh"}. Default "matplotlib".
    backend_kwargs: bool, optional
        These are kwargs specific to the backend being used. For additional documentation
        check the plotting method of the backend.
    show: bool, optional
        Call backend show function.

    Returns
    -------
    axes: matplotlib axes or bokeh figures

    Examples
    --------
    Show a default violin plot

    .. plot::
        :context: close-figs

        >>> import arviz as az
        >>> data = az.load_arviz_data('centered_eight')
        >>> az.plot_violin(data)

    Show a default violin plot, but with a transformation applied to the data

    .. plot::
        :context: close-figs

        >>> az.plot_violin(data, var_names="tau", transform=np.log)

    """
    if labeller is None:
        labeller = BaseLabeller()

    data = convert_to_dataset(data, group="posterior")
    if transform is not None:
        data = transform(data)
    var_names = _var_names(var_names, data, filter_vars)

    plotters = filter_plotters_list(
        list(xarray_var_iter(data, var_names=var_names, combined=True)), "plot_violin"
    )

    rows, cols = default_grid(len(plotters), grid=grid)

    if hdi_prob is None:
        hdi_prob = rcParams["stats.hdi_prob"]
    else:
        if not 1 >= hdi_prob > 0:
            raise ValueError("The value of hdi_prob should be in the interval (0, 1]")

    violinplot_kwargs = dict(
        ax=ax,
        plotters=plotters,
        figsize=figsize,
        rows=rows,
        cols=cols,
        sharex=sharex,
        sharey=sharey,
        shade_kwargs=shade_kwargs,
        shade=shade,
        rug=rug,
        rug_kwargs=rug_kwargs,
        bw=bw,
        textsize=textsize,
        labeller=labeller,
        circular=circular,
        hdi_prob=hdi_prob,
        quartiles=quartiles,
        backend_kwargs=backend_kwargs,
        show=show,
    )

    if backend is None:
        backend = rcParams["plot.backend"]
    backend = backend.lower()

    # TODO: Add backend kwargs
    plot = get_plotting_function("plot_violin", "violinplot", backend)
    ax = plot(**violinplot_kwargs)
    return ax
<commit_msg>Add docs references to plot_violin docstring (#1898)<commit_after>"""Plot posterior traces as violin plot."""
from ..data import convert_to_dataset
from ..labels import BaseLabeller
from ..sel_utils import xarray_var_iter
from ..utils import _var_names
from ..rcparams import rcParams
from .plot_utils import default_grid, filter_plotters_list, get_plotting_function

def plot_violin(
    data,
    var_names=None,
    filter_vars=None,
    transform=None,
    quartiles=True,
    rug=False,
    hdi_prob=None,
    shade=0.35,
    bw="default",
    circular=False,
    sharex=True,
    sharey=True,
    grid=None,
    figsize=None,
    textsize=None,
    labeller=None,
    ax=None,
    shade_kwargs=None,
    rug_kwargs=None,
    backend=None,
    backend_kwargs=None,
    show=None,
):
    """Plot posterior of traces as violin plot.

    Notes
    -----
    If multiple chains are provided for a variable they will be combined

    Parameters
    ----------
    data: obj
        Any object that can be converted to an :class:`arviz.InferenceData` object
        Refer to documentation of :func:`arviz.convert_to_dataset` for details
    var_names: list of variable names, optional
        Variables to be plotted, if None all variable are plotted. Prefix the
        variables by ``~`` when you want to exclude them from the plot.
    filter_vars: {None, "like", "regex"}, optional, default=None
        If `None` (default), interpret var_names as the real variables names. If "like",
        interpret var_names as substrings of the real variables names. If "regex",
        interpret var_names as regular expressions on the real variables names. A la
        ``pandas.filter``.
    transform: callable
        Function to transform data (defaults to None i.e. the identity function).
    quartiles: bool, optional
        Flag for plotting the interquartile range, in addition to the ``hdi_prob`` *100%
        intervals. Defaults to ``True``.
    rug: bool
        If ``True`` adds a jittered rugplot. Defaults to ``False``.
    hdi_prob: float, optional
        Plots highest posterior density interval for chosen percentage of density.
        Defaults to 0.94.
    shade: float
        Alpha blending value for the shaded area under the curve, between 0
        (no shade) and 1 (opaque). Defaults to 0.
    bw: float or str, optional
        If numeric, indicates the bandwidth and must be positive.
        If str, indicates the method to estimate the bandwidth and must be
        one of "scott", "silverman", "isj" or "experimental" when ``circular`` is ``False``
        and "taylor" (for now) when ``circular`` is ``True``.
        Defaults to "default" which means "experimental" when variable is not circular
        and "taylor" when it is.
    circular: bool, optional.
        If ``True``, it interprets `values` is a circular variable measured in radians
        and a circular KDE is used. Defaults to ``False``.
    grid : tuple
        Number of rows and columns. Defaults to None, the rows and columns are
        automatically inferred.
    figsize: tuple
        Figure size. If None it will be defined automatically.
    textsize: int
        Text size of the point_estimates, axis ticks, and highest density interval. If None it will
        be autoscaled based on ``figsize``.
    labeller : labeller instance, optional
        Class providing the method ``make_label_vert`` to generate the labels in the plot titles.
        Read the :ref:`label_guide` for more details and usage examples.
    sharex: bool
        Defaults to ``True``, violinplots share a common x-axis scale.
    sharey: bool
        Defaults to ``True``, violinplots share a common y-axis scale.
    ax: numpy array-like of matplotlib axes or bokeh figures, optional
        A 2D array of locations into which to plot the densities. If not supplied, Arviz will create
        its own array of plot areas (and return it).
    shade_kwargs: dicts, optional
        Additional keywords passed to :meth:`matplotlib.axes.Axes.fill_between`, or
        :meth:`matplotlib.axes.Axes.barh` to control the shade.
    rug_kwargs: dict
        Keywords passed to the rug plot. If true only the right half side of the violin will be
        plotted.
    backend: str, optional
        Select plotting backend {"matplotlib","bokeh"}. Default to "matplotlib".
    backend_kwargs: bool, optional
        These are kwargs specific to the backend being used, passed to
        :func:`matplotlib.pyplot.subplots` or :func:`bokeh.plotting.figure`.
        For additional documentation check the plotting method of the backend.
    show: bool, optional
        Call backend show function.

    Returns
    -------
    axes: matplotlib axes or bokeh figures

    See Also
    --------
    plot_forest: Forest plot to compare HDI intervals from a number of distributions.

    Examples
    --------
    Show a default violin plot

    .. plot::
        :context: close-figs

        >>> import arviz as az
        >>> data = az.load_arviz_data('centered_eight')
        >>> az.plot_violin(data)

    Show a default violin plot, but with a transformation applied to the data

    .. plot::
        :context: close-figs

        >>> az.plot_violin(data, var_names="tau", transform=np.log)

    """
    if labeller is None:
        labeller = BaseLabeller()

    data = convert_to_dataset(data, group="posterior")
    if transform is not None:
        data = transform(data)
    var_names = _var_names(var_names, data, filter_vars)

    plotters = filter_plotters_list(
        list(xarray_var_iter(data, var_names=var_names, combined=True)), "plot_violin"
    )

    rows, cols = default_grid(len(plotters), grid=grid)

    if hdi_prob is None:
        hdi_prob = rcParams["stats.hdi_prob"]
    else:
        if not 1 >= hdi_prob > 0:
            raise ValueError("The value of hdi_prob should be in the interval (0, 1]")

    violinplot_kwargs = dict(
        ax=ax,
        plotters=plotters,
        figsize=figsize,
        rows=rows,
        cols=cols,
        sharex=sharex,
        sharey=sharey,
        shade_kwargs=shade_kwargs,
        shade=shade,
        rug=rug,
        rug_kwargs=rug_kwargs,
        bw=bw,
        textsize=textsize,
        labeller=labeller,
        circular=circular,
        hdi_prob=hdi_prob,
        quartiles=quartiles,
        backend_kwargs=backend_kwargs,
        show=show,
    )

    if backend is None:
        backend = rcParams["plot.backend"]
    backend = backend.lower()

    # TODO: Add backend kwargs
    plot = get_plotting_function("plot_violin", "violinplot", backend)
    ax = plot(**violinplot_kwargs)
    return ax
<|endoftext|>