Incomplete webapp to aggregate achievements/badges from various sources
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

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()