Skip to content
This repository has been archived by the owner on Apr 5, 2019. It is now read-only.

Commit

Permalink
Merge branch 'release-1.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
kyleconroy committed Jul 20, 2010
2 parents 201813b + ce26d91 commit a652bd6
Show file tree
Hide file tree
Showing 55 changed files with 9,622 additions and 4,006 deletions.
19 changes: 19 additions & 0 deletions LICENSE
@@ -0,0 +1,19 @@
Copyright (c) 2010 Twilio Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
37 changes: 37 additions & 0 deletions README.md
@@ -0,0 +1,37 @@
# Stashboard

## About

Stashboard was written by Twilio to provide status information on our phone, SMS, and Communication APIs. We open sourced the code and to provide a generic status page designed to be customized by any hosted services company to provide customers up-to-date status information. The code can be downloaded, customized with your logo, and run on any Google App Engine account.

## Installation

First, install the App Engine SDK for Python.

Next, download and extract Stashboard to your computer.

### Run Locally

Open the SDK, choose File > Add Existing Application..., select the stashboard folder you downloaded above and choose a port. Press Run and navigate to http://localhost:{port} to see your Stashboard installation.

### Deploy to AppSpot

Before you can deploy Stashboard, you will need to create an application on App Engine.

Once your application is registered, open app.yaml in the Stashboard directory and change application-id to the name of your newly created application.

Hit the 'Deploy' button, wait a couple of seconds, and then naviagate to http://{app-name}.appspot.com to enjoy your new status dashboard

## Basic View

By default, Stashboard exposes a rich client, utilizing AJAX and jQuery. If instead you just want a basic read only view, change the `rich_client` attribute to `False` in `config.py`.

## REST API

Full documentation of the REST API can be found at <http://stashboard.appspot.com/documentation/rest>

## Future

Future plans include RSS feeds, Web Hook integration, and a richer support for different status page views.


23 changes: 19 additions & 4 deletions app.yaml
@@ -1,17 +1,32 @@
application: ismywebservicedown
version: 3
application: stashboard
version: 1
runtime: python
api_version: 1

derived_file_type:
- python_precompiled

handlers:
- url: /static
static_dir: static
# URLS for testing
#- url: /tests
# static_dir: testing
# login: required

#- url: /runner
# script: runner.py
# login: required

- url: /css
static_dir: static/css

- url: /images
static_dir: static/images

- url: /js
static_dir: static/js

- url: /widget
static_dir: static/widget

- url: /favicon\.ico
static_files: static/favicon.ico
Expand Down
31 changes: 23 additions & 8 deletions config.py
@@ -1,34 +1,49 @@
# Copyright (c) 2010 Twilio Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

import os
import logging

# Stupid error
from google.appengine.dist import use_library
use_library('django', '1.1')

APP_ROOT_DIR = os.path.abspath(os.path.dirname(__file__))

#Stashboard version
VERSION = "1.0.0"
VERSION = "1.1.0"

# If we're debugging, turn the cache off, etc.
# Set to true if we want to have our webapp print stack traces, etc
DEBUG = os.environ['SERVER_SOFTWARE'].startswith('Dev')
logging.info("Starting application in DEBUG mode: %s", DEBUG)

# Don't change default_blog or default_page to prevent conflicts when merging # Bloog source code updates.
# Do change blog or page dictionaries at the bottom of this config module.

SITE = {
"html_type": "text/html",
"charset": "utf-8",
"title": "Is My Webservice Down?",
"title": "Stashboard",
"author": "Kyle Conroy",
# This must be the email address of a registered administrator for the
# application due to mail api restrictions.
"email": "kyle.j.conroy@gmail.com",
"description": "A RESTful Status Tracker on top of App Engine.",
"root_url": "http://ismywebservicedown.appspot.com",
"master_atom_url": "/feeds/atom.xml",
"root_url": "http://stashboard.appspot.com",
"template_path": os.path.join(APP_ROOT_DIR, "views/default"),
"rich_client": True, #If false, the website will go into a simplified read-only view
}
105 changes: 93 additions & 12 deletions examples/stashboard.py
@@ -1,7 +1,7 @@
import oauth2 as oauth
import json
import urllib
from random import choice
import unittest

oauth_key = '1/PGS5Fvp5hmtUTlHnLyWDVHc8mPrev6IGwa7kicolTT8'
oauth_secret = 'MnqTu_kS47zCs0p0xr9w3H02'
Expand All @@ -18,25 +18,107 @@
# Create our client.
client = oauth.Client(consumer, token=token)

data = urllib.urlencode({
"name": "An Example Service",
"description": "An example service, created using the StashBoard API",
})
class ServicesTest(unittest.TestCase):

def testMissingServiceName(self):
"should return 400 Bad Data"
data = urllib.urlencode({
"description": "An example service API",
})

resp, content = client.request(base_url + "/services",
"POST", body=data)

self.assertEquals(resp.status, 400)

def testMissingServiceDescription(self):
"should return 400 Bad Data"
data = urllib.urlencode({
"name": "Some Random Name",
})

resp, content = client.request(base_url + "/services",
"POST", body=data)

self.assertEquals(resp.status, 400)

def testMissingServiceData(self):
"should return 400 Bad Data"
resp, content = client.request(base_url + "/services", "POST")
self.assertEquals(resp.status, 400)

def testDelete(self):
"should return 405 Method Not Allowed"
resp, content = client.request(base_url + "/services", "DELETE")
self.assertEquals(resp.status, 405)

def testPut(self):
"should return 411 Content Length Required"
resp, content = client.request(base_url + "/services", "PUT")
self.assertEquals(resp.status, 411)

def testPutWithData(self):
"should return 405 Method Not Allowed"
data = urllib.urlencode({
"name": "Some Random Name",
})
resp, content = client.request(base_url + "/services",
"PUT", body=data)
self.assertEquals(resp.status, 405)

def testServiceLifeCycle(self):
"should return 200 and a newly created status"
data = urllib.urlencode({
"name": "What a service",
"description": "An example service API",
})

resp, content = client.request(base_url + "/services", "POST", body=data)
service = json.loads(content)

self.assertEquals(resp.status, 200)
self.assertEquals(service["name"], "What a service")
self.assertEquals(service["description"], "An example service API")

resp, content = client.request(base_url + "/services/" + service["id"], "GET")
service = json.loads(content)

self.assertEquals(resp.status, 200)
self.assertEquals(service["name"], "What a service")
self.assertEquals(service["description"], "An example service API")

# Update service
data = urllib.urlencode({
"description": "An example service API woohoo",
})

resp, content = client.request(base_url + "/services/" + service["id"],
"POST", body=data)
service = json.loads(content)

self.assertEquals(resp.status, 200)
self.assertEquals(service["name"], "What a service")
self.assertEquals(service["description"], "An example service API woohoo")

# Delete service
resp, content = client.request(base_url + "/services/" + service["id"],
"DELETE")
service = json.loads(content)

# The OAuth Client request works just like httplib2 for the most part.
self.assertEquals(resp.status, 200)
self.assertEquals(service["name"], "What a service")
self.assertEquals(service["description"], "An example service API woohoo")

# POST to the Services Resource to create a new service. Save the response for
# later
resp, content = client.request(base_url + "/services", "POST", body=data)
service = json.loads(content)
if __name__ == '__main__':
unittest.main()

# GET the list of possible status images
resp, content = client.request(base_url + "/status-images", "GET")
data = json.loads(content)
images = data["images"]

# Pick a random image for our status
image = choice(images)
image = images[0]

# POST to the Statuses Resources to create a new Status
data = urllib.urlencode({
Expand All @@ -58,4 +140,3 @@
resp, content = client.request(service["url"] + "/events", "POST", body=data)
event = json.loads(content)

print event
2 changes: 1 addition & 1 deletion widget/example.html → examples/widget/example.html
Expand Up @@ -3,7 +3,7 @@

<head>
<title>HellO!</title>
<script type="text/javascript" src="http://localhost:8080/js/stashboard.js"></script>
<script type="text/javascript" src="../static/js/stashboard.js"></script>
</head>
<body>
</body>
Expand Down
File renamed without changes.

0 comments on commit a652bd6

Please sign in to comment.