Permalink
Browse files

Place features are in.

  • Loading branch information...
1 parent ae4be58 commit baeb65e396ea2d7b9ff0f93bf06c58b99a4097c0 @livid committed Aug 3, 2010
View
@@ -104,6 +104,12 @@ handlers:
- url: /images(/.*)?
script: images.py
+
+- url: /place/([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})
+ script: place.py
+
+- url: /remove/place_message/(.*)
+ script: place.py
- url: /_ah/mail/.+
script: mail.py
@@ -113,6 +119,10 @@ handlers:
script: xmpp.py
login: admin
+- url: /remote_api
+ script: $PYTHON_LIB/google/appengine/ext/remote_api/handler.py
+ login: admin
+
- url: .*
script: main.py
View
@@ -0,0 +1,25 @@
+#!/usr/bin/python
+import code
+import getpass
+import sys
+
+sys.path.append("/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine")
+sys.path.append("/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/yaml/lib")
+
+from google.appengine.ext.remote_api import remote_api_stub
+from google.appengine.ext import db
+
+def auth_func():
+ return raw_input('Username:'), getpass.getpass('Password:')
+
+if len(sys.argv) < 2:
+ print "Usage: %s app_id [host]" % (sys.argv[0],)
+app_id = sys.argv[1]
+if len(sys.argv) > 2:
+ host = sys.argv[2]
+else:
+ host = '%s.appspot.com' % app_id
+
+remote_api_stub.ConfigureRemoteDatastore(app_id, '/remote_api', auth_func, host)
+
+code.interact('App Engine interactive console for %s' % (app_id,), None, locals())
View
@@ -59,6 +59,12 @@ indexes:
- name: last_modified
direction: desc
+- kind: PlaceMessage
+ properties:
+ - name: place
+ - name: created
+ direction: desc
+
- kind: Reply
properties:
- name: __key__
View
@@ -48,6 +48,10 @@ def head(self):
pass
def get(self):
+ host = self.request.headers['Host']
+ if host == 'beta.v2ex.com':
+ self.redirect('http://v2ex.appspot.com/')
+ return
browser = detect(self.request)
self.session = Session()
template_values = {}
View
148 place.py
@@ -0,0 +1,148 @@
+#!/usr/bin/env python
+# coding=utf-8
+
+import os
+import re
+import time
+import datetime
+import hashlib
+import string
+import random
+
+from google.appengine.ext import webapp
+from google.appengine.api import memcache
+from google.appengine.ext import db
+from google.appengine.ext.webapp import util
+from google.appengine.ext.webapp import template
+
+from v2ex.babel import Member
+from v2ex.babel import Counter
+from v2ex.babel import Section
+from v2ex.babel import Node
+from v2ex.babel import Topic
+from v2ex.babel import Reply
+from v2ex.babel import Note
+from v2ex.babel import Place
+from v2ex.babel import PlaceMessage
+
+from v2ex.babel import SYSTEM_VERSION
+
+from v2ex.babel.security import *
+from v2ex.babel.ua import *
+from v2ex.babel.da import *
+from v2ex.babel.ext.cookies import Cookies
+
+template.register_template_library('v2ex.templatetags.filters')
+
+class PlaceHandler(webapp.RequestHandler):
+ def get(self, ip):
+ template_values = {}
+ template_values['rnd'] = random.randrange(1, 100)
+ member = CheckAuth(self)
+ if member:
+ template_values['member'] = member
+ template_values['ip'] = ip
+ substance = GetPlaceByIP(ip)
+ if substance:
+ template_values['substance'] = substance
+ template_values['messages'] = db.GqlQuery("SELECT * FROM PlaceMessage WHERE place = :1 ORDER BY created DESC LIMIT 30", substance)
+ else:
+ if member:
+ if member.ip == ip:
+ substance = CreatePlaceByIP(ip)
+ template_values['substance'] = substance
+ can_post = False
+ can_see = True
+ if member:
+ if member.ip == ip:
+ can_post = True
+ can_see = True
+ else:
+ can_see = False
+ else:
+ if 'X-Real-IP' in handler.request.headers:
+ ip_guest = handler.request.headers['X-Real-IP']
+ else:
+ ip_guest = handler.request.remote_addr
+ if ip_guest == ip:
+ can_see = True
+ else:
+ can_see = False
+ template_values['can_post'] = can_post
+ template_values['can_see'] = can_see
+ if member:
+ template_values['ip_guest'] = member.ip
+ else:
+ template_values['ip_guest'] = ip_guest
+ template_values['page_title'] = u'V2EX › ' + ip
+ path = os.path.join(os.path.dirname(__file__), 'tpl', 'desktop', 'place.html')
+ output = template.render(path, template_values)
+ self.response.out.write(output)
+
+ def post(self, ip):
+ if 'Referer' in self.request.headers:
+ go = self.request.headers['Referer']
+ else:
+ go = '/place'
+ member = CheckAuth(self)
+ place = GetPlaceByIP(ip)
+ say = self.request.get('say').strip()
+ if len(say) > 0 and len(say) < 280 and member and place:
+ if member.ip == ip:
+ message = PlaceMessage()
+ q = db.GqlQuery('SELECT * FROM Counter WHERE name = :1', 'place_message.max')
+ if (q.count() == 1):
+ counter = q[0]
+ counter.value = counter.value + 1
+ else:
+ counter = Counter()
+ counter.name = 'place_message.max'
+ counter.value = 1
+ q2 = db.GqlQuery('SELECT * FROM Counter WHERE name = :1', 'place_message.total')
+ if (q2.count() == 1):
+ counter2 = q2[0]
+ counter2.value = counter2.value + 1
+ else:
+ counter2 = Counter()
+ counter2.name = 'place_message.total'
+ counter2.value = 1
+ message.num = counter.value
+ message.place = place
+ message.place_num = place.num
+ message.member = member
+ message.content = say
+ message.put()
+ counter.put()
+ counter2.put()
+ self.redirect(go)
+
+class PlaceMessageRemoveHandler(webapp.RequestHandler):
+ def get(self, key):
+ if 'Referer' in self.request.headers:
+ go = self.request.headers['Referer']
+ else:
+ go = '/place'
+ member = CheckAuth(self)
+ if member:
+ message = db.get(db.Key(key))
+ if message:
+ if message.member.num == member.num:
+ message.delete()
+ q = db.GqlQuery('SELECT * FROM Counter WHERE name = :1', 'place_message.total')
+ if (q.count() == 1):
+ counter = q[0]
+ counter.value = counter.value - 1
+ counter.put()
+ self.redirect(go)
+
+def main():
+ application = webapp.WSGIApplication([
+ ('/place/([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})', PlaceHandler),
+ ('/remove/place_message/(.*)', PlaceMessageRemoveHandler)
+ ],
+ debug=True)
+ util.run_wsgi_app(application)
+
+
+if __name__ == '__main__':
+ main()
@@ -631,4 +631,41 @@ table.grid td.left {
-moz-border-radius: 4px 4px 0px 0px; -webkit-border-radius: 4px;
}
-.cell .gist { max-width: 576px; }
+.cell .gist { max-width: 576px; }
+
+.place_title {
+ font-family: "DINPro";
+ font-size: 32px;
+ line-height: 32px;
+ padding: 0px;
+ margin: 0px;
+}
+
+.place_visitors {
+ font-family: "DINPro";
+ font-size: 14px;
+ line-height: 14px;
+ color: #999;
+}
+
+.place_say {
+ font-family: "DINPro";
+ font-size: 14px;
+ line-height: 14px;
+ color: #999;
+}
+
+a.tiny_label:link, a.tiny_label:visited, a.tiny_label:active {
+ font-size: 10px;
+ line-height: 10px;
+ color: #fff;
+ background-color: #dde;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ padding: 2px 5px 2px 5px;
+}
+
+a.tiny_label:hover {
+ text-decoration: none;
+ background-color: #99a;
+}
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -0,0 +1,24 @@
+<script type="text/javascript">
+ var updateCount = function() {
+ s = document.getElementById("say");
+ r = 280 - s.value.length;
+ tc = document.getElementById("tc");
+ tc.innerHTML = r;
+ }
+</script>
+<form method="post" action="/place/{{ ip }}">
+<textarea class="mll short" name="say" maxlength="280" id="say" onkeyup="updateCount();"></textarea>
+<div class="sep10"></div>
+<div class="fr"><input type="submit" value="Say" class="super normal button" /></div>
+<div class="sep10"></div>
+<div class="sep10"></div>
+<div class="sep5"></div>
+</form>
+<script type="text/javascript">
+ var focusStatus = function() {
+ s = document.getElementById("say");
+ s.focus();
+ }
+
+ setTimeout("focusStatus()", 200);
+</script>
@@ -12,6 +12,7 @@
{% endifequal %}
<!--<li><a href="/mentions" class="white">提到我的</a></li>-->
<li><a href="/notes" class="white">记事本</a></li>
+ <li><a href="/place/{{ member.ip }}" class="white">附近</a></li>
<li><a href="/settings" class="white">设置</a></li>
{% ifequal member.num 1 %}
<li><a href="/backstage" class="white">后台</a></li>
@@ -0,0 +1,43 @@
+{% include 'common/head.html' %}
+<body>
+ {% include 'common/top.html' %}
+ <div id="Wrapper">
+ <div id="Main">
+ <div id="Sidebar">
+ </div>
+ <div id="Rightbar">
+ {% include 'rightbar/user.html' %}
+ </div>
+ <div id="Content">
+ <div class="box">
+ <div class="cell">
+ <span class="fade"><a href="/">V2EX</a> <span class="chevron">&nbsp;&nbsp;</span> 图片上传</span>
+ </div>
+ <div class="inner">
+ </div>
+ <div class="grid">
+ <table cellpadding="5" cellspacing="0" border="1" width="100%" class="grid">
+ <tr>
+ <td width="25%" class="left"></td>
+ <td width="25%"></td>
+ <td width="25%"></td>
+ <td width="25%"></td>
+ </tr>
+ <tr>
+ <td width="25%" class="left"></td>
+ <td width="25%"></td>
+ <td width="25%"></td>
+ <td width="25%"></td>
+ </tr>
+ </table>
+ </div>
+ <div class="inner">
+ </div>
+ </div>
+ </div>
+ <div class="c"></div>
+ </div>
+ </div>
+ {% include 'common/bottom.html' %}
+</body>
+</html>
View
@@ -17,6 +17,8 @@
{% include 'rightbar/recent_nodes.html' %}
<div class="sep20"></div>
{% include 'rightbar/ads.html' %}
+ <div class="sep20"></div>
+ {% include 'rightbar/goodies.html' %}
</div>
<div id="Content">
<div class="box">
Oops, something went wrong.

0 comments on commit baeb65e

Please sign in to comment.