Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Made a lot of progress in a few hours... O_O

  • Loading branch information...
commit de5693e33c1cfbc278333387087303b3c84ccbb1 1 parent 8b5d87f
@al-the-x authored
View
1  app.py
@@ -4,6 +4,7 @@
sys.path = [ 'packages' ] + sys.path
+
if __name__ == '__main__':
from handlers import URLS
View
13 app.yaml
@@ -4,6 +4,19 @@ runtime: python
api_version: 1
handlers:
+- url: /styles
+ static_dir: static/styles/
+
+- url: /scripts
+ static_dir: static/scripts/
+
+- url: /images
+ static_dir: static/images/
+
+- url: /tasks/.*
+ script: app.py
+ login: admin
+
- url: /.*
script: app.py
View
52 base.py
@@ -0,0 +1,52 @@
+from google.appengine.ext import webapp
+import haml, mako.lookup, yaml
+
+lookup = mako.lookup.TemplateLookup('templates',
+ preprocessor = haml.preprocessor
+)
+
+twitter = yaml.load(open('twitter.yaml', 'r'))
+
+
+class view ( dict ):
+ def __missing__ ( self, name ):
+ return None
+
+
+ def __getattr__ ( self, name ):
+ return self[name]
+
+
+ def __setattr__ ( self, name, value ):
+ self[name] = value
+
+ return value
+
+
+class RequestHandler ( webapp.RequestHandler ):
+ segments = { }
+
+ view = view(at_anywhere_url = (
+ twitter['at_anywhere']['url'] % twitter['at_anywhere']['api_key']
+ ))
+
+
+ def get_rendered_template ( self, template ):
+ return lookup.get_template(template).render(
+ segments = self.segments,
+ view = self.view
+ )
+
+
+ def render_to_response ( self, template ):
+ self.response.out.write(self.get_rendered_template(template))
+
+ return self
+
+
+ def render_to_segment ( self, template, segment = 'default' ):
+ self.segments[segment] = self.get_rendered_template(template)
+
+ return self
+
+
View
5 cron.yaml
@@ -0,0 +1,5 @@
+cron:
+- description: fetch new Tweets via Search API
+ url: /tasks/fetch/
+ schedule: every 2 mins
+
View
64 handlers.py
@@ -1,25 +1,65 @@
-from google.appengine.ext import webapp
-import haml, mako.lookup
+from google.appengine.ext import db
+from base import RequestHandler
+from models import Tweet, User
+import functools, tweepy, yaml
-lookup = mako.lookup.TemplateLookup('templates',
- preprocessor = haml.preprocessor
-)
+def login_optional ( f ):
+ @functools.wraps(f)
+ def get_user ( self, *args, **kwargs ):
+ user = User.for_screen_name(self.request.get('screen_name', None))
+ return f(self, user, *args, **kwargs)
+ return get_user
-class RequestHandler ( webapp.RequestHandler ):
- def render ( self, template, write = True ):
- output = lookup.get_template(template).render()
- if write: self.response.out.write(output)
+class IndexPage ( RequestHandler ):
+ def get ( self ):
+ self.view.recents = [ ]
- return output
+ self.render_to_response('index.haml')
-class IndexPage ( RequestHandler ):
+class MarkdPage ( RequestHandler ):
+ @login_optional
+ def get ( self, user ):
+ self.view.user = user
+
+ self.view.by_me = Tweet.all_from(
+ user.id if user else None
+ ).fetch(limit = 5)
+
+ self.view.for_me = Tweet.all_to(
+ user.id if user else None
+ ).fetch(limit = 5)
+
+ self.render_to_response('markd.haml')
+
+
+class FetchTask ( RequestHandler ):
+ #@db.run_in_transaction
def get ( self ):
- self.render('index.haml')
+ last_tweet = Tweet.all().get()
+
+ since = last_tweet and last_tweet.created_at
+
+ self.response.out.write(
+ 'Fetching since "%s":' % since.isoformat() if since else 'Initial run:'
+ )
+
+ for result in tweepy.api.search('#markd', filter = 'links', since = since):
+ t = Tweet.get_or_insert(result.id_str, status_id = result.id_str,
+ from_user = User.for_screen_name(result.from_user),
+ to_user = User.for_user_id(result.to_user_id),
+ created_at = result.created_at, text = result.text
+ )
+
+ self.response.out.write('.' if t else 'X')
+
+ else: self.response.out.write('Done.')
URLS = [
(r'/', IndexPage),
+ (r'/markd/', MarkdPage),
+ (r'/tasks/fetch/', FetchTask),
]
View
80 models.py
@@ -0,0 +1,80 @@
+from google.appengine.ext import db
+import tweepy
+
+class User ( db.Model ):
+ id = db.StringProperty()
+
+ screen_name = db.StringProperty()
+
+
+ @classmethod
+ def for_user_id ( cls, user_id ):
+ if not user_id: return None
+
+ try: twitter_user = tweepy.api.get_user(user_id = user_id)
+
+ except tweepy.error.TweepError: return None
+
+ return cls.get_or_insert(twitter_user.screen_name,
+ id = twitter_user.id_str, screen_name = twitter_user.screen_name
+ )
+
+
+ @classmethod
+ def for_screen_name ( cls, screen_name ):
+ if not screen_name: return None
+
+ return cls.get_or_insert(screen_name, **dict( (k, str(v)) for k, v in vars(
+ tweepy.api.get_user(screen_name = screen_name)
+ ).items() if k in ( 'id', 'screen_name' ) ))
+
+
+ def __str__ ( self ): return unicode(self)
+
+ def __unicode__ ( self ):
+ return unicode(self.screen_name)
+
+
+class Tweet ( db.Model ):
+ status_id = db.StringProperty()
+
+ from_user = db.ReferenceProperty(User,
+ collection_name = 'tweets_from'
+ )
+
+ to_user = db.ReferenceProperty(User,
+ collection_name = 'tweets_to'
+ )
+
+ created_at = db.DateTimeProperty()
+
+ text = db.StringProperty(
+ multiline = True
+ )
+
+
+ @classmethod
+ def all ( cls, *args, **kwargs ):
+ return super(Tweet, cls).all(
+ *args, **kwargs
+ ).order('-created_at')
+
+
+ @classmethod
+ def all_from ( cls, user_id ):
+ return cls.all().filter('from_user_id =', user_id)
+
+
+ @classmethod
+ def all_to ( cls, user_id ):
+ if not user_id: return cls.all().filter('from_user_id =', None)
+
+ return cls.all().filter('to_user_id =', user_id)
+
+
+ def __str__ (self ): return self.__unicode__()
+
+ def __unicode__ ( self ):
+ return unicode(self.text)
+
+
View
4 static/styles/main.css
@@ -0,0 +1,4 @@
+/**
+ * @author David Rogers <david@ethos-development.com>
+ */
+/* I'll get to this eventually... */
View
7 templates/index.haml
@@ -1,8 +1,5 @@
-%h1
- %a(href='hashmarkd.com') hashmarkd.com
-
-%p
- Share links with your friends and the rest of the
+<%inherit file="site.haml" />
+%p Share links with your friends and the rest of the
Twitterverse just by adding the hashtag
%a(href="http://search.twitter.com/search?q=%23markd") \#markd
to your tweets (but following
View
21 templates/markd.haml
@@ -0,0 +1,21 @@
+<%inherit file="site.haml" />
+<%def name="marks(marks)">
+- if not marks:
+ %li Nothing #markd yet! |
+ %a(href="http://twitter.com", rel="external") Get to tweeting!
+- for mark in marks:
+ %li ${mark}
+</%def>
+<%def name="body()">
+%h2 Try it out!
+%form
+ %label(**{ 'for': "screen_name"}) @
+ %input(name="screen_name", value=view.user)
+%ul.panels
+ %li.panel#by_me
+ %h3 \#markd by @${view.user or 'me'}
+ %ul ${self.marks(view.by_me)}
+ %li.panel#for_me
+ %h3 \#markd for @${view.user or 'me'}
+ %ul ${self.marks(view.for_me)}
+</%def>
View
20 templates/site.haml
@@ -0,0 +1,20 @@
+!!! Strict
+%html
+ %head
+ %title hashmarkd.com \| share bookmarks with the Twitterverse
+ %script(src=view.at_anywhere_url, type="text/javascript")
+ %link(href="/styles/main.css", rel="stylesheet", type="text/css")
+ %body
+ #header
+ %h1#logo
+ %a(href="http://hashmarkd.com") hashmarkd.com
+ %ul#meta-nav
+ %li#login
+ %a(href="#") Connect with Twitter (coming soon!)
+ %ul#main-nav
+ %li
+ %a(href="/markd/#by_me") \#markd by me
+ %li
+ %a(href="/markd/#for_me") \#markd for me
+ .content ${self.body()}
+
Please sign in to comment.
Something went wrong with that request. Please try again.