{"action":"created","comment":{"url":"https://api.github.com/repos/City-of-Helsinki/respa/pulls/comments/112650575","pull_request_review_id":33978775,"id":112650575,"diff_hunk":"@@ -317,9 +320,49 @@ def filter_is_favorite(self, queryset, name, value):\n         else:\n             return queryset.exclude(favorited_by=self.user)\n \n+    def _deserialize_datetime(self, value):\n+        try:\n+            return arrow.get(value).datetime\n+        except ParserError:\n+            raise exceptions.ParseError(\"'%s' must be a timestamp in ISO 8601 format\" % value)\n+\n+    def filter_available_between(self, queryset, name, value):\n+        if len(value) != 2:\n+            raise exceptions.ParseError('available_between takes exactly two comma-separated values.')\n+\n+        available_start = self._deserialize_datetime(value[0])\n+        available_end = self._deserialize_datetime(value[1])\n+\n+        if available_start.day != available_end.day:\n+            raise exceptions.ParseError('available_between timestamps must be on the same day.')\n+\n+        reservations = Reservation.objects.filter(end__gt=available_start).filter(begin__lt=available_end)\n+        queryset = queryset.exclude(reservations__in=reservations)\n+\n+        not_available_ids = []\n+        for resource in queryset:\n+            opening_hours = resource.get_opening_hours(available_start, available_end)\n+\n+            if len(opening_hours) > 1:\n+                # range spans over multiple days, assume resources aren't open all night and skip the resource\n+                not_available_ids.append(resource.id)\n+                continue\n+\n+            hours = next(iter(opening_hours.values()))[0]  # assume there is only one hours obj per day","path":"resources/api/resource.py","position":51,"original_position":51,"commit_id":"1f65728b7b8355d621498c4dd4fc4c9f6b5dc811","original_commit_id":"1f65728b7b8355d621498c4dd4fc4c9f6b5dc811","user":{"login":"akx","id":58669,"avatar_url":"https://avatars1.githubusercontent.com/u/58669?v=3","gravatar_id":"","url":"https://api.github.com/users/akx","html_url":"https://github.com/akx","followers_url":"https://api.github.com/users/akx/followers","following_url":"https://api.github.com/users/akx/following{/other_user}","gists_url":"https://api.github.com/users/akx/gists{/gist_id}","starred_url":"https://api.github.com/users/akx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/akx/subscriptions","organizations_url":"https://api.github.com/users/akx/orgs","repos_url":"https://api.github.com/users/akx/repos","events_url":"https://api.github.com/users/akx/events{/privacy}","received_events_url":"https://api.github.com/users/akx/received_events","type":"User","site_admin":false},"body":"Yigh, that's one ugly expression. 😆 ","created_at":"2017-04-21T09:36:52Z","updated_at":"2017-04-21T09:37:07Z","html_url":"https://github.com/City-of-Helsinki/respa/pull/192#discussion_r112650575","pull_request_url":"https://api.github.com/repos/City-of-Helsinki/respa/pulls/192","_links":{"self":{"href":"https://api.github.com/repos/City-of-Helsinki/respa/pulls/comments/112650575"},"html":{"href":"https://github.com/City-of-Helsinki/respa/pull/192#discussion_r112650575"},"pull_request":{"href":"https://api.github.com/repos/City-of-Helsinki/respa/pulls/192"}}},"pull_request":{"url":"https://api.github.com/repos/City-of-Helsinki/respa/pulls/192","id":116943174,"html_url":"https://github.com/City-of-Helsinki/respa/pull/192","diff_url":"https://github.com/City-of-Helsinki/respa/pull/192.diff","patch_url":"https://github.com/City-of-Helsinki/respa/pull/192.patch","issue_url":"https://api.github.com/repos/City-of-Helsinki/respa/issues/192","number":192,"state":"open","locked":false,"title":"Add available_between filter to Resource endpoint","user":{"login":"tuomas777","id":1314604,"avatar_url":"https://avatars0.githubusercontent.com/u/1314604?v=3","gravatar_id":"","url":"https://api.github.com/users/tuomas777","html_url":"https://github.com/tuomas777","followers_url":"https://api.github.com/users/tuomas777/followers","following_url":"https://api.github.com/users/tuomas777/following{/other_user}","gists_url":"https://api.github.com/users/tuomas777/gists{/gist_id}","starred_url":"https://api.github.com/users/tuomas777/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tuomas777/subscriptions","organizations_url":"https://api.github.com/users/tuomas777/orgs","repos_url":"https://api.github.com/users/tuomas777/repos","events_url":"https://api.github.com/users/tuomas777/events{/privacy}","received_events_url":"https://api.github.com/users/tuomas777/received_events","type":"User","site_admin":false},"body":"The filter expects two comma-separated datetimes and returns resources\r\nthat are open and free on the given range. Both datetimes must be on the\r\nsame day.\r\n\r\nThe implementation is currently pretty naive and doesn't scale for large amount\r\nof resources.\r\n\r\nCloses #187","created_at":"2017-04-21T09:15:29Z","updated_at":"2017-04-21T09:37:07Z","closed_at":null,"merged_at":null,"merge_commit_sha":"a9c6ba4352fbdfb4f0f311396ce52c2c7723cf19","assignee":{"login":"juyrjola","id":216030,"avatar_url":"https://avatars3.githubusercontent.com/u/216030?v=3","gravatar_id":"","url":"https://api.github.com/users/juyrjola","html_url":"https://github.com/juyrjola","followers_url":"https://api.github.com/users/juyrjola/followers","following_url":"https://api.github.com/users/juyrjola/following{/other_user}","gists_url":"https://api.github.com/users/juyrjola/gists{/gist_id}","starred_url":"https://api.github.com/users/juyrjola/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/juyrjola/subscriptions","organizations_url":"https://api.github.com/users/juyrjola/orgs","repos_url":"https://api.github.com/users/juyrjola/repos","events_url":"https://api.github.com/users/juyrjola/events{/privacy}","received_events_url":"https://api.github.com/users/juyrjola/received_events","type":"User","site_admin":false},"assignees":[{"login":"juyrjola","id":216030,"avatar_url":"https://avatars3.githubusercontent.com/u/216030?v=3","gravatar_id":"","url":"https://api.github.com/users/juyrjola","html_url":"https://github.com/juyrjola","followers_url":"https://api.github.com/users/juyrjola/followers","following_url":"https://api.github.com/users/juyrjola/following{/other_user}","gists_url":"https://api.github.com/users/juyrjola/gists{/gist_id}","starred_url":"https://api.github.com/users/juyrjola/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/juyrjola/subscriptions","organizations_url":"https://api.github.com/users/juyrjola/orgs","repos_url":"https://api.github.com/users/juyrjola/repos","events_url":"https://api.github.com/users/juyrjola/events{/privacy}","received_events_url":"https://api.github.com/users/juyrjola/received_events","type":"User","site_admin":false}],"milestone":null,"commits_url":"https://api.github.com/repos/City-of-Helsinki/respa/pulls/192/commits","review_comments_url":"https://api.github.com/repos/City-of-Helsinki/respa/pulls/192/comments","review_comment_url":"https://api.github.com/repos/City-of-Helsinki/respa/pulls/comments{/number}","comments_url":"https://api.github.com/repos/City-of-Helsinki/respa/issues/192/comments","statuses_url":"https://api.github.com/repos/City-of-Helsinki/respa/statuses/1f65728b7b8355d621498c4dd4fc4c9f6b5dc811","head":{"label":"tuomas777:available_between","ref":"available_between","sha":"1f65728b7b8355d621498c4dd4fc4c9f6b5dc811","user":{"login":"tuomas777","id":1314604,"avatar_url":"https://avatars0.githubusercontent.com/u/1314604?v=3","gravatar_id":"","url":"https://api.github.com/users/tuomas777","html_url":"https://github.com/tuomas777","followers_url":"https://api.github.com/users/tuomas777/followers","following_url":"https://api.github.com/users/tuomas777/following{/other_user}","gists_url":"https://api.github.com/users/tuomas777/gists{/gist_id}","starred_url":"https://api.github.com/users/tuomas777/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tuomas777/subscriptions","organizations_url":"https://api.github.com/users/tuomas777/orgs","repos_url":"https://api.github.com/users/tuomas777/repos","events_url":"https://api.github.com/users/tuomas777/events{/privacy}","received_events_url":"https://api.github.com/users/tuomas777/received_events","type":"User","site_admin":false},"repo":{"id":45026665,"name":"respa","full_name":"tuomas777/respa","owner":{"login":"tuomas777","id":1314604,"avatar_url":"https://avatars0.githubusercontent.com/u/1314604?v=3","gravatar_id":"","url":"https://api.github.com/users/tuomas777","html_url":"https://github.com/tuomas777","followers_url":"https://api.github.com/users/tuomas777/followers","following_url":"https://api.github.com/users/tuomas777/following{/other_user}","gists_url":"https://api.github.com/users/tuomas777/gists{/gist_id}","starred_url":"https://api.github.com/users/tuomas777/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tuomas777/subscriptions","organizations_url":"https://api.github.com/users/tuomas777/orgs","repos_url":"https://api.github.com/users/tuomas777/repos","events_url":"https://api.github.com/users/tuomas777/events{/privacy}","received_events_url":"https://api.github.com/users/tuomas777/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/tuomas777/respa","description":"Django application for resource reservation","fork":true,"url":"https://api.github.com/repos/tuomas777/respa","forks_url":"https://api.github.com/repos/tuomas777/respa/forks","keys_url":"https://api.github.com/repos/tuomas777/respa/keys{/key_id}","collaborators_url":"https://api.github.com/repos/tuomas777/respa/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/tuomas777/respa/teams","hooks_url":"https://api.github.com/repos/tuomas777/respa/hooks","issue_events_url":"https://api.github.com/repos/tuomas777/respa/issues/events{/number}","events_url":"https://api.github.com/repos/tuomas777/respa/events","assignees_url":"https://api.github.com/repos/tuomas777/respa/assignees{/user}","branches_url":"https://api.github.com/repos/tuomas777/respa/branches{/branch}","tags_url":"https://api.github.com/repos/tuomas777/respa/tags","blobs_url":"https://api.github.com/repos/tuomas777/respa/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/tuomas777/respa/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/tuomas777/respa/git/refs{/sha}","trees_url":"https://api.github.com/repos/tuomas777/respa/git/trees{/sha}","statuses_url":"https://api.github.com/repos/tuomas777/respa/statuses/{sha}","languages_url":"https://api.github.com/repos/tuomas777/respa/languages","stargazers_url":"https://api.github.com/repos/tuomas777/respa/stargazers","contributors_url":"https://api.github.com/repos/tuomas777/respa/contributors","subscribers_url":"https://api.github.com/repos/tuomas777/respa/subscribers","subscription_url":"https://api.github.com/repos/tuomas777/respa/subscription","commits_url":"https://api.github.com/repos/tuomas777/respa/commits{/sha}","git_commits_url":"https://api.github.com/repos/tuomas777/respa/git/commits{/sha}","comments_url":"https://api.github.com/repos/tuomas777/respa/comments{/number}","issue_comment_url":"https://api.github.com/repos/tuomas777/respa/issues/comments{/number}","contents_url":"https://api.github.com/repos/tuomas777/respa/contents/{+path}","compare_url":"https://api.github.com/repos/tuomas777/respa/compare/{base}...{head}","merges_url":"https://api.github.com/repos/tuomas777/respa/merges","archive_url":"https://api.github.com/repos/tuomas777/respa/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/tuomas777/respa/downloads","issues_url":"https://api.github.com/repos/tuomas777/respa/issues{/number}","pulls_url":"https://api.github.com/repos/tuomas777/respa/pulls{/number}","milestones_url":"https://api.github.com/repos/tuomas777/respa/milestones{/number}","notifications_url":"https://api.github.com/repos/tuomas777/respa/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/tuomas777/respa/labels{/name}","releases_url":"https://api.github.com/repos/tuomas777/respa/releases{/id}","deployments_url":"https://api.github.com/repos/tuomas777/respa/deployments","created_at":"2015-10-27T08:23:11Z","updated_at":"2016-03-23T10:19:00Z","pushed_at":"2017-04-21T09:12:54Z","git_url":"git://github.com/tuomas777/respa.git","ssh_url":"git@github.com:tuomas777/respa.git","clone_url":"https://github.com/tuomas777/respa.git","svn_url":"https://github.com/tuomas777/respa","homepage":null,"size":684,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"City-of-Helsinki:master","ref":"master","sha":"52ca2bb19020b03ed7d42a7ba28def290871ad99","user":{"login":"City-of-Helsinki","id":1875564,"avatar_url":"https://avatars3.githubusercontent.com/u/1875564?v=3","gravatar_id":"","url":"https://api.github.com/users/City-of-Helsinki","html_url":"https://github.com/City-of-Helsinki","followers_url":"https://api.github.com/users/City-of-Helsinki/followers","following_url":"https://api.github.com/users/City-of-Helsinki/following{/other_user}","gists_url":"https://api.github.com/users/City-of-Helsinki/gists{/gist_id}","starred_url":"https://api.github.com/users/City-of-Helsinki/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/City-of-Helsinki/subscriptions","organizations_url":"https://api.github.com/users/City-of-Helsinki/orgs","repos_url":"https://api.github.com/users/City-of-Helsinki/repos","events_url":"https://api.github.com/users/City-of-Helsinki/events{/privacy}","received_events_url":"https://api.github.com/users/City-of-Helsinki/received_events","type":"Organization","site_admin":false},"repo":{"id":36498563,"name":"respa","full_name":"City-of-Helsinki/respa","owner":{"login":"City-of-Helsinki","id":1875564,"avatar_url":"https://avatars3.githubusercontent.com/u/1875564?v=3","gravatar_id":"","url":"https://api.github.com/users/City-of-Helsinki","html_url":"https://github.com/City-of-Helsinki","followers_url":"https://api.github.com/users/City-of-Helsinki/followers","following_url":"https://api.github.com/users/City-of-Helsinki/following{/other_user}","gists_url":"https://api.github.com/users/City-of-Helsinki/gists{/gist_id}","starred_url":"https://api.github.com/users/City-of-Helsinki/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/City-of-Helsinki/subscriptions","organizations_url":"https://api.github.com/users/City-of-Helsinki/orgs","repos_url":"https://api.github.com/users/City-of-Helsinki/repos","events_url":"https://api.github.com/users/City-of-Helsinki/events{/privacy}","received_events_url":"https://api.github.com/users/City-of-Helsinki/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/City-of-Helsinki/respa","description":"Django application for resource reservation","fork":false,"url":"https://api.github.com/repos/City-of-Helsinki/respa","forks_url":"https://api.github.com/repos/City-of-Helsinki/respa/forks","keys_url":"https://api.github.com/repos/City-of-Helsinki/respa/keys{/key_id}","collaborators_url":"https://api.github.com/repos/City-of-Helsinki/respa/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/City-of-Helsinki/respa/teams","hooks_url":"https://api.github.com/repos/City-of-Helsinki/respa/hooks","issue_events_url":"https://api.github.com/repos/City-of-Helsinki/respa/issues/events{/number}","events_url":"https://api.github.com/repos/City-of-Helsinki/respa/events","assignees_url":"https://api.github.com/repos/City-of-Helsinki/respa/assignees{/user}","branches_url":"https://api.github.com/repos/City-of-Helsinki/respa/branches{/branch}","tags_url":"https://api.github.com/repos/City-of-Helsinki/respa/tags","blobs_url":"https://api.github.com/repos/City-of-Helsinki/respa/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/City-of-Helsinki/respa/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/City-of-Helsinki/respa/git/refs{/sha}","trees_url":"https://api.github.com/repos/City-of-Helsinki/respa/git/trees{/sha}","statuses_url":"https://api.github.com/repos/City-of-Helsinki/respa/statuses/{sha}","languages_url":"https://api.github.com/repos/City-of-Helsinki/respa/languages","stargazers_url":"https://api.github.com/repos/City-of-Helsinki/respa/stargazers","contributors_url":"https://api.github.com/repos/City-of-Helsinki/respa/contributors","subscribers_url":"https://api.github.com/repos/City-of-Helsinki/respa/subscribers","subscription_url":"https://api.github.com/repos/City-of-Helsinki/respa/subscription","commits_url":"https://api.github.com/repos/City-of-Helsinki/respa/commits{/sha}","git_commits_url":"https://api.github.com/repos/City-of-Helsinki/respa/git/commits{/sha}","comments_url":"https://api.github.com/repos/City-of-Helsinki/respa/comments{/number}","issue_comment_url":"https://api.github.com/repos/City-of-Helsinki/respa/issues/comments{/number}","contents_url":"https://api.github.com/repos/City-of-Helsinki/respa/contents/{+path}","compare_url":"https://api.github.com/repos/City-of-Helsinki/respa/compare/{base}...{head}","merges_url":"https://api.github.com/repos/City-of-Helsinki/respa/merges","archive_url":"https://api.github.com/repos/City-of-Helsinki/respa/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/City-of-Helsinki/respa/downloads","issues_url":"https://api.github.com/repos/City-of-Helsinki/respa/issues{/number}","pulls_url":"https://api.github.com/repos/City-of-Helsinki/respa/pulls{/number}","milestones_url":"https://api.github.com/repos/City-of-Helsinki/respa/milestones{/number}","notifications_url":"https://api.github.com/repos/City-of-Helsinki/respa/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/City-of-Helsinki/respa/labels{/name}","releases_url":"https://api.github.com/repos/City-of-Helsinki/respa/releases{/id}","deployments_url":"https://api.github.com/repos/City-of-Helsinki/respa/deployments","created_at":"2015-05-29T10:49:41Z","updated_at":"2017-03-14T10:15:59Z","pushed_at":"2017-04-21T09:15:30Z","git_url":"git://github.com/City-of-Helsinki/respa.git","ssh_url":"git@github.com:City-of-Helsinki/respa.git","clone_url":"https://github.com/City-of-Helsinki/respa.git","svn_url":"https://github.com/City-of-Helsinki/respa","homepage":null,"size":648,"stargazers_count":2,"watchers_count":2,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":6,"mirror_url":null,"open_issues_count":43,"forks":6,"open_issues":43,"watchers":2,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/City-of-Helsinki/respa/pulls/192"},"html":{"href":"https://github.com/City-of-Helsinki/respa/pull/192"},"issue":{"href":"https://api.github.com/repos/City-of-Helsinki/respa/issues/192"},"comments":{"href":"https://api.github.com/repos/City-of-Helsinki/respa/issues/192/comments"},"review_comments":{"href":"https://api.github.com/repos/City-of-Helsinki/respa/pulls/192/comments"},"review_comment":{"href":"https://api.github.com/repos/City-of-Helsinki/respa/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/City-of-Helsinki/respa/pulls/192/commits"},"statuses":{"href":"https://api.github.com/repos/City-of-Helsinki/respa/statuses/1f65728b7b8355d621498c4dd4fc4c9f6b5dc811"}}}}
{"actor":{"display_login":"akx"}}