<commit_before># Datetime Packages
from time import mktime
from datetime import timedelta
from datetime import datetime
import pytz

# Celery Imports
from celery.task import Task, PeriodicTask
from celery.utils.log import get_task_logger

# Feedparser
import feedparser

# Models
from models import Feed, FeedItem

# Logger object
LOGGER = get_task_logger(__name__)

class EnqueueFeedUpdates(PeriodicTask):
    """
    Updates the research agents for all characters.
    """

    # Run every minute
    run_every = timedelta(minutes=1)

    def run(self, **kwargs):

        # Get feeds that need to be updated
        feeds = Feed.objects.filter(next_update__lte=pytz.utc.localize(datetime.utcnow()))

        # Enqueue Tasks
        for feed in feeds:
            UpdateFeed.apply_async(args=[feed.id])

class UpdateFeed(Task):
    """
    Update a feed's items. Remove all old items from the DB.
    """

    def run(self, feed_id):

        # Get feed object
        feed = Feed.objects.get(id=feed_id)

        # Debug log
        LOGGER.debug("Updating feed %s", feed.name)

        # Set User-Agent header
        feedparser.USER_AGENT = "Element43Feedreader/Git +https://element-43.com/"

        # Fetch feed
        document = feedparser.parse(feed.url)

        if document.status == 200:
            # Remove all existing entries of that feed
            FeedItem.objects.filter(feed=feed).delete()

            # Add current content
            for item in document.entries:
                # Create item
                feed_item = FeedItem(feed=feed,
                                     title=item.title,
                                     description=item.summary,
                                     link=item.link,
                                     published=pytz.utc.localize(datetime.fromtimestamp(mktime(item.published_parsed))))

                # Save item to DB
                feed_item.save()

        else:
            # Log HTTP error
            LOGGER.warn("Error fetching feed %s - server returned status code %d .", feed.name, document.status)

        # Set next update to be 5 minutes from now
        five_minutes_from_now = datetime.utcnow() + timedelta(minutes=5)
        feed.next_update = pytz.utc.localize(five_minutes_from_now)
        feed.save()

        LOGGER.debug("Finished updating feed %s", feed.name)
<commit_msg>Feedreader fix<commit_after># Datetime Packages
from time import mktime
from datetime import timedelta
from datetime import datetime
import pytz

# Celery Imports
from celery.task import Task, PeriodicTask
from celery.utils.log import get_task_logger

# Feedparser
import feedparser

# Models
from models import Feed, FeedItem

# Logger object
LOGGER = get_task_logger(__name__)

class EnqueueFeedUpdates(PeriodicTask):
    """
    Updates the research agents for all characters.
    """

    # Run every minute
    run_every = timedelta(minutes=1)

    def run(self, **kwargs):

        # Get feeds that need to be updated
        feeds = Feed.objects.filter(next_update__lte=pytz.utc.localize(datetime.utcnow()))

        # Enqueue Tasks
        for feed in feeds:
            UpdateFeed.apply_async(args=[feed.id])

class UpdateFeed(Task):
    """
    Update a feed's items. Remove all old items from the DB.
    """

    def run(self, feed_id):

        # Get feed object
        feed = Feed.objects.get(id=feed_id)

        # Debug log
        LOGGER.debug("Updating feed %s", feed.name)

        # Set User-Agent header
        feedparser.USER_AGENT = "Element43Feedreader/Git +https://element-43.com/"

        # Fetch feed
        document = feedparser.parse(feed.url)

        if document.status == 200:
            # Remove all existing entries of that feed
            FeedItem.objects.filter(feed=feed).delete()

            # Add current content
            for item in document.entries:
                # Create item
                feed_item = FeedItem(feed=feed,
                                     title=(item.title[:97] + '...') if len(item.title) > 100 else item.title,
                                     description=item.summary,
                                     link=item.link,
                                     published=pytz.utc.localize(datetime.fromtimestamp(mktime(item.published_parsed))))

                # Save item to DB
                feed_item.save()

        else:
            # Log HTTP error
            LOGGER.warn("Error fetching feed %s - server returned status code %d .", feed.name, document.status)

        # Set next update to be 5 minutes from now
        five_minutes_from_now = datetime.utcnow() + timedelta(minutes=5)
        feed.next_update = pytz.utc.localize(five_minutes_from_now)
        feed.save()

        LOGGER.debug("Finished updating feed %s", feed.name)
<|endoftext|>


<commit_before>import logging
import urllib

from django.core.paginator import Paginator, InvalidPage
from django.contrib.auth.models import User
from django.conf.urls.defaults import url
from django.shortcuts import get_object_or_404
from django.http import Http404
from django.core.urlresolvers import reverse

from haystack.query import SearchQuerySet
from haystack.utils import Highlighter
from tastypie import fields
from tastypie.authentication import BasicAuthentication
from tastypie.authorization import Authorization
from tastypie.constants import ALL_WITH_RELATIONS, ALL
from tastypie.resources import ModelResource
from tastypie.exceptions import NotFound, ImmediateHttpResponse
from tastypie import http
from tastypie.utils.mime import determine_format, build_content_type
from tastypie.http import HttpCreated
from tastypie.utils import dict_strip_unicode_keys, trailing_slash

from core.forms import FacetedSearchForm
from builds.models import Build, Version
from projects.models import Project, ImportedFile
from projects.utils import highest_version, mkversion
from projects import tasks
from djangome import views as djangome

log = logging.getLogger(__name__)

class SearchMixin(object):
    '''
    Adds a search api to any ModelResource provided the model is indexed.
    The search can be configured using the Meta class in each ModelResource.
    The search is limited to the model defined by the meta queryset. If the
    search is invalid, a 400 Bad Request will be raised.

    e.g.
        class Meta:
            # Return facet counts for each facetname
            search_facets = ['facetname1', 'facetname1']

            # Number of results returned per page
            search_page_size = 20

            # Highlight search terms in the text
            search_highlight = True
    '''
    def get_search(self, request, **kwargs):
        self.method_check(request, allowed=['get'])
        self.is_authenticated(request)
        self.throttle_check(request)
        object_list = self._search(request,
            self._meta.queryset.model,
            facets = getattr(self._meta, 'search_facets', []),
            page_size = getattr(self._meta, 'search_page_size', 20),
            highlight = getattr(self._meta, 'search_highlight', True),
        )
        self.log_throttled_access(request)
        return self.create_response(request, object_list)

    def _url_template(self, query, selected_facets):
        '''
        Construct a url template to assist with navigating the resources.
        This looks a bit nasty but urllib.urlencode resulted in even
        nastier output...
        '''
        query_params = []
        for facet in selected_facets:
            query_params.append(('selected_facets', facet))
        query_params += [('q', query), ('format', 'json'), ('page', '{0}')]
        query_string = '&'.join('='.join(p) for p in query_params)
        url_template = reverse('api_get_search', kwargs={
            'resource_name': self._meta.resource_name,
            'api_name': 'v1'
        })
        return url_template + '?' + query_string

    def _search(self, request, model, facets=None, page_size=20, highlight=True):
        '''
        `facets`
            A list of facets to include with the results
        `models`
            Limit the search to one or more models
        '''
        form = FacetedSearchForm(request.GET, facets=facets or [],
                                 models=(model,), load_all=True)
        if not form.is_valid():
            return self.error_response({'errors': form.errors }, request)
        results = form.search()

        paginator = Paginator(results, page_size)
        try:
            page = paginator.page(int(request.GET.get('page', 1)))
        except InvalidPage:
            raise Http404("Sorry, no results on that page.")

        objects = []
        query = request.GET.get('q', '')
        highlighter = Highlighter(query)
        for result in page.object_list:
            if not result:
                continue
            text = result.text
            if highlight:
                text = highlighter.highlight(text)
            bundle = self.build_bundle(obj=result.object, request=request)
            bundle = self.full_dehydrate(bundle)
            bundle.data['text'] = text
            objects.append(bundle)

        url_template = self._url_template(query, form['selected_facets'].value())
        page_data = {
            'number': page.number,
            'per_page': paginator.per_page,
            'num_pages': paginator.num_pages,
            'page_range': paginator.page_range,
            'object_count': paginator.count,
            'url_template': url_template,
        }
        if page.has_next():
            page_data['url_next'] = url_template.format(page.next_page_number())
        if page.has_previous():
            page_data['url_prev'] = url_template.format(page.previous_page_number())

        object_list = {
            'page': page_data,
            'objects': objects,
        }
        if facets:
            object_list.update({'facets': results.facet_counts()})
        return object_list

    # XXX: This method is available in the latest tastypie, remove
    # once available in production.
    def error_response(self, errors, request):
        if request:
            desired_format = self.determine_format(request)
        else:
            desired_format = self._meta.default_format
        serialized = self.serialize(request, errors, desired_format)
        response = http.HttpBadRequest(content=serialized, content_type=build_content_type(desired_format))
        raise ImmediateHttpResponse(response=response)

class PostAuthentication(BasicAuthentication):
    def is_authenticated(self, request, **kwargs):
        if request.method == "GET":
            return True
        return super(PostAuthentication, self).is_authenticated(request, **kwargs)

class EnhancedModelResource(ModelResource):
    def obj_get_list(self, request=None, **kwargs):
        """
        A ORM-specific implementation of ``obj_get_list``.

        Takes an optional ``request`` object, whose ``GET`` dictionary can be
        used to narrow the query.
        """
        filters = None

        if hasattr(request, 'GET'):
            filters = request.GET

        applicable_filters = self.build_filters(filters=filters)
        applicable_filters.update(kwargs)

        try:
            return self.get_object_list(request).filter(**applicable_filters)
        except ValueError, e:
            raise NotFound("Invalid resource lookup data provided (mismatched type).: %s" % e)

class UserResource(ModelResource):
    class Meta:
        allowed_methods = ['get']
        queryset = User.objects.all()
        fields = ['username', 'first_name', 'last_name', 'last_login', 'id']
        filtering = {
            'username': 'exact',
        }

    def override_urls(self):
        return [
            url(r"^(?P<resource_name>%s)/(?P<username>[a-z-_]+)/$" % self._meta.resource_name, self.wrap_view('dispatch_detail'), name="api_dispatch_detail"),
        ]

class ProjectResource(ModelResource, SearchMixin):
    users = fields.ToManyField(UserResource, 'users')

    class Meta:
        include_absolute_url = True
        allowed_methods = ['get', 'post', 'put']
        queryset = Project.objects.all()
        authentication = PostAuthentication()
        authorization = Authorization()
        excludes = ['path', 'skip', 'featured']
        filtering = {
            "users": ALL_WITH_RELATIONS,
            "slug": ALL_WITH_RELATIONS,
        }

    def dehydrate(self, bundle):
        bundle.data['subdomain'] = "http://%s/" % bundle.obj.subdomain
        return bundle

    def post_list(self, request, **kwargs):
        """
        Creates a new resource/object with the provided data.

        Calls ``obj_create`` with the provided data and returns a response
        with the new resource's location.

        If a new resource is created, return ``HttpCreated`` (201 Created).
        """
        deserialized = self.deserialize(request, request.raw_post_data, format=request.META.get('CONTENT_TYPE', 'application/json'))

        # Force this in an ugly way, at least should do "reverse"
        deserialized["users"] = ["/api/v1/user/%s/" % request.user.id,]
        bundle = self.build_bundle(data=dict_strip_unicode_keys(deserialized))
        self.is_valid(bundle, request)
        updated_bundle = self.obj_create(bundle, request=request)
        return HttpCreated(location=self.get_resource_uri(updated_bundle))

    def override_urls(self):
        return [
            url(r"^(?P<resource_name>%s)/search%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('get_search'), name="api_get_search"),
            url(r"^(?P<resource_name>%s)/(?P<slug>[a-z-_]+)/$" % self._meta.resource_name, self.wrap_view('dispatch_detail'), name="api_dispatch_detail"),
        ]

class BuildResource(EnhancedModelResource):
    project = fields.ForeignKey(ProjectResource, 'project')
    version = fields.ForeignKey('api.base.VersionResource', 'version')

    class Meta:
        include_absolute_url = True
        allowed_methods = ['get', 'post', 'put']
        queryset = Build.objects.all()
        authentication = PostAuthentication()
        authorization = Authorization()
        filtering = {
            "project": ALL_WITH_RELATIONS,
            "slug": ALL_WITH_RELATIONS,
            "type": ALL_WITH_RELATIONS,
            "state": ALL_WITH_RELATIONS,
        }

    def override_urls(self):
        return [
            url(r"^(?P<resource_name>%s)/(?P<project__slug>[a-z-_]+)/$" % self._meta.resource_name, self.wrap_view('dispatch_list'), name="build_list_detail"),
        ]

class VersionResource(EnhancedModelResource):
    project = fields.ForeignKey(ProjectResource, 'project', full=True)

    class Meta:
        queryset = Version.objects.all()
        allowed_methods = ['get', 'put', 'post']
        always_return_data = True
        queryset = Version.objects.all()
        authentication = PostAuthentication()
        authorization = Authorization()
        filtering = {
            "project": ALL_WITH_RELATIONS,
            "slug": ALL_WITH_RELATIONS,
            "active": ALL,
        }

    #Find a better name for this before including it.
    #def dehydrate(self, bundle):
        #bundle.data['subdomain'] = "http://%s/en/%s/" % (bundle.obj.project.subdomain, bundle.obj.slug)
        #return bundle

    def version_compare(self, request, **kwargs):
        project = get_object_or_404(Project, slug=kwargs['project_slug'])
        highest = highest_version(project.versions.filter(active=True))
        base = kwargs.get('base', None)
        ret_val = {
            'project': highest[0],
            'version': highest[1],
            'is_highest': True,
        }
        if highest[0]:
            ret_val['url'] = highest[0].get_absolute_url()
            ret_val['slug'] =  highest[0].slug,
        if base and base != 'latest':
            try:
                ver_obj = project.versions.get(slug=base)
                base_ver = mkversion(ver_obj)
                if base_ver:
                    #This is only place where is_highest can get set.
                    #All error cases will be set to True, for non-
                    #standard versions.
                    ret_val['is_highest'] = base_ver >= highest[1]
                else:
                    ret_val['is_highest'] = True
            except (Version.DoesNotExist, TypeError) as e:
                ret_val['is_highest'] = True
        return self.create_response(request, ret_val)

    def build_version(self, request, **kwargs):
        project = get_object_or_404(Project, slug=kwargs['project_slug'])
        version = kwargs.get('version_slug', 'latest')
        version_obj = project.versions.get(slug=version)
        tasks.update_docs.delay(pk=project.pk, version_pk=version_obj.pk)
        return self.create_response(request, {'building': True})

    def override_urls(self):
        return [
            url(r"^(?P<resource_name>%s)/(?P<project_slug>[a-z-_]+)/highest/(?P<base>.+)/$" % self._meta.resource_name, self.wrap_view('version_compare'), name="version_compare"),
            url(r"^(?P<resource_name>%s)/(?P<project_slug>[a-z-_]+)/highest/$" % self._meta.resource_name, self.wrap_view('version_compare'), name="version_compare"),
            url(r"^(?P<resource_name>%s)/(?P<project__slug>[a-z-_]+[a-z0-9-_]+)/$" % self._meta.resource_name, self.wrap_view('dispatch_list'), name="api_version_list"),
            url(r"^(?P<resource_name>%s)/(?P<project_slug>[a-z-_]+)/(?P<version_slug>[a-z-_]+)/build$" % self._meta.resource_name, self.wrap_view('build_version'), name="api_version_build_slug"),
        ]

class FileResource(EnhancedModelResource, SearchMixin):
    project = fields.ForeignKey(ProjectResource, 'project', full=True)

    class Meta:
        allowed_methods = ['get', 'post']
        queryset = ImportedFile.objects.all()
        excludes = ['md5', 'slug']
        include_absolute_url = True
        authentication = PostAuthentication()
        authorization = Authorization()
        search_facets = ['project']

    def override_urls(self):
        return [
            url(r"^(?P<resource_name>%s)/search%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('get_search'), name="api_get_search"),
            url(r"^(?P<resource_name>%s)/anchor%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('get_anchor'), name="api_get_anchor"),
        ]

    def get_anchor(self, request, **kwargs):
        self.method_check(request, allowed=['get'])
        self.is_authenticated(request)
        self.throttle_check(request)

        query = request.GET.get('q', '')
        redis_data = djangome.r.keys("*redirects:v3*%s*" % query)
        #-2 because http:
        urls = [''.join(data.split(':')[6:]) for data in redis_data if 'http://' in data]

        """
        paginator = Paginator(urls, 20)

        try:
            page = paginator.page(int(request.GET.get('page', 1)))
        except InvalidPage:
            raise Http404("Sorry, no results on that page.")

        objects = [result for result in page.object_list]
        object_list = { 'objects': objects, }
        """
        object_list = { 'objects': urls }

        self.log_throttled_access(request)
        return self.create_response(request, object_list)
<commit_msg>Allow<commit_after>import logging
import urllib

from django.core.paginator import Paginator, InvalidPage
from django.contrib.auth.models import User
from django.conf.urls.defaults import url
from django.shortcuts import get_object_or_404
from django.http import Http404
from django.core.urlresolvers import reverse

from haystack.query import SearchQuerySet
from haystack.utils import Highlighter
from tastypie import fields
from tastypie.authentication import BasicAuthentication
from tastypie.authorization import Authorization
from tastypie.constants import ALL_WITH_RELATIONS, ALL
from tastypie.resources import ModelResource
from tastypie.exceptions import NotFound, ImmediateHttpResponse
from tastypie import http
from tastypie.utils.mime import determine_format, build_content_type
from tastypie.http import HttpCreated
from tastypie.utils import dict_strip_unicode_keys, trailing_slash

from core.forms import FacetedSearchForm
from builds.models import Build, Version
from projects.models import Project, ImportedFile
from projects.utils import highest_version, mkversion
from projects import tasks
from djangome import views as djangome

log = logging.getLogger(__name__)

class SearchMixin(object):
    '''
    Adds a search api to any ModelResource provided the model is indexed.
    The search can be configured using the Meta class in each ModelResource.
    The search is limited to the model defined by the meta queryset. If the
    search is invalid, a 400 Bad Request will be raised.

    e.g.
        class Meta:
            # Return facet counts for each facetname
            search_facets = ['facetname1', 'facetname1']

            # Number of results returned per page
            search_page_size = 20

            # Highlight search terms in the text
            search_highlight = True
    '''
    def get_search(self, request, **kwargs):
        self.method_check(request, allowed=['get'])
        self.is_authenticated(request)
        self.throttle_check(request)
        object_list = self._search(request,
            self._meta.queryset.model,
            facets = getattr(self._meta, 'search_facets', []),
            page_size = getattr(self._meta, 'search_page_size', 20),
            highlight = getattr(self._meta, 'search_highlight', True),
        )
        self.log_throttled_access(request)
        return self.create_response(request, object_list)

    def _url_template(self, query, selected_facets):
        '''
        Construct a url template to assist with navigating the resources.
        This looks a bit nasty but urllib.urlencode resulted in even
        nastier output...
        '''
        query_params = []
        for facet in selected_facets:
            query_params.append(('selected_facets', facet))
        query_params += [('q', query), ('format', 'json'), ('page', '{0}')]
        query_string = '&'.join('='.join(p) for p in query_params)
        url_template = reverse('api_get_search', kwargs={
            'resource_name': self._meta.resource_name,
            'api_name': 'v1'
        })
        return url_template + '?' + query_string

    def _search(self, request, model, facets=None, page_size=20, highlight=True):
        '''
        `facets`
            A list of facets to include with the results
        `models`
            Limit the search to one or more models
        '''
        form = FacetedSearchForm(request.GET, facets=facets or [],
                                 models=(model,), load_all=True)
        if not form.is_valid():
            return self.error_response({'errors': form.errors }, request)
        results = form.search()

        paginator = Paginator(results, page_size)
        try:
            page = paginator.page(int(request.GET.get('page', 1)))
        except InvalidPage:
            raise Http404("Sorry, no results on that page.")

        objects = []
        query = request.GET.get('q', '')
        highlighter = Highlighter(query)
        for result in page.object_list:
            if not result:
                continue
            text = result.text
            if highlight:
                text = highlighter.highlight(text)
            bundle = self.build_bundle(obj=result.object, request=request)
            bundle = self.full_dehydrate(bundle)
            bundle.data['text'] = text
            objects.append(bundle)

        url_template = self._url_template(query, form['selected_facets'].value())
        page_data = {
            'number': page.number,
            'per_page': paginator.per_page,
            'num_pages': paginator.num_pages,
            'page_range': paginator.page_range,
            'object_count': paginator.count,
            'url_template': url_template,
        }
        if page.has_next():
            page_data['url_next'] = url_template.format(page.next_page_number())
        if page.has_previous():
            page_data['url_prev'] = url_template.format(page.previous_page_number())

        object_list = {
            'page': page_data,
            'objects': objects,
        }
        if facets:
            object_list.update({'facets': results.facet_counts()})
        return object_list

    # XXX: This method is available in the latest tastypie, remove
    # once available in production.
    def error_response(self, errors, request):
        if request:
            desired_format = self.determine_format(request)
        else:
            desired_format = self._meta.default_format
        serialized = self.serialize(request, errors, desired_format)
        response = http.HttpBadRequest(content=serialized, content_type=build_content_type(desired_format))
        raise ImmediateHttpResponse(response=response)

class PostAuthentication(BasicAuthentication):
    def is_authenticated(self, request, **kwargs):
        if request.method == "GET":
            return True
        return super(PostAuthentication, self).is_authenticated(request, **kwargs)

class EnhancedModelResource(ModelResource):
    def obj_get_list(self, request=None, **kwargs):
        """
        A ORM-specific implementation of ``obj_get_list``.

        Takes an optional ``request`` object, whose ``GET`` dictionary can be
        used to narrow the query.
        """
        filters = None

        if hasattr(request, 'GET'):
            filters = request.GET

        applicable_filters = self.build_filters(filters=filters)
        applicable_filters.update(kwargs)

        try:
            return self.get_object_list(request).filter(**applicable_filters)
        except ValueError, e:
            raise NotFound("Invalid resource lookup data provided (mismatched type).: %s" % e)

class UserResource(ModelResource):
    class Meta:
        allowed_methods = ['get']
        queryset = User.objects.all()
        fields = ['username', 'first_name', 'last_name', 'last_login', 'id']
        filtering = {
            'username': 'exact',
        }

    def override_urls(self):
        return [
            url(r"^(?P<resource_name>%s)/(?P<username>[a-z-_]+)/$" % self._meta.resource_name, self.wrap_view('dispatch_detail'), name="api_dispatch_detail"),
        ]

class ProjectResource(ModelResource, SearchMixin):
    users = fields.ToManyField(UserResource, 'users')

    class Meta:
        include_absolute_url = True
        allowed_methods = ['get', 'post', 'put']
        queryset = Project.objects.all()
        authentication = PostAuthentication()
        authorization = Authorization()
        excludes = ['path', 'skip', 'featured']
        filtering = {
            "users": ALL_WITH_RELATIONS,
            "slug": ALL_WITH_RELATIONS,
        }

    def dehydrate(self, bundle):
        bundle.data['subdomain'] = "http://%s/" % bundle.obj.subdomain
        return bundle

    def post_list(self, request, **kwargs):
        """
        Creates a new resource/object with the provided data.

        Calls ``obj_create`` with the provided data and returns a response
        with the new resource's location.

        If a new resource is created, return ``HttpCreated`` (201 Created).
        """
        deserialized = self.deserialize(request, request.raw_post_data, format=request.META.get('CONTENT_TYPE', 'application/json'))

        # Force this in an ugly way, at least should do "reverse"
        deserialized["users"] = ["/api/v1/user/%s/" % request.user.id,]
        bundle = self.build_bundle(data=dict_strip_unicode_keys(deserialized))
        self.is_valid(bundle, request)
        updated_bundle = self.obj_create(bundle, request=request)
        return HttpCreated(location=self.get_resource_uri(updated_bundle))

    def override_urls(self):
        return [
            url(r"^(?P<resource_name>%s)/search%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('get_search'), name="api_get_search"),
            url(r"^(?P<resource_name>%s)/(?P<slug>[a-z-_]+)/$" % self._meta.resource_name, self.wrap_view('dispatch_detail'), name="api_dispatch_detail"),
        ]

class BuildResource(EnhancedModelResource):
    project = fields.ForeignKey(ProjectResource, 'project')
    version = fields.ForeignKey('api.base.VersionResource', 'version')

    class Meta:
        include_absolute_url = True
        allowed_methods = ['get', 'post', 'put']
        queryset = Build.objects.all()
        authentication = PostAuthentication()
        authorization = Authorization()
        filtering = {
            "project": ALL_WITH_RELATIONS,
            "slug": ALL_WITH_RELATIONS,
            "type": ALL_WITH_RELATIONS,
            "state": ALL_WITH_RELATIONS,
        }

    def override_urls(self):
        return [
            url(r"^(?P<resource_name>%s)/(?P<project__slug>[a-z-_]+)/$" % self._meta.resource_name, self.wrap_view('dispatch_list'), name="build_list_detail"),
        ]

class VersionResource(EnhancedModelResource):
    project = fields.ForeignKey(ProjectResource, 'project', full=True)

    class Meta:
        queryset = Version.objects.all()
        allowed_methods = ['get', 'put', 'post']
        always_return_data = True
        queryset = Version.objects.all()
        authentication = PostAuthentication()
        authorization = Authorization()
        filtering = {
            "project": ALL_WITH_RELATIONS,
            "slug": ALL_WITH_RELATIONS,
            "active": ALL,
        }

    #Find a better name for this before including it.
    #def dehydrate(self, bundle):
        #bundle.data['subdomain'] = "http://%s/en/%s/" % (bundle.obj.project.subdomain, bundle.obj.slug)
        #return bundle

    def version_compare(self, request, **kwargs):
        project = get_object_or_404(Project, slug=kwargs['project_slug'])
        highest = highest_version(project.versions.filter(active=True))
        base = kwargs.get('base', None)
        ret_val = {
            'project': highest[0],
            'version': highest[1],
            'is_highest': True,
        }
        if highest[0]:
            ret_val['url'] = highest[0].get_absolute_url()
            ret_val['slug'] =  highest[0].slug,
        if base and base != 'latest':
            try:
                ver_obj = project.versions.get(slug=base)
                base_ver = mkversion(ver_obj)
                if base_ver:
                    #This is only place where is_highest can get set.
                    #All error cases will be set to True, for non-
                    #standard versions.
                    ret_val['is_highest'] = base_ver >= highest[1]
                else:
                    ret_val['is_highest'] = True
            except (Version.DoesNotExist, TypeError) as e:
                ret_val['is_highest'] = True
        return self.create_response(request, ret_val)

    def build_version(self, request, **kwargs):
        project = get_object_or_404(Project, slug=kwargs['project_slug'])
        version = kwargs.get('version_slug', 'latest')
        version_obj = project.versions.get(slug=version)
        tasks.update_docs.delay(pk=project.pk, version_pk=version_obj.pk)
        return self.create_response(request, {'building': True})

    def override_urls(self):
        return [
            url(r"^(?P<resource_name>%s)/(?P<project_slug>[a-z-_]+)/highest/(?P<base>.+)/$" % self._meta.resource_name, self.wrap_view('version_compare'), name="version_compare"),
            url(r"^(?P<resource_name>%s)/(?P<project_slug>[a-z-_]+)/highest/$" % self._meta.resource_name, self.wrap_view('version_compare'), name="version_compare"),
            url(r"^(?P<resource_name>%s)/(?P<project__slug>[a-z-_]+[a-z0-9-_]+)/$" % self._meta.resource_name, self.wrap_view('dispatch_list'), name="api_version_list"),
            url(r"^(?P<resource_name>%s)/(?P<project_slug>[a-z-_]+)/(?P<version_slug>[a-z0-9-_]+)/build/$" % self._meta.resource_name, self.wrap_view('build_version'), name="api_version_build_slug"),
        ]

class FileResource(EnhancedModelResource, SearchMixin):
    project = fields.ForeignKey(ProjectResource, 'project', full=True)

    class Meta:
        allowed_methods = ['get', 'post']
        queryset = ImportedFile.objects.all()
        excludes = ['md5', 'slug']
        include_absolute_url = True
        authentication = PostAuthentication()
        authorization = Authorization()
        search_facets = ['project']

    def override_urls(self):
        return [
            url(r"^(?P<resource_name>%s)/search%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('get_search'), name="api_get_search"),
            url(r"^(?P<resource_name>%s)/anchor%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('get_anchor'), name="api_get_anchor"),
        ]

    def get_anchor(self, request, **kwargs):
        self.method_check(request, allowed=['get'])
        self.is_authenticated(request)
        self.throttle_check(request)

        query = request.GET.get('q', '')
        redis_data = djangome.r.keys("*redirects:v3*%s*" % query)
        #-2 because http:
        urls = [''.join(data.split(':')[6:]) for data in redis_data if 'http://' in data]

        """
        paginator = Paginator(urls, 20)

        try:
            page = paginator.page(int(request.GET.get('page', 1)))
        except InvalidPage:
            raise Http404("Sorry, no results on that page.")

        objects = [result for result in page.object_list]
        object_list = { 'objects': objects, }
        """
        object_list = { 'objects': urls }

        self.log_throttled_access(request)
        return self.create_response(request, object_list)
<|endoftext|>


<commit_before>import logging

from django.core.paginator import Paginator, InvalidPage
from django.contrib.auth.models import User
from django.conf.urls.defaults import url
from django.shortcuts import get_object_or_404
from django.http import Http404

from haystack.query import SearchQuerySet
from haystack.utils import Highlighter
from tastypie import fields
from tastypie.authentication import BasicAuthentication
from tastypie.authorization import Authorization
from tastypie.constants import ALL_WITH_RELATIONS, ALL
from tastypie.resources import ModelResource
from tastypie.exceptions import NotFound
from tastypie.http import HttpCreated
from tastypie.utils import dict_strip_unicode_keys, trailing_slash

from builds.models import Build, Version
from projects.models import Project, ImportedFile
from projects.utils import highest_version, mkversion
from projects import tasks
from djangome import views as djangome

log = logging.getLogger(__name__)

def _do_search(self, request, model):

    self.method_check(request, allowed=['get'])
    self.is_authenticated(request)
    self.throttle_check(request)

    # Do the query.
    query = request.GET.get('q', '')
    sqs = SearchQuerySet().models(model).load_all().auto_query(query)
    paginator = Paginator(sqs, 20)

    try:
        page = paginator.page(int(request.GET.get('page', 1)))
    except InvalidPage:
        raise Http404("Sorry, no results on that page.")

    objects = []

    for result in page.object_list:
        if result:
            highlighter = Highlighter(query)
            text = highlighter.highlight(result.text)
            bundle = self.build_bundle(obj=result.object, request=request)
            bundle = self.full_dehydrate(bundle)
            bundle.data['text'] = text
            objects.append(bundle)

    object_list = {
        'objects': objects,
    }

    self.log_throttled_access(request)
    return self.create_response(request, object_list)

class PostAuthentication(BasicAuthentication):
    def is_authenticated(self, request, **kwargs):
        if request.method == "GET":
            return True
        return super(PostAuthentication, self).is_authenticated(request, **kwargs)

class EnhancedModelResource(ModelResource):
    def obj_get_list(self, request=None, **kwargs):
        """
        A ORM-specific implementation of ``obj_get_list``.

        Takes an optional ``request`` object, whose ``GET`` dictionary can be
        used to narrow the query.
        """
        filters = None

        if hasattr(request, 'GET'):
            filters = request.GET

        applicable_filters = self.build_filters(filters=filters)
        applicable_filters.update(kwargs)

        try:
            return self.get_object_list(request).filter(**applicable_filters)
        except ValueError, e:
            raise NotFound("Invalid resource lookup data provided (mismatched type).: %s" % e)

class UserResource(ModelResource):
    class Meta:
        allowed_methods = ['get']
        queryset = User.objects.all()
        fields = ['username', 'first_name', 'last_name', 'last_login', 'id']
        filtering = {
            'username': 'exact',
        }

    def override_urls(self):
        return [
            url(r"^(?P<resource_name>%s)/(?P<username>[a-z-]+)/$" % self._meta.resource_name, self.wrap_view('dispatch_detail'), name="api_dispatch_detail"),
        ]

class ProjectResource(ModelResource):
    users = fields.ToManyField(UserResource, 'users')

    class Meta:
        include_absolute_url = True
        allowed_methods = ['get', 'post', 'put']
        queryset = Project.objects.all()
        authentication = PostAuthentication()
        authorization = Authorization()
        excludes = ['use_virtualenv', 'path', 'skip', 'featured']
        filtering = {
            "users": ALL_WITH_RELATIONS,
            "slug": ALL_WITH_RELATIONS,
        }

    def post_list(self, request, **kwargs):
        """
        Creates a new resource/object with the provided data.

        Calls ``obj_create`` with the provided data and returns a response
        with the new resource's location.

        If a new resource is created, return ``HttpCreated`` (201 Created).
        """
        deserialized = self.deserialize(request, request.raw_post_data, format=request.META.get('CONTENT_TYPE', 'application/json'))

        # Force this in an ugly way, at least should do "reverse"
        deserialized["users"] = ["/api/v1/user/%s/" % request.user.id,]
        bundle = self.build_bundle(data=dict_strip_unicode_keys(deserialized))
        self.is_valid(bundle, request)
        updated_bundle = self.obj_create(bundle, request=request)
        return HttpCreated(location=self.get_resource_uri(updated_bundle))

    def get_search(self, request, **kwargs):
        return _do_search(self, request, Project)

    def override_urls(self):
        return [
            url(r"^(?P<resource_name>%s)/search%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('get_search'), name="api_get_search"),
            url(r"^(?P<resource_name>%s)/(?P<slug>[a-z-]+)/$" % self._meta.resource_name, self.wrap_view('dispatch_detail'), name="api_dispatch_detail"),

        ]

class BuildResource(EnhancedModelResource):
    project = fields.ForeignKey(ProjectResource, 'project')

    class Meta:
        allowed_methods = ['get', 'post']
        queryset = Build.objects.all()
        filtering = {
            "project": ALL_WITH_RELATIONS,
            "slug": ALL_WITH_RELATIONS,
        }

    def override_urls(self):
        return [
            url(r"^(?P<resource_name>%s)/(?P<project__slug>[a-z-]+)/$" % self._meta.resource_name, self.wrap_view('dispatch_list'), name="build_list_detail"),
        ]

class VersionResource(EnhancedModelResource):
    project = fields.ForeignKey(ProjectResource, 'project')

    class Meta:
        queryset = Version.objects.all()
        filtering = {
            "project": ALL_WITH_RELATIONS,
            "slug": ALL_WITH_RELATIONS,
            "active": ALL,
        }

    def version_compare(self, request, **kwargs):
        project = get_object_or_404(Project, slug=kwargs['project_slug'])
        highest = highest_version(project.versions.filter(active=True))
        base = kwargs.get('base', None)
        ret_val = {
            'project': highest[0],
            'version': highest[1],
            'is_highest': True,
        }
        if highest[0]:
            ret_val['url'] = highest[0].get_absolute_url()
            ret_val['slug'] =  highest[0].slug,
        if base and base != 'latest':
            try:
                ver_obj = project.versions.get(slug=base)
                base_ver = mkversion(ver_obj)
                if base_ver:
                    #This is only place where is_highest can get set.
                    #All error cases will be set to True, for non-
                    #standard versions.
                    ret_val['is_highest'] = base_ver >= highest[1]
                else:
                    ret_val['is_highest'] = True
            except (Version.DoesNotExist, TypeError) as e:
                ret_val['is_highest'] = True
        return self.create_response(request, ret_val)

    def build_version(self, request, **kwargs):
        project = get_object_or_404(Project, slug=kwargs['project_slug'])
        version = kwargs.get('version_slug', 'latest')
        version_obj = project.versions.get(slug=version)
        tasks.update_docs.delay(pk=project.pk, version_pk=version_obj.pk)
        return self.create_response(request, {'building': True})

    def override_urls(self):
        return [
            url(r"^(?P<resource_name>%s)/(?P<project_slug>[a-z-]+)/highest/(?P<base>.+)/$" % self._meta.resource_name, self.wrap_view('version_compare'), name="version_compare"),
            url(r"^(?P<resource_name>%s)/(?P<project_slug>[a-z-]+)/highest/$" % self._meta.resource_name, self.wrap_view('version_compare'), name="version_compare"),
            url(r"^(?P<resource_name>%s)/(?P<project__slug>[a-z-]+)/$" % self._meta.resource_name, self.wrap_view('dispatch_list'), name="api_version_list"),
            url(r"^(?P<resource_name>%s)/(?P<project_slug>[a-z-]+)/(?P<version_slug>[a-z-]+)/build$" % self._meta.resource_name, self.wrap_view('build_version'), name="api_version_build_slug"),
        ]

class FileResource(EnhancedModelResource):
    project = fields.ForeignKey(ProjectResource, 'project', full=True)

    class Meta:
        allowed_methods = ['get']
        queryset = ImportedFile.objects.all()
        excludes = ['md5', 'slug']
        include_absolute_url = True

    def override_urls(self):
        return [
            url(r"^(?P<resource_name>%s)/search%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('get_search'), name="api_get_search"),
            url(r"^(?P<resource_name>%s)/anchor%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('get_anchor'), name="api_get_anchor"),
        ]

    def get_search(self, request, **kwargs):
        return _do_search(self, request, ImportedFile)

    def get_anchor(self, request, **kwargs):
        self.method_check(request, allowed=['get'])
        self.is_authenticated(request)
        self.throttle_check(request)

        query = request.GET.get('q', '')
        redis_data = djangome.r.keys("*redirects:v3*%s*" % query)
        #-2 because http:
        urls = [''.join(data.split(':')[6:]) for data in redis_data if 'http://' in data]

        """
        paginator = Paginator(urls, 20)

        try:
            page = paginator.page(int(request.GET.get('page', 1)))
        except InvalidPage:
            raise Http404("Sorry, no results on that page.")

        objects = [result for result in page.object_list]
        object_list = { 'objects': objects, }
        """
        object_list = { 'objects': urls }

        self.log_throttled_access(request)
        return self.create_response(request, object_list)
<commit_msg>Return the full project in version queries.<commit_after>import logging

from django.core.paginator import Paginator, InvalidPage
from django.contrib.auth.models import User
from django.conf.urls.defaults import url
from django.shortcuts import get_object_or_404
from django.http import Http404

from haystack.query import SearchQuerySet
from haystack.utils import Highlighter
from tastypie import fields
from tastypie.authentication import BasicAuthentication
from tastypie.authorization import Authorization
from tastypie.constants import ALL_WITH_RELATIONS, ALL
from tastypie.resources import ModelResource
from tastypie.exceptions import NotFound
from tastypie.http import HttpCreated
from tastypie.utils import dict_strip_unicode_keys, trailing_slash

from builds.models import Build, Version
from projects.models import Project, ImportedFile
from projects.utils import highest_version, mkversion
from projects import tasks
from djangome import views as djangome

log = logging.getLogger(__name__)

def _do_search(self, request, model):

    self.method_check(request, allowed=['get'])
    self.is_authenticated(request)
    self.throttle_check(request)

    # Do the query.
    query = request.GET.get('q', '')
    sqs = SearchQuerySet().models(model).load_all().auto_query(query)
    paginator = Paginator(sqs, 20)

    try:
        page = paginator.page(int(request.GET.get('page', 1)))
    except InvalidPage:
        raise Http404("Sorry, no results on that page.")

    objects = []

    for result in page.object_list:
        if result:
            highlighter = Highlighter(query)
            text = highlighter.highlight(result.text)
            bundle = self.build_bundle(obj=result.object, request=request)
            bundle = self.full_dehydrate(bundle)
            bundle.data['text'] = text
            objects.append(bundle)

    object_list = {
        'objects': objects,
    }

    self.log_throttled_access(request)
    return self.create_response(request, object_list)

class PostAuthentication(BasicAuthentication):
    def is_authenticated(self, request, **kwargs):
        if request.method == "GET":
            return True
        return super(PostAuthentication, self).is_authenticated(request, **kwargs)

class EnhancedModelResource(ModelResource):
    def obj_get_list(self, request=None, **kwargs):
        """
        A ORM-specific implementation of ``obj_get_list``.

        Takes an optional ``request`` object, whose ``GET`` dictionary can be
        used to narrow the query.
        """
        filters = None

        if hasattr(request, 'GET'):
            filters = request.GET

        applicable_filters = self.build_filters(filters=filters)
        applicable_filters.update(kwargs)

        try:
            return self.get_object_list(request).filter(**applicable_filters)
        except ValueError, e:
            raise NotFound("Invalid resource lookup data provided (mismatched type).: %s" % e)

class UserResource(ModelResource):
    class Meta:
        allowed_methods = ['get']
        queryset = User.objects.all()
        fields = ['username', 'first_name', 'last_name', 'last_login', 'id']
        filtering = {
            'username': 'exact',
        }

    def override_urls(self):
        return [
            url(r"^(?P<resource_name>%s)/(?P<username>[a-z-]+)/$" % self._meta.resource_name, self.wrap_view('dispatch_detail'), name="api_dispatch_detail"),
        ]

class ProjectResource(ModelResource):
    users = fields.ToManyField(UserResource, 'users')

    class Meta:
        include_absolute_url = True
        allowed_methods = ['get', 'post', 'put']
        queryset = Project.objects.all()
        authentication = PostAuthentication()
        authorization = Authorization()
        excludes = ['use_virtualenv', 'path', 'skip', 'featured']
        filtering = {
            "users": ALL_WITH_RELATIONS,
            "slug": ALL_WITH_RELATIONS,
        }

    def post_list(self, request, **kwargs):
        """
        Creates a new resource/object with the provided data.

        Calls ``obj_create`` with the provided data and returns a response
        with the new resource's location.

        If a new resource is created, return ``HttpCreated`` (201 Created).
        """
        deserialized = self.deserialize(request, request.raw_post_data, format=request.META.get('CONTENT_TYPE', 'application/json'))

        # Force this in an ugly way, at least should do "reverse"
        deserialized["users"] = ["/api/v1/user/%s/" % request.user.id,]
        bundle = self.build_bundle(data=dict_strip_unicode_keys(deserialized))
        self.is_valid(bundle, request)
        updated_bundle = self.obj_create(bundle, request=request)
        return HttpCreated(location=self.get_resource_uri(updated_bundle))

    def get_search(self, request, **kwargs):
        return _do_search(self, request, Project)

    def override_urls(self):
        return [
            url(r"^(?P<resource_name>%s)/search%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('get_search'), name="api_get_search"),
            url(r"^(?P<resource_name>%s)/(?P<slug>[a-z-]+)/$" % self._meta.resource_name, self.wrap_view('dispatch_detail'), name="api_dispatch_detail"),

        ]

class BuildResource(EnhancedModelResource):
    project = fields.ForeignKey(ProjectResource, 'project')

    class Meta:
        allowed_methods = ['get', 'post']
        queryset = Build.objects.all()
        filtering = {
            "project": ALL_WITH_RELATIONS,
            "slug": ALL_WITH_RELATIONS,
        }

    def override_urls(self):
        return [
            url(r"^(?P<resource_name>%s)/(?P<project__slug>[a-z-]+)/$" % self._meta.resource_name, self.wrap_view('dispatch_list'), name="build_list_detail"),
        ]

class VersionResource(EnhancedModelResource):
    project = fields.ForeignKey(ProjectResource, 'project', full_dehydrate=True)

    class Meta:
        queryset = Version.objects.all()
        filtering = {
            "project": ALL_WITH_RELATIONS,
            "slug": ALL_WITH_RELATIONS,
            "active": ALL,
        }

    def version_compare(self, request, **kwargs):
        project = get_object_or_404(Project, slug=kwargs['project_slug'])
        highest = highest_version(project.versions.filter(active=True))
        base = kwargs.get('base', None)
        ret_val = {
            'project': highest[0],
            'version': highest[1],
            'is_highest': True,
        }
        if highest[0]:
            ret_val['url'] = highest[0].get_absolute_url()
            ret_val['slug'] =  highest[0].slug,
        if base and base != 'latest':
            try:
                ver_obj = project.versions.get(slug=base)
                base_ver = mkversion(ver_obj)
                if base_ver:
                    #This is only place where is_highest can get set.
                    #All error cases will be set to True, for non-
                    #standard versions.
                    ret_val['is_highest'] = base_ver >= highest[1]
                else:
                    ret_val['is_highest'] = True
            except (Version.DoesNotExist, TypeError) as e:
                ret_val['is_highest'] = True
        return self.create_response(request, ret_val)

    def build_version(self, request, **kwargs):
        project = get_object_or_404(Project, slug=kwargs['project_slug'])
        version = kwargs.get('version_slug', 'latest')
        version_obj = project.versions.get(slug=version)
        tasks.update_docs.delay(pk=project.pk, version_pk=version_obj.pk)
        return self.create_response(request, {'building': True})

    def override_urls(self):
        return [
            url(r"^(?P<resource_name>%s)/(?P<project_slug>[a-z-]+)/highest/(?P<base>.+)/$" % self._meta.resource_name, self.wrap_view('version_compare'), name="version_compare"),
            url(r"^(?P<resource_name>%s)/(?P<project_slug>[a-z-]+)/highest/$" % self._meta.resource_name, self.wrap_view('version_compare'), name="version_compare"),
            url(r"^(?P<resource_name>%s)/(?P<project__slug>[a-z-]+)/$" % self._meta.resource_name, self.wrap_view('dispatch_list'), name="api_version_list"),
            url(r"^(?P<resource_name>%s)/(?P<project_slug>[a-z-]+)/(?P<version_slug>[a-z-]+)/build$" % self._meta.resource_name, self.wrap_view('build_version'), name="api_version_build_slug"),
        ]

class FileResource(EnhancedModelResource):
    project = fields.ForeignKey(ProjectResource, 'project', full=True)

    class Meta:
        allowed_methods = ['get']
        queryset = ImportedFile.objects.all()
        excludes = ['md5', 'slug']
        include_absolute_url = True

    def override_urls(self):
        return [
            url(r"^(?P<resource_name>%s)/search%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('get_search'), name="api_get_search"),
            url(r"^(?P<resource_name>%s)/anchor%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('get_anchor'), name="api_get_anchor"),
        ]

    def get_search(self, request, **kwargs):
        return _do_search(self, request, ImportedFile)

    def get_anchor(self, request, **kwargs):
        self.method_check(request, allowed=['get'])
        self.is_authenticated(request)
        self.throttle_check(request)

        query = request.GET.get('q', '')
        redis_data = djangome.r.keys("*redirects:v3*%s*" % query)
        #-2 because http:
        urls = [''.join(data.split(':')[6:]) for data in redis_data if 'http://' in data]

        """
        paginator = Paginator(urls, 20)

        try:
            page = paginator.page(int(request.GET.get('page', 1)))
        except InvalidPage:
            raise Http404("Sorry, no results on that page.")

        objects = [result for result in page.object_list]
        object_list = { 'objects': objects, }
        """
        object_list = { 'objects': urls }

        self.log_throttled_access(request)
        return self.create_response(request, object_list)
<|endoftext|>


<commit_before>import django_filters.rest_framework
from rest_framework.authentication import SessionAuthentication, TokenAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.renderers import JSONRenderer
from rest_framework.throttling import UserRateThrottle, AnonRateThrottle
from rest_flex_fields import FlexFieldsModelViewSet

from readthedocs.projects.models import Project
from readthedocs.restapi.permissions import IsOwner

from .serializers import ProjectSerializer

class APIv3Settings:

    authentication_classes = (SessionAuthentication, TokenAuthentication)
    permission_classes = (IsAuthenticated, IsOwner)
    renderer_classes = (JSONRenderer,)
    throttle_classes = (UserRateThrottle, AnonRateThrottle)
    filter_backends = (django_filters.rest_framework.DjangoFilterBackend,)

class ProjectsViewSet(APIv3Settings, FlexFieldsModelViewSet):

    model = Project
    lookup_field = 'slug'
    lookup_url_kwarg = 'project_slug'
    serializer_class = ProjectSerializer
    filterset_fields = (
        'slug',
        'privacy_level',
    )
    permit_list_expands = [
        'users',
        'active_versions',
        'active_versions.last_build',
        'active_versions.last_build.config',
    ]

    def get_queryset(self):
        user = self.request.user
        return user.projects.all()
<commit_msg>Use a class filter to allow expansion<commit_after>import django_filters.rest_framework as filters
from rest_framework.authentication import SessionAuthentication, TokenAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.renderers import JSONRenderer
from rest_framework.throttling import UserRateThrottle, AnonRateThrottle
from rest_flex_fields import FlexFieldsModelViewSet

from readthedocs.projects.models import Project
from readthedocs.restapi.permissions import IsOwner

from .filters import ProjectFilter
from .serializers import ProjectSerializer

class APIv3Settings:

    authentication_classes = (SessionAuthentication, TokenAuthentication)
    permission_classes = (IsAuthenticated, IsOwner)
    renderer_classes = (JSONRenderer,)
    throttle_classes = (UserRateThrottle, AnonRateThrottle)
    filter_backends = (filters.DjangoFilterBackend,)

class ProjectsViewSet(APIv3Settings, FlexFieldsModelViewSet):

    model = Project
    lookup_field = 'slug'
    lookup_url_kwarg = 'project_slug'
    serializer_class = ProjectSerializer
    filterset_class = ProjectFilter
    permit_list_expands = [
        'users',
        'active_versions',
        'active_versions.last_build',
        'active_versions.last_build.config',
    ]

    def get_queryset(self):
        user = self.request.user
        return user.projects.all()
<|endoftext|>


<commit_before>"""
Test DataTable interface.
"""
import os, unittest
import opensim as osim

class TestDataTable(unittest.TestCase):
    def test_DataTable(self):
        table = osim.DataTable()
        # Set column labels.
        table.setColumnLabels(['0', '1', '2', '3'])
        assert table.getColumnLabels() == ('0', '1', '2', '3')
        assert table.hasColumn('0')
        assert table.hasColumn('2')
        assert not table.hasColumn('not-found')
        table.setColumnLabel(0, 'zero')
        table.setColumnLabel(2, 'two')
        assert table.getColumnLabel(0) == 'zero'
        assert table.getColumnLabel(2) == 'two'
        assert table.getColumnIndex('zero') == 0
        assert table.getColumnIndex('two')  == 2
        # Append a row to the table.
        row = osim.RowVector([1, 2, 3, 4])
        table.appendRow(0.1, row)
        assert table.getNumRows() == 1
        assert table.getNumColumns() == 4
        row0 = table.getRowAtIndex(0)
        assert (row0[0] == row[0] and
                row0[1] == row[1] and
                row0[2] == row[2] and
                row0[3] == row[3])
        # Append another row to the table.
        row[0] *= 2
        row[1] *= 2
        row[2] *= 2
        row[3] *= 2
        table.appendRow(0.2, row)
        assert table.getNumRows() == 2
        assert table.getNumColumns() == 4
        row1 = table.getRow(0.2)
        assert (row1[0] == row[0] and
                row1[1] == row[1] and
                row1[2] == row[2] and
                row1[3] == row[3])
        # Append another row to the table.
        row[0] *= 2
        row[1] *= 2
        row[2] *= 2
        row[3] *= 2
        table.appendRow(0.3, row)
        assert table.getNumRows() == 3
        assert table.getNumColumns() == 4
        row2 = table.getRow(0.3)
        assert (row2[0] == row[0] and
                row2[1] == row[1] and
                row2[2] == row[2] and
                row2[3] == row[3])
        # Retrieve independent column.
        assert table.getIndependentColumn() == (0.1, 0.2, 0.3)
        # Retrieve dependent columns.
        col1 = table.getDependentColumnAtIndex(1)
        assert (col1[0] == 2 and
                col1[1] == 4 and
                col1[2] == 8)
        col3 = table.getDependentColumn('3')
        assert (col3[0] == 4 and
                col3[1] == 8 and
                col3[2] == 16)
        assert table.hasColumn(0)
        assert table.hasColumn(2)
        # Edit rows of the table.
        row0 = table.getRowAtIndex(0)
        row0[0] = 10
        row0[1] = 10
        row0[2] = 10
        row0[3] = 10
        row0 = table.getRowAtIndex(0)
        assert (row0[0] == 10 and
                row0[1] == 10 and
                row0[2] == 10 and
                row0[3] == 10)
        row2 = table.getRow(0.3)
        row2[0] = 20
        row2[1] = 20
        row2[2] = 20
        row2[3] = 20
        row2 = table.getRow(0.3)
        assert (row2[0] == 20 and
                row2[1] == 20 and
                row2[2] == 20 and
                row2[3] == 20)
        # Edit columns of the table.
        col1 = table.getDependentColumnAtIndex(1)
        col1[0] = 30
        col1[1] = 30
        col1[2] = 30
        col1 = table.getDependentColumnAtIndex(1)
        assert (col1[0] == 30 and
                col1[1] == 30 and
                col1[2] == 30)
        col3 = table.getDependentColumn('3')
        col3[0] = 40
        col3[1] = 40
        col3[2] = 40
        col3 = table.getDependentColumn('3')
        assert (col3[0] == 40 and
                col3[1] == 40 and
                col3[2] == 40)
        # Access eleemnt with index out of bounds. Exception expected
        try:
            shouldThrow = row0[5]
        except RuntimeError:
            pass

    def test_TimeSeriesTable(self):
        table = osim.TimeSeriesTable()
        table.setColumnLabels(('col1', 'col2', 'col3', 'col4'))
        assert(table.getColumnLabels() == ('col1', 'col2', 'col3', 'col4'))
        # Append a row to the table.
        row = osim.RowVector([1, 2, 3, 4])
        table.appendRow(0.1, row)
        assert table.getNumRows() == 1
        assert table.getNumColumns() == 4
        row0 = table.getRowAtIndex(0)
        assert (row0[0] == row[0] and
                row0[1] == row[1] and
                row0[2] == row[2] and
                row0[3] == row[3])
        # Append another row to the table.
        row[0] *= 2
        row[1] *= 2
        row[2] *= 2
        row[3] *= 2
        table.appendRow(0.2, row)
        assert table.getNumRows() == 2
        assert table.getNumColumns() == 4
        row1 = table.getRow(0.2)
        assert (row1[0] == row[0] and
                row1[1] == row[1] and
                row1[2] == row[2] and
                row1[3] == row[3])
        # Append another row to the table with a timestamp
        # less than the previous one. Exception expected.
        try:
            table.appendRow(0.15, row)
            assert False
        except RuntimeError:
            pass

    def test_DataTableVec3(self):
        table = osim.DataTableVec3()
        # Set columns labels.
        table.setColumnLabels(['0', '1', '2'])
        assert table.getColumnLabels() == ('0', '1', '2')
        # Append a row to the table.
        row = osim.RowVectorOfVec3([osim.Vec3(1, 2, 3),
                                    osim.Vec3(4, 5, 6),
                                    osim.Vec3(7, 8, 9)])
        table.appendRow(0.1, row)
        assert table.getNumRows() == 1
        assert table.getNumColumns() == 3
        row0 = table.getRowAtIndex(0)
        assert (str(row0[0]) == str(row[0]) and
                str(row0[1]) == str(row[1]) and
                str(row0[2]) == str(row[2]))
        # Append another row to the table.
        row = osim.RowVectorOfVec3([osim.Vec3( 2,  4,  6),
                                    osim.Vec3( 8, 10, 12),
                                    osim.Vec3(14, 16, 18)])
        table.appendRow(0.2, row)
        assert table.getNumRows() == 2
        assert table.getNumColumns() == 3
        row1 = table.getRow(0.2)
        assert (str(row1[0]) == str(row[0]) and
                str(row1[1]) == str(row[1]) and
                str(row1[2]) == str(row[2]))
        # Append another row to the table.
        row = osim.RowVectorOfVec3([osim.Vec3( 4,  8, 12),
                                    osim.Vec3(16, 20, 24),
                                    osim.Vec3(28, 32, 36)])
        table.appendRow(0.3, row)
        assert table.getNumRows() == 3
        assert table.getNumColumns() == 3
        row2 = table.getRow(0.3)
        assert (str(row2[0]) == str(row[0]) and
                str(row2[1]) == str(row[1]) and
                str(row2[2]) == str(row[2]))
        # Retrieve independent column.
        assert table.getIndependentColumn() == (0.1, 0.2, 0.3)
        # Retrieve dependent columns.
        col1 = table.getDependentColumnAtIndex(1)
        assert (str(col1[0]) == str(osim.Vec3( 4,  5,  6)) and
                str(col1[1]) == str(osim.Vec3( 8, 10, 12)) and
                str(col1[2]) == str(osim.Vec3(16, 20, 24)))
        col2 = table.getDependentColumn('2')
        assert (str(col2[0]) == str(osim.Vec3( 7,  8,  9)) and
                str(col2[1]) == str(osim.Vec3(14, 16, 18)) and
                str(col2[2]) == str(osim.Vec3(28, 32, 36)))
        # Edit rows of the table.
        row0 = table.getRowAtIndex(0)
        row0[0] = osim.Vec3(10, 10, 10)
        row0[1] = osim.Vec3(10, 10, 10)
        row0[2] = osim.Vec3(10, 10, 10)
        row0 = table.getRowAtIndex(0)
        assert (str(row0[0]) == str(osim.Vec3(10, 10, 10)) and
                str(row0[1]) == str(osim.Vec3(10, 10, 10)) and
                str(row0[2]) == str(osim.Vec3(10, 10, 10)))
        row2 = table.getRow(0.3)
        row2[0] = osim.Vec3(20, 20, 20)
        row2[1] = osim.Vec3(20, 20, 20)
        row2[2] = osim.Vec3(20, 20, 20)
        row2 = table.getRow(0.3)
        assert (str(row2[0]) == str(osim.Vec3(20, 20, 20)) and
                str(row2[1]) == str(osim.Vec3(20, 20, 20)) and
                str(row2[2]) == str(osim.Vec3(20, 20, 20)))
        # Edit columns of the table.
        col1 = table.getDependentColumnAtIndex(1)
        col1[0] = osim.Vec3(30, 30, 30)
        col1[1] = osim.Vec3(30, 30, 30)
        col1[2] = osim.Vec3(30, 30, 30)
        col1 = table.getDependentColumnAtIndex(1)
        assert (str(col1[0]) == str(osim.Vec3(30, 30, 30)) and
                str(col1[1]) == str(osim.Vec3(30, 30, 30)) and
                str(col1[2]) == str(osim.Vec3(30, 30, 30)))
        col2 = table.getDependentColumn('2')
        col2[0] = osim.Vec3(40, 40, 40)
        col2[1] = osim.Vec3(40, 40, 40)
        col2[2] = osim.Vec3(40, 40, 40)
        col2 = table.getDependentColumn('2')
        assert (str(col2[0]) == str(osim.Vec3(40, 40, 40)) and
                str(col2[1]) == str(osim.Vec3(40, 40, 40)) and
                str(col2[2]) == str(osim.Vec3(40, 40, 40)))

    def test_TimeSeriesTableVec3(self):
        table = osim.TimeSeriesTableVec3()
        # Set columns labels.
        table.setColumnLabels(['0', '1', '2'])
        assert table.getColumnLabels() == ('0', '1', '2')
        # Append a row to the table.
        row = osim.RowVectorOfVec3([osim.Vec3(1, 2, 3),
                                    osim.Vec3(4, 5, 6),
                                    osim.Vec3(7, 8, 9)])
        table.appendRow(0.1, row)
        assert table.getNumRows() == 1
        assert table.getNumColumns() == 3
        row0 = table.getRowAtIndex(0)
        assert (str(row0[0]) == str(row[0]) and
                str(row0[1]) == str(row[1]) and
                str(row0[2]) == str(row[2]))
        # Append another row to the table.
        row = osim.RowVectorOfVec3([osim.Vec3( 2,  4,  6),
                                    osim.Vec3( 8, 10, 12),
                                    osim.Vec3(14, 16, 18)])
        table.appendRow(0.2, row)
        assert table.getNumRows() == 2
        assert table.getNumColumns() == 3
        row1 = table.getRow(0.2)
        assert (str(row1[0]) == str(row[0]) and
                str(row1[1]) == str(row[1]) and
                str(row1[2]) == str(row[2]))
        # Append another row to the table with a timestamp
        # less than the previous one. Exception expected.
        try:
            table.appendRow(0.15, row)
            assert False
        except RuntimeError:
            pass
<commit_msg>More python tests with exceptions.<commit_after>"""
Test DataTable interface.
"""
import os, unittest
import opensim as osim

class TestDataTable(unittest.TestCase):
    def test_DataTable(self):
        table = osim.DataTable()
        # Set column labels.
        table.setColumnLabels(['0', '1', '2', '3'])
        assert table.getColumnLabels() == ('0', '1', '2', '3')
        assert table.hasColumn('0')
        assert table.hasColumn('2')
        assert not table.hasColumn('not-found')
        table.setColumnLabel(0, 'zero')
        table.setColumnLabel(2, 'two')
        assert table.getColumnLabel(0) == 'zero'
        assert table.getColumnLabel(2) == 'two'
        assert table.getColumnIndex('zero') == 0
        assert table.getColumnIndex('two')  == 2
        # Append a row to the table.
        row = osim.RowVector([1, 2, 3, 4])
        table.appendRow(0.1, row)
        assert table.getNumRows() == 1
        assert table.getNumColumns() == 4
        row0 = table.getRowAtIndex(0)
        assert (row0[0] == row[0] and
                row0[1] == row[1] and
                row0[2] == row[2] and
                row0[3] == row[3])
        # Append another row to the table.
        row[0] *= 2
        row[1] *= 2
        row[2] *= 2
        row[3] *= 2
        table.appendRow(0.2, row)
        assert table.getNumRows() == 2
        assert table.getNumColumns() == 4
        row1 = table.getRow(0.2)
        assert (row1[0] == row[0] and
                row1[1] == row[1] and
                row1[2] == row[2] and
                row1[3] == row[3])
        # Append another row to the table.
        row[0] *= 2
        row[1] *= 2
        row[2] *= 2
        row[3] *= 2
        table.appendRow(0.3, row)
        assert table.getNumRows() == 3
        assert table.getNumColumns() == 4
        row2 = table.getRow(0.3)
        assert (row2[0] == row[0] and
                row2[1] == row[1] and
                row2[2] == row[2] and
                row2[3] == row[3])
        # Retrieve independent column.
        assert table.getIndependentColumn() == (0.1, 0.2, 0.3)
        # Retrieve dependent columns.
        col1 = table.getDependentColumnAtIndex(1)
        assert (col1[0] == 2 and
                col1[1] == 4 and
                col1[2] == 8)
        col3 = table.getDependentColumn('3')
        assert (col3[0] == 4 and
                col3[1] == 8 and
                col3[2] == 16)
        assert table.hasColumn(0)
        assert table.hasColumn(2)
        # Edit rows of the table.
        row0 = table.getRowAtIndex(0)
        row0[0] = 10
        row0[1] = 10
        row0[2] = 10
        row0[3] = 10
        row0 = table.getRowAtIndex(0)
        assert (row0[0] == 10 and
                row0[1] == 10 and
                row0[2] == 10 and
                row0[3] == 10)
        row2 = table.getRow(0.3)
        row2[0] = 20
        row2[1] = 20
        row2[2] = 20
        row2[3] = 20
        row2 = table.getRow(0.3)
        assert (row2[0] == 20 and
                row2[1] == 20 and
                row2[2] == 20 and
                row2[3] == 20)
        # Edit columns of the table.
        col1 = table.getDependentColumnAtIndex(1)
        col1[0] = 30
        col1[1] = 30
        col1[2] = 30
        col1 = table.getDependentColumnAtIndex(1)
        assert (col1[0] == 30 and
                col1[1] == 30 and
                col1[2] == 30)
        col3 = table.getDependentColumn('3')
        col3[0] = 40
        col3[1] = 40
        col3[2] = 40
        col3 = table.getDependentColumn('3')
        assert (col3[0] == 40 and
                col3[1] == 40 and
                col3[2] == 40)
        # Access eleemnt with index out of bounds. Exception expected.
        try:
            shouldThrow = row0[5]
            assert false
        except RuntimeError:
            pass
        try:
            shouldThrow = col1[5]
            assert false
        except RuntimeError:
            pass
        # Access row with index out of bounds. Exception expected.
        try:
            shouldThrow = table.getRowAtIndex(5)
            assert false
        except RuntimeError:
            pass
        # Access row with timestamp that does not exist. Exception expected.
        try:
            shouldThrow = table.getRow(5.5)
            assert false
        except RuntimeError:
            pass
        # Access column with index out of bounds. Exception expected.
        try:
            shouldThrow = table.getDependentColumnAtIndex(5)
            assert false
        except RuntimeError:
            pass
        # Access column with label that does not exist. Exception expected.
        try:
            shouldThrow = table.getDependentColumn('not-found')
            assert false
        except RuntimeError:
            pass

    def test_TimeSeriesTable(self):
        table = osim.TimeSeriesTable()
        table.setColumnLabels(('col1', 'col2', 'col3', 'col4'))
        assert(table.getColumnLabels() == ('col1', 'col2', 'col3', 'col4'))
        # Append a row to the table.
        row = osim.RowVector([1, 2, 3, 4])
        table.appendRow(0.1, row)
        assert table.getNumRows() == 1
        assert table.getNumColumns() == 4
        row0 = table.getRowAtIndex(0)
        assert (row0[0] == row[0] and
                row0[1] == row[1] and
                row0[2] == row[2] and
                row0[3] == row[3])
        # Append another row to the table.
        row[0] *= 2
        row[1] *= 2
        row[2] *= 2
        row[3] *= 2
        table.appendRow(0.2, row)
        assert table.getNumRows() == 2
        assert table.getNumColumns() == 4
        row1 = table.getRow(0.2)
        assert (row1[0] == row[0] and
                row1[1] == row[1] and
                row1[2] == row[2] and
                row1[3] == row[3])
        # Append another row to the table with a timestamp
        # less than the previous one. Exception expected.
        try:
            table.appendRow(0.15, row)
            assert False
        except RuntimeError:
            pass

    def test_DataTableVec3(self):
        table = osim.DataTableVec3()
        # Set columns labels.
        table.setColumnLabels(['0', '1', '2'])
        assert table.getColumnLabels() == ('0', '1', '2')
        # Append a row to the table.
        row = osim.RowVectorOfVec3([osim.Vec3(1, 2, 3),
                                    osim.Vec3(4, 5, 6),
                                    osim.Vec3(7, 8, 9)])
        table.appendRow(0.1, row)
        assert table.getNumRows() == 1
        assert table.getNumColumns() == 3
        row0 = table.getRowAtIndex(0)
        assert (str(row0[0]) == str(row[0]) and
                str(row0[1]) == str(row[1]) and
                str(row0[2]) == str(row[2]))
        # Append another row to the table.
        row = osim.RowVectorOfVec3([osim.Vec3( 2,  4,  6),
                                    osim.Vec3( 8, 10, 12),
                                    osim.Vec3(14, 16, 18)])
        table.appendRow(0.2, row)
        assert table.getNumRows() == 2
        assert table.getNumColumns() == 3
        row1 = table.getRow(0.2)
        assert (str(row1[0]) == str(row[0]) and
                str(row1[1]) == str(row[1]) and
                str(row1[2]) == str(row[2]))
        # Append another row to the table.
        row = osim.RowVectorOfVec3([osim.Vec3( 4,  8, 12),
                                    osim.Vec3(16, 20, 24),
                                    osim.Vec3(28, 32, 36)])
        table.appendRow(0.3, row)
        assert table.getNumRows() == 3
        assert table.getNumColumns() == 3
        row2 = table.getRow(0.3)
        assert (str(row2[0]) == str(row[0]) and
                str(row2[1]) == str(row[1]) and
                str(row2[2]) == str(row[2]))
        # Retrieve independent column.
        assert table.getIndependentColumn() == (0.1, 0.2, 0.3)
        # Retrieve dependent columns.
        col1 = table.getDependentColumnAtIndex(1)
        assert (str(col1[0]) == str(osim.Vec3( 4,  5,  6)) and
                str(col1[1]) == str(osim.Vec3( 8, 10, 12)) and
                str(col1[2]) == str(osim.Vec3(16, 20, 24)))
        col2 = table.getDependentColumn('2')
        assert (str(col2[0]) == str(osim.Vec3( 7,  8,  9)) and
                str(col2[1]) == str(osim.Vec3(14, 16, 18)) and
                str(col2[2]) == str(osim.Vec3(28, 32, 36)))
        # Edit rows of the table.
        row0 = table.getRowAtIndex(0)
        row0[0] = osim.Vec3(10, 10, 10)
        row0[1] = osim.Vec3(10, 10, 10)
        row0[2] = osim.Vec3(10, 10, 10)
        row0 = table.getRowAtIndex(0)
        assert (str(row0[0]) == str(osim.Vec3(10, 10, 10)) and
                str(row0[1]) == str(osim.Vec3(10, 10, 10)) and
                str(row0[2]) == str(osim.Vec3(10, 10, 10)))
        row2 = table.getRow(0.3)
        row2[0] = osim.Vec3(20, 20, 20)
        row2[1] = osim.Vec3(20, 20, 20)
        row2[2] = osim.Vec3(20, 20, 20)
        row2 = table.getRow(0.3)
        assert (str(row2[0]) == str(osim.Vec3(20, 20, 20)) and
                str(row2[1]) == str(osim.Vec3(20, 20, 20)) and
                str(row2[2]) == str(osim.Vec3(20, 20, 20)))
        # Edit columns of the table.
        col1 = table.getDependentColumnAtIndex(1)
        col1[0] = osim.Vec3(30, 30, 30)
        col1[1] = osim.Vec3(30, 30, 30)
        col1[2] = osim.Vec3(30, 30, 30)
        col1 = table.getDependentColumnAtIndex(1)
        assert (str(col1[0]) == str(osim.Vec3(30, 30, 30)) and
                str(col1[1]) == str(osim.Vec3(30, 30, 30)) and
                str(col1[2]) == str(osim.Vec3(30, 30, 30)))
        col2 = table.getDependentColumn('2')
        col2[0] = osim.Vec3(40, 40, 40)
        col2[1] = osim.Vec3(40, 40, 40)
        col2[2] = osim.Vec3(40, 40, 40)
        col2 = table.getDependentColumn('2')
        assert (str(col2[0]) == str(osim.Vec3(40, 40, 40)) and
                str(col2[1]) == str(osim.Vec3(40, 40, 40)) and
                str(col2[2]) == str(osim.Vec3(40, 40, 40)))

    def test_TimeSeriesTableVec3(self):
        table = osim.TimeSeriesTableVec3()
        # Set columns labels.
        table.setColumnLabels(['0', '1', '2'])
        assert table.getColumnLabels() == ('0', '1', '2')
        # Append a row to the table.
        row = osim.RowVectorOfVec3([osim.Vec3(1, 2, 3),
                                    osim.Vec3(4, 5, 6),
                                    osim.Vec3(7, 8, 9)])
        table.appendRow(0.1, row)
        assert table.getNumRows() == 1
        assert table.getNumColumns() == 3
        row0 = table.getRowAtIndex(0)
        assert (str(row0[0]) == str(row[0]) and
                str(row0[1]) == str(row[1]) and
                str(row0[2]) == str(row[2]))
        # Append another row to the table.
        row = osim.RowVectorOfVec3([osim.Vec3( 2,  4,  6),
                                    osim.Vec3( 8, 10, 12),
                                    osim.Vec3(14, 16, 18)])
        table.appendRow(0.2, row)
        assert table.getNumRows() == 2
        assert table.getNumColumns() == 3
        row1 = table.getRow(0.2)
        assert (str(row1[0]) == str(row[0]) and
                str(row1[1]) == str(row[1]) and
                str(row1[2]) == str(row[2]))
        # Append another row to the table with a timestamp
        # less than the previous one. Exception expected.
        try:
            table.appendRow(0.15, row)
            assert False
        except RuntimeError:
            pass
<|endoftext|>


<commit_before>{
    'name': 'Web',
    'category': 'Hidden',
    'version': '7.0.1.0',
    'description':
        """
OpenERP Web core module.
========================

This module provides the core of the OpenERP Web Client.
        """,
    'depends': [],
    'auto_install': True,
    'post_load': 'wsgi_postload',
    'js' : [
        "static/lib/datejs/globalization/en-US.js",
        "static/lib/datejs/core.js",
        "static/lib/datejs/parser.js",
        "static/lib/datejs/sugarpak.js",
        "static/lib/datejs/extras.js",
        "static/lib/jquery/jquery-1.8.2.js",
        "static/lib/jquery.MD5/jquery.md5.js",
        "static/lib/jquery.form/jquery.form.js",
        "static/lib/jquery.validate/jquery.validate.js",
        "static/lib/jquery.ba-bbq/jquery.ba-bbq.js",
        "static/lib/spinjs/spin.js",
        "static/lib/jquery.autosize/jquery.autosize.js",
        "static/lib/jquery.blockUI/jquery.blockUI.js",
        "static/lib/jquery.ui/js/jquery-ui-1.9.1.custom.js",
        "static/lib/jquery.ui.timepicker/js/jquery-ui-timepicker-addon.js",
        "static/lib/jquery.ui.notify/js/jquery.notify.js",
        "static/lib/jquery.deferred-queue/jquery.deferred-queue.js",
        "static/lib/jquery.scrollTo/jquery.scrollTo-min.js",
        "static/lib/jquery.tipsy/jquery.tipsy.js",
        "static/lib/jquery.textext/jquery.textext.js",
        "static/lib/jquery.timeago/jquery.timeago.js",
        "static/lib/qweb/qweb2.js",
        "static/lib/underscore/underscore.js",
        "static/lib/underscore/underscore.string.js",
        "static/lib/backbone/backbone.js",
        "static/lib/cleditor/jquery.cleditor.js",
        "static/lib/py.js/lib/py.js",
        "static/src/js/boot.js",
        "static/src/js/testing.js",
        "static/src/js/corelib.js",
        "static/src/js/coresetup.js",
        "static/src/js/dates.js",
        "static/src/js/formats.js",
        "static/src/js/chrome.js",
        "static/src/js/views.js",
        "static/src/js/data.js",
        "static/src/js/data_export.js",
        "static/src/js/search.js",
        "static/src/js/view_form.js",
        "static/src/js/view_list.js",
        "static/src/js/view_list_editable.js",
        "static/src/js/view_tree.js",
    ],
    'css' : [
        "static/lib/jquery.ui.bootstrap/css/custom-theme/jquery-ui-1.9.0.custom.css",
        "static/lib/jquery.ui.timepicker/css/jquery-ui-timepicker-addon.css",
        "static/lib/jquery.ui.notify/css/ui.notify.css",
        "static/lib/jquery.tipsy/tipsy.css",
        "static/lib/jquery.textext/jquery.textext.css",
        "static/src/css/base.css",
        "static/src/css/data_export.css",
        "static/lib/cleditor/jquery.cleditor.css",
    ],
    'qweb' : [
        "static/src/xml/*.xml",
    ],
    'test': [
        "static/test/testing.js",
        "static/test/class.js",
        "static/test/registry.js",
        "static/test/form.js",
        "static/test/list-utils.js",
        "static/test/formats.js",
        "static/test/rpc.js",
        "static/test/evals.js",
        "static/test/search.js",
        "static/test/Widget.js",
        "static/test/list.js"
        "static/test/list-editable.js"
    ],
    'bootstrap': True,
    'twitter': False,
}
<commit_msg>[FIX] missing comma<commit_after>{
    'name': 'Web',
    'category': 'Hidden',
    'version': '7.0.1.0',
    'description':
        """
OpenERP Web core module.
========================

This module provides the core of the OpenERP Web Client.
        """,
    'depends': [],
    'auto_install': True,
    'post_load': 'wsgi_postload',
    'js' : [
        "static/lib/datejs/globalization/en-US.js",
        "static/lib/datejs/core.js",
        "static/lib/datejs/parser.js",
        "static/lib/datejs/sugarpak.js",
        "static/lib/datejs/extras.js",
        "static/lib/jquery/jquery-1.8.2.js",
        "static/lib/jquery.MD5/jquery.md5.js",
        "static/lib/jquery.form/jquery.form.js",
        "static/lib/jquery.validate/jquery.validate.js",
        "static/lib/jquery.ba-bbq/jquery.ba-bbq.js",
        "static/lib/spinjs/spin.js",
        "static/lib/jquery.autosize/jquery.autosize.js",
        "static/lib/jquery.blockUI/jquery.blockUI.js",
        "static/lib/jquery.ui/js/jquery-ui-1.9.1.custom.js",
        "static/lib/jquery.ui.timepicker/js/jquery-ui-timepicker-addon.js",
        "static/lib/jquery.ui.notify/js/jquery.notify.js",
        "static/lib/jquery.deferred-queue/jquery.deferred-queue.js",
        "static/lib/jquery.scrollTo/jquery.scrollTo-min.js",
        "static/lib/jquery.tipsy/jquery.tipsy.js",
        "static/lib/jquery.textext/jquery.textext.js",
        "static/lib/jquery.timeago/jquery.timeago.js",
        "static/lib/qweb/qweb2.js",
        "static/lib/underscore/underscore.js",
        "static/lib/underscore/underscore.string.js",
        "static/lib/backbone/backbone.js",
        "static/lib/cleditor/jquery.cleditor.js",
        "static/lib/py.js/lib/py.js",
        "static/src/js/boot.js",
        "static/src/js/testing.js",
        "static/src/js/corelib.js",
        "static/src/js/coresetup.js",
        "static/src/js/dates.js",
        "static/src/js/formats.js",
        "static/src/js/chrome.js",
        "static/src/js/views.js",
        "static/src/js/data.js",
        "static/src/js/data_export.js",
        "static/src/js/search.js",
        "static/src/js/view_form.js",
        "static/src/js/view_list.js",
        "static/src/js/view_list_editable.js",
        "static/src/js/view_tree.js",
    ],
    'css' : [
        "static/lib/jquery.ui.bootstrap/css/custom-theme/jquery-ui-1.9.0.custom.css",
        "static/lib/jquery.ui.timepicker/css/jquery-ui-timepicker-addon.css",
        "static/lib/jquery.ui.notify/css/ui.notify.css",
        "static/lib/jquery.tipsy/tipsy.css",
        "static/lib/jquery.textext/jquery.textext.css",
        "static/src/css/base.css",
        "static/src/css/data_export.css",
        "static/lib/cleditor/jquery.cleditor.css",
    ],
    'qweb' : [
        "static/src/xml/*.xml",
    ],
    'test': [
        "static/test/testing.js",
        "static/test/class.js",
        "static/test/registry.js",
        "static/test/form.js",
        "static/test/list-utils.js",
        "static/test/formats.js",
        "static/test/rpc.js",
        "static/test/evals.js",
        "static/test/search.js",
        "static/test/Widget.js",
        "static/test/list.js",
        "static/test/list-editable.js"
    ],
    'bootstrap': True,
    'twitter': False,
}
<|endoftext|>


<commit_before>import httplib as http

from modularodm import Q

from website.project.model import MetaSchema, DraftRegistration, DraftRegistrationApproval
from framework.mongo.utils import get_or_http_error
from framework.auth.core import User
from framework.auth import Auth
from website.project.metadata.utils import serialize_meta_schema
from website.app import do_set_backends, init_addons
from website import settings as osf_settings

import utils

init_addons(osf_settings, routes=False)
do_set_backends(osf_settings)

# TODO[lauren]: change once users have osf id associated with them
adminUser = User.load('dsmpw')

def get_all_drafts():
    """Retrieves all submitted prereg drafts from OSF db
    :return: Dict of submitted prereg drafts
    """
    # TODO[lauren]: add query parameters to only retrieve submitted drafts
    # they will have an approval associated with them
    all_drafts = DraftRegistration.find()
    # TODO[lauren]: change to current user
    auth = Auth(adminUser)

    serialized_drafts = {
        'drafts': [utils.serialize_draft_registration(d, auth) for d in all_drafts]
    }
    return serialized_drafts

get_schema_or_fail = lambda query: get_or_http_error(MetaSchema, query)

def get_draft(draft_pk):
    """Retrieves a specified draft from the OSF db
    :param draft_pk: Unique id for draft
    :return: Serialized draft obj
    """
    # TODO[lauren]: change to current user
    auth = Auth(adminUser)

    draft = DraftRegistration.find(
        Q('_id', 'eq', draft_pk)
    )

    return utils.serialize_draft_registration(draft[0], auth), http.OK

def get_draft_obj(draft_pk):
    """Retrieves a specified draft from the OSF db
    :param draft_pk: Unique id for draft
    :return: Draft obj
    """
    # TODO[lauren]: change to current user
    auth = Auth(adminUser)

    draft = DraftRegistration.find(
        Q('_id', 'eq', draft_pk)
    )

    return draft[0], auth

def get_approval_obj(approval_pk):
    """Retrieves a specified approval from the OSF db
    :param approval_pk: Unique id for approval
    :return: Approval obj
    """
    # TODO[lauren]: change to current user
    auth = Auth(adminUser)

    approval = DraftRegistrationApproval.find(
        Q('_id', 'eq', approval_pk)
    )

    return approval[0], auth

def get_metaschemas():
    """Retrieves all MetaSchemas from the OSF db
    :return: Dict of serialized MetaSchemas
    """
    all_schemas = MetaSchema.find()
    serialized_schemas = {
        'schemas': [utils.serialize_meta_schema(s) for s in all_schemas]
    }
    return serialized_schemas

def get_metaschema(schema_name, schema_version=1):
    """Retrieves a specified MetaSchemas from the OSF db
    :param schema_name: name of schema to retrieve
    :param schema_version: version of schema to retrieve
    :return: Serialized MetaSchema
    """
    meta_schema = get_schema_or_fail(
        Q('name', 'eq', schema_name) &
        Q('schema_version', 'eq', schema_version)
    )
    return serialize_meta_schema(meta_schema), http.OK
<commit_msg>add comment<commit_after>import httplib as http

from modularodm import Q

from website.project.model import MetaSchema, DraftRegistration, DraftRegistrationApproval
from framework.mongo.utils import get_or_http_error
from framework.auth.core import User
from framework.auth import Auth
from website.project.metadata.utils import serialize_meta_schema
from website.app import do_set_backends, init_addons
from website import settings as osf_settings

import utils

# [lauren] I think this is done in manage-admin.py now
init_addons(osf_settings, routes=False)
do_set_backends(osf_settings)

# TODO[lauren]: remove once all auth is taken out of project
adminUser = User.load('dsmpw')

def get_all_drafts():
    """Retrieves all submitted prereg drafts from OSF db
    :return: Dict of submitted prereg drafts
    """
    # TODO[lauren]: add query parameters to only retrieve submitted drafts
    # they will have an approval associated with them
    all_drafts = DraftRegistration.find()
    # TODO[lauren]: change to current user
    auth = Auth(adminUser)

    serialized_drafts = {
        'drafts': [utils.serialize_draft_registration(d, auth) for d in all_drafts]
    }
    return serialized_drafts

get_schema_or_fail = lambda query: get_or_http_error(MetaSchema, query)

def get_draft(draft_pk):
    """Retrieves a specified draft from the OSF db
    :param draft_pk: Unique id for draft
    :return: Serialized draft obj
    """
    # TODO[lauren]: change to current user
    auth = Auth(adminUser)

    draft = DraftRegistration.find(
        Q('_id', 'eq', draft_pk)
    )

    return utils.serialize_draft_registration(draft[0], auth), http.OK

def get_draft_obj(draft_pk):
    """Retrieves a specified draft from the OSF db
    :param draft_pk: Unique id for draft
    :return: Draft obj
    """
    # TODO[lauren]: change to current user
    auth = Auth(adminUser)

    draft = DraftRegistration.find(
        Q('_id', 'eq', draft_pk)
    )

    return draft[0], auth

def get_approval_obj(approval_pk):
    """Retrieves a specified approval from the OSF db
    :param approval_pk: Unique id for approval
    :return: Approval obj
    """
    # TODO[lauren]: change to current user
    auth = Auth(adminUser)

    approval = DraftRegistrationApproval.find(
        Q('_id', 'eq', approval_pk)
    )

    return approval[0], auth

def get_metaschemas():
    """Retrieves all MetaSchemas from the OSF db
    :return: Dict of serialized MetaSchemas
    """
    all_schemas = MetaSchema.find()
    serialized_schemas = {
        'schemas': [utils.serialize_meta_schema(s) for s in all_schemas]
    }
    return serialized_schemas

def get_metaschema(schema_name, schema_version=1):
    """Retrieves a specified MetaSchemas from the OSF db
    :param schema_name: name of schema to retrieve
    :param schema_version: version of schema to retrieve
    :return: Serialized MetaSchema
    """
    meta_schema = get_schema_or_fail(
        Q('name', 'eq', schema_name) &
        Q('schema_version', 'eq', schema_version)
    )
    return serialize_meta_schema(meta_schema), http.OK
<|endoftext|>


<commit_before>from django.core.urlresolvers import reverse
from django.utils.translation import ugettext_lazy as _
from admin_tools.menu import items

class Menu(object):
    """
    This is the base class for creating custom navigation menus.
    A menu can have the following properties:

    ``template``
        A string representing the path to template to use to render the menu.
        As for any other template, the path must be relative to one of the
        directories of your ``TEMPLATE_DIRS`` setting.
        Default value: "admin_tools/menu/menu.html".

    ``children``
        A list of children menu items. All children items mus be instances of
        the :class:`~admin_tools.menu.items.MenuItem` class.

    If you want to customize the look of your menu and it's menu items, you
    can declare css stylesheets and/or javascript files to include when
    rendering the menu, for example::

        from admin_tools.menu import Menu

        class MyMenu(Menu):
            class Media:
                css = ('/media/css/mymenu.css',)
                js = ('/media/js/mymenu.js',)

    Here's a concrete example of a custom menu::

        from django.core.urlresolvers import reverse
        from admin_tools.menu import items, Menu

        class MyMenu(Menu):
            def __init__(self, **kwargs):
                super(MyMenu, self).__init__(**kwargs)
                self.children.append(
                    items.MenuItem('Home', reverse('admin:index'))
                )
                self.children.append(
                    items.AppList('Applications')
                )
                self.children.append(
                    items.MenuItem(
                        title='Multi level menu item',
                        children=[
                            items.MenuItem(title='Child 1', url='/foo/'),
                            items.MenuItem(title='Child 2', url='/bar/'),
                        ]
                    ),
                )

    Below is a screenshot of the resulting menu:

    .. image:: images/menu_example.png
    """
    template = 'admin_tools/menu/menu.html'
    children = None

    class Media:
        css = ()
        js  = ()

    def __init__(self, **kwargs):
        for key in kwargs:
            if hasattr(self.__class__, key):
                setattr(self, key, kwargs[key])
        self.children = kwargs.get('children', [])

    def init_with_context(self, context):
        """
        Sometimes you may need to access context or request variables to build
        your menu, this is what the ``init_with_context()`` method is for.
        This method is called just before the display with a
        ``django.template.RequestContext`` as unique argument, so you can
        access to all context variables and to the ``django.http.HttpRequest``.
        """
        pass

class DefaultMenu(Menu):
    """
    The default menu displayed by django-admin-tools.
    To change the default menu you'll have to type the following from the
    commandline in your project root directory::

        python manage.py custommenu

    And then set the ``ADMIN_TOOLS_MENU`` settings variable to point to your
    custom menu class.
    """
    def __init__(self, **kwargs):
        super(DefaultMenu, self).__init__(**kwargs)

        self.children += [
            items.MenuItem(_('Dashboard'), reverse('admin:index')),
            items.Bookmarks(),
            items.AppList(
                _('Applications'),
                exclude_list=('django.contrib',)
            ),
            items.AppList(
                _('Administration'),
                include_list=('django.contrib',)
            )
        ]
<commit_msg>Less verbose example for custom menu<commit_after>from django.core.urlresolvers import reverse
from django.utils.translation import ugettext_lazy as _
from admin_tools.menu import items

class Menu(object):
    """
    This is the base class for creating custom navigation menus.
    A menu can have the following properties:

    ``template``
        A string representing the path to template to use to render the menu.
        As for any other template, the path must be relative to one of the
        directories of your ``TEMPLATE_DIRS`` setting.
        Default value: "admin_tools/menu/menu.html".

    ``children``
        A list of children menu items. All children items mus be instances of
        the :class:`~admin_tools.menu.items.MenuItem` class.

    If you want to customize the look of your menu and it's menu items, you
    can declare css stylesheets and/or javascript files to include when
    rendering the menu, for example::

        from admin_tools.menu import Menu

        class MyMenu(Menu):
            class Media:
                css = ('/media/css/mymenu.css',)
                js = ('/media/js/mymenu.js',)

    Here's a concrete example of a custom menu::

        from django.core.urlresolvers import reverse
        from admin_tools.menu import items, Menu

        class MyMenu(Menu):
            def __init__(self, **kwargs):
                super(MyMenu, self).__init__(**kwargs)
                self.children += [
                    items.MenuItem('Home', reverse('admin:index')),
                    items.AppList('Applications'),
                    items.MenuItem('Multi level menu item',
                        children=[
                            items.MenuItem('Child 1', '/foo/'),
                            items.MenuItem('Child 2', '/bar/'),
                        ]
                    ),
                ]

    Below is a screenshot of the resulting menu:

    .. image:: images/menu_example.png
    """
    template = 'admin_tools/menu/menu.html'
    children = None

    class Media:
        css = ()
        js  = ()

    def __init__(self, **kwargs):
        for key in kwargs:
            if hasattr(self.__class__, key):
                setattr(self, key, kwargs[key])
        self.children = kwargs.get('children', [])

    def init_with_context(self, context):
        """
        Sometimes you may need to access context or request variables to build
        your menu, this is what the ``init_with_context()`` method is for.
        This method is called just before the display with a
        ``django.template.RequestContext`` as unique argument, so you can
        access to all context variables and to the ``django.http.HttpRequest``.
        """
        pass

class DefaultMenu(Menu):
    """
    The default menu displayed by django-admin-tools.
    To change the default menu you'll have to type the following from the
    commandline in your project root directory::

        python manage.py custommenu

    And then set the ``ADMIN_TOOLS_MENU`` settings variable to point to your
    custom menu class.
    """
    def __init__(self, **kwargs):
        super(DefaultMenu, self).__init__(**kwargs)

        self.children += [
            items.MenuItem(_('Dashboard'), reverse('admin:index')),
            items.Bookmarks(),
            items.AppList(
                _('Applications'),
                exclude_list=('django.contrib',)
            ),
            items.AppList(
                _('Administration'),
                include_list=('django.contrib',)
            )
        ]
<|endoftext|>