def giphy(client, channel, nick, message, cmd, args): key = getattr(settings, 'GIPHY_API_KEY', GIPHY_PUBLIC_KEY) api = Giphy(api_key=key, strict=True) search = ' '.join(args) try: return api.random_gif(search).media_url except GiphyApiException: try: return api.translate(search).media_url except GiphyApiException: try: return api.search_list(search, limit=1)[0].media_url except (GiphyApiException, IndexError): pass return random.choice(responses).format(nick=nick)
class GiphyExtension(CommandExtension): """ A plugin for all things gifs """ NAME = 'giphy' usage = '[BOTNICK] (gif|gifme) [<search_term> ...]' sad_panda = [ "Well this is embarassing...", "Yeah I've got nothing %(nick)s", "I couldn't find anything for you %(nick)s", "PC LOAD LETTER", ] def __init__(self, *args, **kwargs): self.api_key = getattr(settings, 'GIPHY_API_KEY', GIPHY_PUBLIC_KEY) logger.info('Connecting to Giphy API with key %s' % self.api_key) self.api = Giphy(api_key=GIPHY_PUBLIC_KEY, strict=True) super(GiphyExtension, self).__init__(*args, **kwargs) def handle_message(self, opts, message): search = ' '.join(opts['<search_term>']) message.response = self.gifme(search=search) def gifme(self, search=None): """ Hook into giphypop to find a gif. If no search term, just return a random gif. If a search term is given, try to translate it and default back to a search """ try: return self.api.random_gif(search).media_url except GiphyApiException: try: return self.api.translate(search).media_url except GiphyApiException: try: return self.api.search_list(search, limit=1)[0].media_url except (GiphyApiException, IndexError): pass return random.choice(self.sad_panda)
class GiphyTestCase(TestCase): def setUp(self): self.g = Giphy() def test_endpoint(self): assert self.g._endpoint('search') == 'http://api.giphy.com/v1/gifs/search' def test_check_or_raise_raises(self): self.assertRaises(GiphyApiException, self.g._check_or_raise, {'status': 400}) def test_check_or_raise_no_status(self): self.assertRaises(GiphyApiException, self.g._check_or_raise, {}) def test_check_or_raise(self): assert self.g._check_or_raise({'status': 200}) is None @patch('giphypop.requests') def test_fetch_error_raises(self, requests): # api returns error messages sorta like... err = {'meta': {'error_type': 'ERROR', 'code': 400, 'error_message': ''}} requests.get.return_value = requests requests.json.return_value = err self.assertRaises(GiphyApiException, self.g._fetch, 'foo') @patch('giphypop.requests') def test_fetch(self, requests): data = {'data': FAKE_DATA, 'meta': {'status': 200}} requests.get.return_value = requests requests.json.return_value = data assert self.g._fetch('foo') == data def fake_search_fetch(self, num_results, pages=3): self.g._fetch = Mock() self.g._fetch.return_value = { 'data': [FAKE_DATA for x in range(num_results)], 'pagination': { 'total_count': pages * num_results, 'count': 25, 'offset': 0 }, 'meta': {'status': 200} } def fake_trending_fetch(self, num_results, pages=3): self.g._fetch = Mock() self.g._fetch.return_value = { 'data': [FAKE_DATA for x in range(num_results)], 'pagination': { 'total_count': pages * num_results, 'count': 25, 'offset': 0 }, 'meta': {'status': 200} } def fake_fetch(self, result=FAKE_DATA): self.g._fetch = Mock() self.g._fetch.return_value = { 'data': result or None, 'meta': {'status': 200} } def test_search_no_results(self): self.fake_search_fetch(0, pages=1) results = list(self.g.search('foo')) assert len(results) == 0 def test_search_respects_hard_limit(self): self.fake_search_fetch(25) results = list(self.g.search('foo', limit=10)) assert len(results) == 10 def test_search_handles_pages(self): self.fake_search_fetch(25) results = list(self.g.search('foo', limit=50)) assert len(results) == 50 def test_search_correctly_pages(self): self.fake_search_fetch(25, pages=2) list(self.g.search('foo', limit=50)) calls = self.g._fetch.call_args_list assert len(calls) == 2 assert calls[0][1]['offset'] == 0 assert calls[1][1]['offset'] == 25 def test_search_no_limit_returns_all(self): self.fake_search_fetch(25) results = list(self.g.search('foo', limit=None)) assert len(results) == 75 def test_search_list_returns_list(self): self.fake_search_fetch(25) results = self.g.search_list('foo', limit=10) assert isinstance(results, list) assert len(results) == 10 def test_search_with_phrase_hyphenates(self): self.fake_search_fetch(0, pages=1) self.g.search(phrase='foo bar baz') assert self.g._fetch.called_with(q='foo-bar-baz') def test_translate_with_phrase_hyphenates(self): self.fake_fetch() self.g.translate(phrase='foo bar baz') assert self.g._fetch.called_with(s='foo-bar-baz') def test_translate(self): self.fake_fetch() assert isinstance(self.g.translate('foo'), GiphyImage) assert self.g._fetch.called_with('translate') def test_trending_no_results(self): self.fake_trending_fetch(0, pages=1) results = list(self.g.trending()) assert len(results) == 0 def test_trending_respects_hard_limit(self): self.fake_trending_fetch(25) results = list(self.g.trending(limit=10)) assert len(results) == 10 def test_trending_handles_pages(self): self.fake_trending_fetch(25) results = list(self.g.trending(limit=50)) assert len(results) == 50 def test_trending_correctly_pages(self): self.fake_trending_fetch(25, pages=2) list(self.g.trending(limit=50)) calls = self.g._fetch.call_args_list assert len(calls) == 2 assert calls[0][1]['offset'] == 0 assert calls[1][1]['offset'] == 25 def test_trending_no_limit_returns_all(self): self.fake_trending_fetch(25) results = list(self.g.trending(limit=None)) assert len(results) == 75 def test_trending_list_returns_list(self): self.fake_trending_fetch(25) results = self.g.trending_list(limit=10) assert isinstance(results, list) assert len(results) == 10 def test_gif(self): self.fake_fetch() assert isinstance(self.g.gif('foo'), GiphyImage) assert self.g._fetch.called_with('foo') def test_screensaver(self): self.fake_fetch() assert isinstance(self.g.screensaver(), GiphyImage) def test_screensaver_passes_tag(self): self.fake_fetch() self.g.screensaver('foo') assert self.g._fetch.called_with(tag='foo') def test_random_gif(self): self.fake_fetch() assert isinstance(self.g.random_gif(), GiphyImage) def test_translate_returns_none(self): self.fake_fetch(result=None) assert self.g.translate('foo') is None def test_gif_returns_none(self): self.fake_fetch(result=None) assert self.g.gif('foo') is None def test_screensaver_returns_none(self): self.fake_fetch(result=None) assert self.g.screensaver('foo') is None def test_translate_raises_strict(self): self.fake_fetch(result=None) self.assertRaises(GiphyApiException, self.g.translate, 'foo', strict=True) def test_gif_returns_raises_strict(self): self.fake_fetch(result=None) self.assertRaises(GiphyApiException, self.g.gif, 'foo', strict=True) def test_screensaver_raises_strict(self): self.fake_fetch(result=None) self.assertRaises(GiphyApiException, self.g.screensaver, 'foo', strict=True) def test_strict_for_all(self): self.g = Giphy(strict=True) self.fake_fetch(result=None) self.assertRaises(GiphyApiException, self.g.translate, 'foo', strict=False) self.assertRaises(GiphyApiException, self.g.gif, 'foo', strict=False) self.assertRaises(GiphyApiException, self.g.screensaver, 'foo', strict=False) @patch('requests.post') def test_upload(self, post): resp = Mock() resp.json.return_value = { "data": {"id": "testid"}, "meta": {"status": 200} } post.return_value = resp self.g.gif = Mock(return_value="test") self.assertEqual(self.g.upload(['foo', 'bar'], '/dev/null'), "test") self.assertTrue(post.called) self.g.gif.assert_called_with("testid")
class GiphyTestCase(TestCase): def runTest(self): pass def setUp(self): self.g = Giphy() def test_endpoint(self): assert self.g._endpoint('search') == 'http://api.giphy.com/v1/gifs/search' def test_check_or_raise_raises(self): self.assertRaises(GiphyApiException, self.g._check_or_raise, {'status': 400}) def test_check_or_raise_no_status(self): self.assertRaises(GiphyApiException, self.g._check_or_raise, {}) def test_check_or_raise(self): assert self.g._check_or_raise({'status': 200}) is None @patch('giphypop.requests') def test_fetch_error_raises(self, requests): # api returns error messages sorta like... err = {'meta': {'error_type': 'ERROR', 'code': 400, 'error_message': ''}} requests.get.return_value = requests requests.json.return_value = err self.assertRaises(GiphyApiException, self.g._fetch, 'foo') @patch('giphypop.requests') def test_fetch(self, requests): data = {'data': FAKE_DATA, 'meta': {'status': 200}} requests.get.return_value = requests requests.json = data assert self.g._fetch('foo') == data @patch('giphypop.requests') def test_fetch_sort_recent(self, requests): data = {'data': FAKE_DATA_RECENT, 'meta': {'status': 200}} requests.get.return_value = requests requests.json = data assert self.g._fetch('foo', recent=True) == data @patch('giphypop.requests') def test_fetch_data_sort_relevant(self, requests): data = {'data': FAKE_DATA_RELEVANT, 'meta': {'status': 200}} requests.get.return_value = requests requests.json = data assert self.g._fetch('foo') == data def fake_search_fetch(self, num_results, pages=3): self.g._fetch = Mock() self.g._fetch.return_value = { 'data': [FAKE_DATA for x in range(num_results)], 'pagination': { 'total_count': pages, 'count': 25, 'offset': 0 }, 'meta': {'status': 200} } def fake_search_fetch_recent(self): self.g._fetch = Mock() self.g._fetch.return_value = { 'data': FAKE_DATA_RECENT, 'pagination': { 'total_count': 3, 'count': len(FAKE_DATA_RECENT), 'offset': 0 }, 'meta': {'status': 200} } def fake_search_fetch_relevant(self): self.g._fetch = Mock() self.g._fetch.return_value = { 'data': FAKE_DATA_RELEVANT, 'pagination': { 'total_count': 3, 'count': len(FAKE_DATA_RELEVANT), 'offset': 0 }, 'meta': {'status': 200} } def fake_fetch(self, result=FAKE_DATA): self.g._fetch = Mock() self.g._fetch.return_value = { 'data': result or None, 'meta': {'status': 200} } def test_search_no_results(self): self.fake_search_fetch(0, pages=1) results = [x for x in self.g.search('foo')] assert len(results) == 0 def test_search_respects_hard_limit(self): self.fake_search_fetch(25) results = [x for x in self.g.search('foo', limit=10)] assert len(results) == 10 def test_search_handles_pages(self): self.fake_search_fetch(25) results = [x for x in self.g.search('foo', limit=50)] assert len(results) == 50 def test_search_no_limit_returns_all(self): self.fake_search_fetch(25) results = [x for x in self.g.search('foo', limit=None)] assert len(results) == 75 def test_search_list_returns_list(self): self.fake_search_fetch(25) results = self.g.search_list('foo', limit=10) assert isinstance(results, list) assert len(results) == 10 def test_search_with_phrase_hyphenates(self): self.fake_search_fetch(0, pages=1) self.g.search(phrase='foo bar baz') assert self.g._fetch.called_with(q='foo-bar-baz') def test_search_with_recent_parameter(self): self.fake_search_fetch_recent() results = self.g._fetch(phrase='foo', sort_recent=True) assert results.get('data') == FAKE_DATA_RECENT def test_search_with_relevant_parameter(self): self.fake_search_fetch_relevant() results = self.g._fetch(phrase='foo', sort_recent=False) assert results.get('data') == FAKE_DATA_RELEVANT def test_translate_with_phrase_hyphenates(self): self.fake_fetch() self.g.translate(phrase='foo bar baz') assert self.g._fetch.called_with(s='foo-bar-baz') def test_translate(self): self.fake_fetch() assert isinstance(self.g.translate('foo'), GiphyImage) assert self.g._fetch.called_with('translate') def test_gif(self): self.fake_fetch() assert isinstance(self.g.gif('foo'), GiphyImage) assert self.g._fetch.called_with('foo') def test_screensaver(self): self.fake_fetch() assert isinstance(self.g.screensaver(), GiphyImage) def test_screensaver_passes_tag(self): self.fake_fetch() self.g.screensaver('foo') assert self.g._fetch.called_with(tag='foo') def test_random_gif(self): self.fake_fetch() assert isinstance(self.g.random_gif(), GiphyImage) def test_translate_returns_none(self): self.fake_fetch(result=None) assert self.g.translate('foo') is None def test_gif_returns_none(self): self.fake_fetch(result=None) assert self.g.gif('foo') is None def test_screensaver_returns_none(self): self.fake_fetch(result=None) assert self.g.screensaver('foo') is None def test_translate_raises_strict(self): self.fake_fetch(result=None) self.assertRaises(GiphyApiException, self.g.translate, 'foo', strict=True) def test_gif_returns_raises_strict(self): self.fake_fetch(result=None) self.assertRaises(GiphyApiException, self.g.gif, 'foo', strict=True) def test_screensaver_raises_strict(self): self.fake_fetch(result=None) self.assertRaises(GiphyApiException, self.g.screensaver, 'foo', strict=True) def test_strict_for_all(self): self.g = Giphy(strict=True) self.fake_fetch(result=None) self.assertRaises(GiphyApiException, self.g.translate, 'foo', strict=False) self.assertRaises(GiphyApiException, self.g.gif, 'foo', strict=False) self.assertRaises(GiphyApiException, self.g.screensaver, 'foo', strict=False)