Incomplete webapp to aggregate achievements/badges from various sources
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

helloworld.py 6.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. import logging
  2. import os
  3. from Scraper import Scraper
  4. from google.appengine.ext.webapp import template
  5. from google.appengine.ext import webapp
  6. from google.appengine.api import users
  7. from google.appengine.ext.webapp.util import run_wsgi_app
  8. from google.appengine.ext import db
  9. class AchievementSource(db.Model):
  10. name = db.StringProperty()
  11. url = db.LinkProperty()
  12. created_by = db.SelfReferenceProperty(default=None)
  13. class UserAccount(db.Model):
  14. user = db.UserProperty()
  15. source = db.ReferenceProperty(reference_class=AchievementSource)
  16. credentials = db.StringProperty()
  17. added = db.DateTimeProperty(auto_now_add=True)
  18. updated = db.DateTimeProperty()
  19. class Achievement(db.Model):
  20. name = db.StringProperty()
  21. image = db.LinkProperty()
  22. description = db.StringProperty()
  23. source = db.ReferenceProperty(reference_class=AchievementSource)
  24. class AwardedAchievement(db.Model):
  25. achievement = db.ReferenceProperty(reference_class=Achievement)
  26. user = db.UserProperty()
  27. awarded = db.DateTimeProperty()
  28. discovered = db.DateTimeProperty(auto_now_add=True)
  29. class MainPage(webapp.RequestHandler):
  30. def get(self):
  31. user = users.get_current_user()
  32. if not user:
  33. self.redirect(users.create_login_url(self.request.uri))
  34. return
  35. template_values = {
  36. 'is_admin': users.is_current_user_admin(),
  37. 'sources': AchievementSource.all().filter('created_by = ', None),
  38. 'accounts': UserAccount.gql("WHERE user = :user", user=user),
  39. 'achievements': AwardedAchievement.all().filter('user = ', user)
  40. .order('-awarded')
  41. }
  42. path = os.path.join(os.path.dirname(__file__), 'index.html')
  43. self.response.out.write(template.render(path, template_values))
  44. class AddSourcePage(webapp.RequestHandler):
  45. def post(self):
  46. if not users.is_current_user_admin():
  47. self.error(403)
  48. return
  49. source = AchievementSource(name=self.request.get('name'),
  50. url=self.request.get('url'))
  51. source.put()
  52. self.redirect('/')
  53. class AddAccountPage(webapp.RequestHandler):
  54. def post(self):
  55. if not users.get_current_user():
  56. self.error(403)
  57. return
  58. source = db.get(db.Key(self.request.get('type')))
  59. account = UserAccount(user=users.get_current_user(),
  60. source=source,
  61. credentials=self.request.get('credentials'))
  62. account.put()
  63. self.redirect('/')
  64. class DeleteAccountPage(webapp.RequestHandler):
  65. def post(self):
  66. if not users.get_current_user():
  67. self.error(403)
  68. return
  69. account = db.get(db.Key(self.request.get('key')))
  70. if account.user != users.get_current_user() and not users.is_current_user_admin():
  71. logging.warning("Account deletion attempted by :u1 for account owned by :u2",
  72. u1 = users.get_current_user(), u2 = account.user)
  73. self.error(403)
  74. return
  75. account.delete()
  76. self.redirect('/')
  77. class UpdatePage(webapp.RequestHandler):
  78. def post(self):
  79. account = db.get(db.Key(self.request.get('key')))
  80. if account.source.name == 'Spore':
  81. UpdatePage.merge_achievements(account, Scraper.scrape_spore(account.credentials))
  82. elif account.source.name == 'Steam':
  83. UpdatePage.merge_sources(account, Scraper.scrape_steam(account.credentials))
  84. elif account.source.created_by != None and account.source.created_by.name == 'Steam':
  85. UpdatePage.merge_achievements(account, Scraper.scrape_steam_game(account.credentials, account.source.url))
  86. self.redirect('/')
  87. @staticmethod
  88. def merge_sources(account, sources):
  89. for user_source in sources:
  90. UpdatePage.get_or_create_source(user_source, account)
  91. @staticmethod
  92. def merge_achievements(account, achievements):
  93. for awarded in achievements:
  94. achievement = UpdatePage.get_achievement(account.source, awarded)
  95. res = AwardedAchievement.gql("WHERE achievement = :ac AND user = :user",
  96. ac=achievement,
  97. user=account.user)
  98. if res.count(1) == 0:
  99. AwardedAchievement(achievement=achievement,
  100. user=account.user,
  101. awarded=awarded['date']).put()
  102. @staticmethod
  103. def get_achievement(source, achievement):
  104. res = Achievement.gql("WHERE name = :name AND source = :source",
  105. name=achievement['title'],
  106. source=source)
  107. if res.count(1) == 0:
  108. res = Achievement(name=achievement['title'],
  109. image=achievement['img'],
  110. description=achievement['desc'],
  111. source=source)
  112. res.put()
  113. else:
  114. res = res.get()
  115. return res
  116. @staticmethod
  117. def get_or_create_source(source_info, account):
  118. source = AchievementSource.gql("WHERE name = :name", name=source_info['name'])
  119. if source.count(1) == 0:
  120. source = AchievementSource(name = source_info['name'],
  121. url = source_info['url'],
  122. created_by = account.source)
  123. source.put()
  124. else:
  125. source = source.get()
  126. res = UserAccount.gql("WHERE source = :source AND user = :user AND "
  127. + "credentials = :creds", source = source,
  128. user = account.user,
  129. creds = account.credentials)
  130. if res.count(1) == 0:
  131. res = UserAccount(user = account.user,
  132. source = source,
  133. credentials = account.credentials)
  134. res.put()
  135. else:
  136. res = res.get()
  137. return res
  138. application = webapp.WSGIApplication([('/', MainPage),
  139. ('/admin/source/add', AddSourcePage),
  140. ('/worker/update', UpdatePage),
  141. ('/account/add', AddAccountPage),
  142. ('/account/delete', DeleteAccountPage)],
  143. debug=True)
  144. def main():
  145. run_wsgi_app(application)
  146. if __name__ == "__main__":
  147. main()