From f98ba0ec4fe27e9fcd945d476e043877da10bcd2 Mon Sep 17 00:00:00 2001 From: Bill Prin Date: Thu, 28 Apr 2016 11:27:56 -0700 Subject: [PATCH] Add XMPP Sample --- appengine/xmpp/README.md | 8 ++++ appengine/xmpp/app.yaml | 15 +++++++ appengine/xmpp/xmpp.py | 86 +++++++++++++++++++++++++++++++++++++ appengine/xmpp/xmpp_test.py | 60 ++++++++++++++++++++++++++ dataproc/README.md | 0 dataproc/create_cluster.py | 0 6 files changed, 169 insertions(+) create mode 100644 appengine/xmpp/README.md create mode 100644 appengine/xmpp/app.yaml create mode 100644 appengine/xmpp/xmpp.py create mode 100644 appengine/xmpp/xmpp_test.py create mode 100644 dataproc/README.md create mode 100644 dataproc/create_cluster.py diff --git a/appengine/xmpp/README.md b/appengine/xmpp/README.md new file mode 100644 index 000000000000..39a9f1f178da --- /dev/null +++ b/appengine/xmpp/README.md @@ -0,0 +1,8 @@ +# Google App Engine XMPP + +This sample includes snippets used in the [App Engine XMPP Docs](https://cloud.google.com/appengine/docs/python/xmpp/#Python_JIDs_and_resources). + + + + + diff --git a/appengine/xmpp/app.yaml b/appengine/xmpp/app.yaml new file mode 100644 index 000000000000..029a33213f94 --- /dev/null +++ b/appengine/xmpp/app.yaml @@ -0,0 +1,15 @@ +runtime: python27 +threadsafe: yes +api_version: 1 + +handlers: +- url: .* + script: xmpp.app + +# [START inbound-services] +inbound_services: +- xmpp_message +- xmpp_presence +- xmpp_subscribe +- xmpp_error +# [END inbound-services] diff --git a/appengine/xmpp/xmpp.py b/appengine/xmpp/xmpp.py new file mode 100644 index 000000000000..abd1eae86441 --- /dev/null +++ b/appengine/xmpp/xmpp.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python + +# Copyright 2016 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import logging + +# [START xmpp-imports] +from google.appengine.api import xmpp +# [END xmpp-imports] +import mock +import webapp2 + +# Mock roster of users +roster = mock.Mock() + + +class SubscribeHandler(webapp2.RequestHandler): + def post(self): + # [START track] + # Split the bare XMPP address (e.g., user@gmail.com) + # from the resource (e.g., gmail), and then add the + # address to the roster. + sender = self.request.get('from').split('/')[0] + roster.add_contact(sender) + # [END track] + + +class PresenceHandler(webapp2.RequestHandler): + def post(self): + # [START presence] + # Split the bare XMPP address (e.g., user@gmail.com) + # from the resource (e.g., gmail), and then add the + # address to the roster. + sender = self.request.get('from').split('/')[0] + roster.add_contact(sender) + # [END presence] + + +class SendPresenceHandler(webapp2.RequestHandler): + def post(self): + # [START send-presence] + jid = self.request.get('jid') + xmpp.send_presence(jid, status="My app's status") + # [END send-presence] + + +class ErrorHandler(webapp2.RequestHandler): + def post(self): + # [START error] + # In the handler for _ah/xmpp/error + # Log an error + error_sender = self.request.get('from') + error_stanza = self.request.get('stanza') + logging.error('XMPP error received from {} ({})' + .format(error_sender, error_stanza)) + # [END error] + + +# [START chat] +class XMPPHandler(webapp2.RequestHandler): + def post(self): + print "REQUEST POST IS %s " % self.request.POST + message = xmpp.Message(self.request.POST) + if message.body[0:5].lower() == 'hello': + message.reply("Greetings!") +# [END chat] + +app = webapp2.WSGIApplication([ + ('/_ah/xmpp/message/chat/', XMPPHandler), + ('/_ah/xmpp/subscribe', SubscribeHandler), + ('/_ah/xmpp/presence/available', PresenceHandler), + ('/_ah/xmpp/error/', ErrorHandler), + ('/send_presence', SendPresenceHandler), +]) diff --git a/appengine/xmpp/xmpp_test.py b/appengine/xmpp/xmpp_test.py new file mode 100644 index 000000000000..eb97a228b152 --- /dev/null +++ b/appengine/xmpp/xmpp_test.py @@ -0,0 +1,60 @@ +# Copyright 2016 Google Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import mock +import pytest +import webtest +import xmpp + + +@pytest.fixture +def app(testbed): + return webtest.TestApp(xmpp.app) + + +@mock.patch('xmpp.xmpp') +def test_chat(xmpp_mock, app): + app.post('/_ah/xmpp/message/chat/', { + 'from': 'sender@example.com', + 'to': 'recipient@example.com', + 'body': 'hello', + }) + + +@mock.patch('xmpp.xmpp') +def test_subscribe(xmpp_mock, app): + app.post('/_ah/xmpp/subscribe') + + +@mock.patch('xmpp.xmpp') +def test_check_presence(xmpp_mock, app): + + app.post('/_ah/xmpp/presence/available', { + 'from': 'sender@example.com' + }) + + +@mock.patch('xmpp.xmpp') +def test_send_presence(xmpp_mock, app): + app.post('/send_presence', { + 'jid': 'node@domain/resource' + }) + + +@mock.patch('xmpp.xmpp') +def test_error(xmpp_mock, app): + app.post('/_ah/xmpp/error/', { + 'from': 'sender@example.com', + 'stanza': 'hello world' + }) diff --git a/dataproc/README.md b/dataproc/README.md new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/dataproc/create_cluster.py b/dataproc/create_cluster.py new file mode 100644 index 000000000000..e69de29bb2d1