-
+ {% for domain in domains %}
+
- {{ domain.name }} + {% endfor %} +
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..318bc5d --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.pyc +**/*.pyc +keys.py +.DS_Store \ No newline at end of file diff --git a/app.yaml b/app.yaml index 328e7a3..a272b2f 100644 --- a/app.yaml +++ b/app.yaml @@ -6,5 +6,9 @@ api_version: 1 handlers: - url: /dns.* script: dns.py +- url: /domains.* + script: domains.py +- url: /static + static_dir: static - url: .* script: main.py diff --git a/domains.py b/domains.py new file mode 100644 index 0000000..0cb14f7 --- /dev/null +++ b/domains.py @@ -0,0 +1,25 @@ +import wsgiref.handlers +from google.appengine.ext import webapp +from google.appengine.api import users +from google.appengine.ext.webapp import template + +from main import Domain + +class DomainsHandler(webapp.RequestHandler): + def get(self): + user = users.get_current_user() + if user: + domains = Domain.get_all_by_user(user) + logout_url = users.create_logout_url("/") + self.response.out.write(template.render('templates/domains.html', locals())) + else: + self.redirect('/') + + +def main(): + application = webapp.WSGIApplication([('/domains', DomainsHandler),], debug=True) + wsgiref.handlers.CGIHandler().run(application) + + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/main.py b/main.py index 264c1f2..93c9021 100755 --- a/main.py +++ b/main.py @@ -1,34 +1,31 @@ -#!/usr/bin/env python -# -# Copyright 2007 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 wsgiref.handlers - from google.appengine.ext import webapp from google.appengine.api import users from google.appengine.api import urlfetch from google.appengine.ext.webapp import template +from google.appengine.ext import db + +import urllib # These only work if your IP is allowed -ENOM_UID = 'fihn' -ENOM_PASS = '' +import keys +ENOM_UID = keys.enom_uid +ENOM_PASS = keys.enom_pass +ENOM_HOST = keys.enom_host +NS1 = 'ns1.domdori.com' +NS2 = 'ns2.domdori.com' + +class Domain(db.Model): + user = db.UserProperty(auto_current_user_add=True) + created = db.DateTimeProperty(auto_now_add=True) + updated = db.DateTimeProperty(auto_now=True) + name = db.StringProperty(required=True) + + @classmethod + def get_all_by_user(cls, user): + return cls.all().filter('user =', user) + def parse_response(body): return dict([kvp.split('=') for kvp in body.split('\r\n') if len(kvp) and not kvp[0] == ';']) @@ -36,6 +33,20 @@ def parse_response(body): class RegisterHandler(webapp.RequestHandler): def get(self): self.response.out.write(template.render('templates/main.html', locals())) + + def post(self): + domain = self.request.POST['domain'] + sld, tld = domain.split('.') + url = "http://%s/Interface.asp?command=Purchase&UID=%s&PW=%s&SLD=%s&TLD=%s&NS1=%s&NS2=%s" % (ENOM_HOST, ENOM_UID, ENOM_PASS, sld, tld, NS1, NS2) + resp = urlfetch.fetch(url) + resp = parse_response(resp.content) + if resp['RRPCode'] == '200': + d = Domain(name=domain) + d.put() + self.response.headers.add_header('Set-Cookie', 'flash=%s' % urllib.quote("You successfully registered %s!" % domain)) + self.redirect('/domains') + else: + self.response.out.write(resp['RRPText']) class MainHandler(webapp.RequestHandler): def get(self): @@ -54,7 +65,7 @@ def get(self): else: sld = domain tld = '@' - url = "http://resellertest.enom.com/interface.asp?Command=Check&UID=%s&PW=%s&SLD=%s&TLD=%s" % (ENOM_UID, ENOM_PASS, sld, tld) + url = "http://%s/interface.asp?Command=Check&UID=%s&PW=%s&SLD=%s&TLD=%s" % (ENOM_HOST, ENOM_UID, ENOM_PASS, sld, tld) resp = urlfetch.fetch(url) resp = parse_response(resp.content) domains = {} @@ -66,9 +77,12 @@ def get(self): domains[domain] = resp['RRPText'] self.response.out.write(str(domains)) +class SplashHandler(webapp.RequestHandler): + def get(self): + self.response.out.write("Be patient...") def main(): - application = webapp.WSGIApplication([('/', MainHandler), ('/check', CheckHandler), ('/register', RegisterHandler)], debug=True) + application = webapp.WSGIApplication([('/', SplashHandler), ('/main', MainHandler), ('/check', CheckHandler), ('/register', RegisterHandler)], debug=True) wsgiref.handlers.CGIHandler().run(application) diff --git a/static/js/jquery.cookie.js b/static/js/jquery.cookie.js new file mode 100644 index 0000000..6df1fac --- /dev/null +++ b/static/js/jquery.cookie.js @@ -0,0 +1,96 @@ +/** + * Cookie plugin + * + * Copyright (c) 2006 Klaus Hartl (stilbuero.de) + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + * + */ + +/** + * Create a cookie with the given name and value and other optional parameters. + * + * @example $.cookie('the_cookie', 'the_value'); + * @desc Set the value of a cookie. + * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true }); + * @desc Create a cookie with all available options. + * @example $.cookie('the_cookie', 'the_value'); + * @desc Create a session cookie. + * @example $.cookie('the_cookie', null); + * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain + * used when the cookie was set. + * + * @param String name The name of the cookie. + * @param String value The value of the cookie. + * @param Object options An object literal containing key/value pairs to provide optional cookie attributes. + * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object. + * If a negative value is specified (e.g. a date in the past), the cookie will be deleted. + * If set to null or omitted, the cookie will be a session cookie and will not be retained + * when the the browser exits. + * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie). + * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie). + * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will + * require a secure protocol (like HTTPS). + * @type undefined + * + * @name $.cookie + * @cat Plugins/Cookie + * @author Klaus Hartl/klaus.hartl@stilbuero.de + */ + +/** + * Get the value of a cookie with the given name. + * + * @example $.cookie('the_cookie'); + * @desc Get the value of a cookie. + * + * @param String name The name of the cookie. + * @return The value of the cookie. + * @type String + * + * @name $.cookie + * @cat Plugins/Cookie + * @author Klaus Hartl/klaus.hartl@stilbuero.de + */ +jQuery.cookie = function(name, value, options) { + if (typeof value != 'undefined') { // name and value given, set cookie + options = options || {}; + if (value === null) { + value = ''; + options.expires = -1; + } + var expires = ''; + if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) { + var date; + if (typeof options.expires == 'number') { + date = new Date(); + date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000)); + } else { + date = options.expires; + } + expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE + } + // CAUTION: Needed to parenthesize options.path and options.domain + // in the following expressions, otherwise they evaluate to undefined + // in the packed version for some reason... + var path = options.path ? '; path=' + (options.path) : ''; + var domain = options.domain ? '; domain=' + (options.domain) : ''; + var secure = options.secure ? '; secure' : ''; + document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join(''); + } else { // only name given, get cookie + var cookieValue = null; + if (document.cookie && document.cookie != '') { + var cookies = document.cookie.split(';'); + for (var i = 0; i < cookies.length; i++) { + var cookie = jQuery.trim(cookies[i]); + // Does this cookie string begin with the name we want? + if (cookie.substring(0, name.length + 1) == (name + '=')) { + cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); + break; + } + } + } + return cookieValue; + } +}; \ No newline at end of file diff --git a/static/js/jquery.growl.js b/static/js/jquery.growl.js new file mode 100644 index 0000000..2174e2f --- /dev/null +++ b/static/js/jquery.growl.js @@ -0,0 +1,143 @@ +/* + * jQuery Growl plugin + * Version 1.0.2 (8/1/2009) + * @requires jQuery v1.3.2 or later + * + * Examples at: http://fragmentedcode.com/jquery-growl + * Copyright (c) 2008-2009 David Higgins + * + * Special thanks to Daniel Mota for inspiration: + * http://icebeat.bitacoras.com/mootools/growl/ + */ + +/* +USAGE: + + $.growl(title, msg); + $.growl(title, msg, image); + $.growl(title, msg, image, priority); + +THEME/SKIN: + +You can override the default look and feel by updating these objects: +$.growl.settings.displayTimeout = 4000; +$.growl.settings.noticeTemplate = '' + + '
%message%
' + + '%message%
' + + '