A web framework for aspiring media terrorists – PRE-ALPHA – DO NOT DEPLOY!
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.

example.py 6.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. #!/usr/bin/env python
  2. import math
  3. import random
  4. import json
  5. import requests
  6. import datetime
  7. import flask
  8. import poobrains
  9. from flask import redirect
  10. app = poobrains.app
  11. @app.route('/')
  12. def front():
  13. return redirect(News.url())
  14. class TestSubForm(poobrains.form.Fieldset):
  15. oink = poobrains.form.fields.Text(label="OMGWTF")
  16. foo = poobrains.form.fields.Text(label="SUBfoo")
  17. submit = poobrains.form.Button('submit', label="SUBSUBMIT")
  18. @app.expose('/form')
  19. class TestForm(poobrains.form.Form):
  20. foo = poobrains.form.fields.Text()
  21. bar = TestSubForm()
  22. optin = poobrains.form.fields.Checkbox(label="Opt-in", default=False, required=True, choices=[(True, None)])
  23. radio = poobrains.form.fields.Radio(type=poobrains.form.types.INT, choices=[(1, 'One'), (5, 'Five'), (23, 'Twentythree'), (42, 'Fortytwo')])
  24. multicheck = poobrains.form.fields.Checkbox(label="Check 'em", type=poobrains.form.types.STRING, choices=[('dubs', 'dubs'), ('trips', 'TRIPS'), ('quads', 'QUADS!1!!!!')], multi=True)
  25. completeme = poobrains.form.fields.Text(label="Lookit me, I can autocomplete without JS!", choices=[('Mr. Foo', 'foo'), ('Mr. Florb', 'florb'), ('Ms. Bar', 'bar')])
  26. ranged = poobrains.form.fields.Range()
  27. trigger = poobrains.form.Button('submit', label='Hit me!')
  28. def process(self, submit):
  29. flask.flash('TestForm.process called!')
  30. return self
  31. @app.expose('/news', mode='full')
  32. class News(poobrains.commenting.Commentable):
  33. """ This is the news class docstring """
  34. class Meta:
  35. search_fields = ['title', 'name', 'text']
  36. title = poobrains.storage.fields.CharField()
  37. text = poobrains.md.MarkdownField()
  38. @app.expose('/paste', mode='full', title='Copypasta')
  39. class Paste(poobrains.tagging.Taggable):
  40. type = poobrains.storage.fields.CharField()
  41. text = poobrains.storage.fields.TextField()
  42. @app.site.box('menu_main')
  43. def menu_main():
  44. menu = poobrains.rendering.Menu('main')
  45. try:
  46. News.permissions['read'].check(flask.g.user)
  47. menu.append(News.url(), 'News')
  48. except poobrains.auth.AccessDenied:
  49. pass
  50. try:
  51. Paste.permissions['read'].check(flask.g.user)
  52. menu.append(Paste.url(), 'Pastes')
  53. except poobrains.auth.AccessDenied:
  54. pass
  55. for url, caption in poobrains.auth.Page.main_menu_entries():
  56. menu.append(url, caption)
  57. return menu
  58. class NonExposed(poobrains.auth.Administerable):
  59. text = poobrains.storage.fields.TextField()
  60. class NonExposedB(NonExposed):
  61. pass
  62. class AVeryVeryLongNameToTestMenuPositioning(poobrains.auth.Administerable):
  63. florp = poobrains.storage.fields.BooleanField()
  64. #class MultiPK(poobrains.auth.Administerable):
  65. #
  66. # class Meta:
  67. # primary_key = peewee.CompositeKey('pk_a', 'pk_b')
  68. #
  69. # pk_a = poobrains.storage.fields.IntegerField()
  70. # pk_b = poobrains.storage.fields.IntegerField()
  71. #
  72. #
  73. #class NestedHandle(poobrains.auth.Administerable):
  74. #
  75. # class Meta:
  76. # primary_key = peewee.CompositeKey('foreign', 'local')
  77. #
  78. # foreign = poobrains.storage.fields.ForeignKeyField(MultiPK)
  79. # local = poobrains.storage.fields.CharField()
  80. @app.site.listing(NonExposedB, '/custom', mode='full', title='Custom Listing')
  81. def list_nonexposed(listing):
  82. return listing
  83. class NASAApproaches(poobrains.svg.plot.Dataset):
  84. def fill(self, spkid=2099942): # default spkid for apophis
  85. try:
  86. spkid = int(spkid)
  87. except ValueError:
  88. raise poobrains.errors.ValidationError("Invalid SPK ID; must be an integer.")
  89. response = requests.get('https://api.nasa.gov/neo/rest/v1/neo/%d?api_key=DEMO_KEY' % spkid)
  90. if response.status_code != 200:
  91. raise poobrains.errors.ValidationError("NASA API responded with error code %d." % response.status_code)
  92. data = json.loads(response.text)
  93. self.title = "Close approaches of %s" % (data['name_limited'] if 'name_limited' in data else data['name'])
  94. self.description = "**%s** belongs to orbit class **%s**; %s" % (data['name'], data['orbital_data']['orbit_class']['orbit_class_type'], data['orbital_data']['orbit_class']['orbit_class_description'])
  95. for approach in data['close_approach_data']:
  96. x = float(approach['epoch_date_close_approach'])
  97. y = float(approach['miss_distance']['kilometers'])
  98. self.add_datapoint(x, y)
  99. class StockWeekly(poobrains.svg.plot.Dataset):
  100. def fill(self, symbol='FB'):
  101. response = requests.get('https://www.alphavantage.co/query?function=TIME_SERIES_WEEKLY&symbol=%s&apikey=%s' % (symbol, app.config['ALPHAVANTAGE_API_KEY']))
  102. if response.status_code != 200:
  103. raise poobrains.errors.ValidationError("AlphaVantage API responded with error code %d." % response.status_code)
  104. data = json.loads(response.text)
  105. dates = [x for x in data['Weekly Time Series'].keys()]
  106. first_date = dates[-1]
  107. last_date = dates[0]
  108. self.title = symbol
  109. self.description = f"Data from {first_date} to {last_date}"
  110. for datestring, datapoint in data['Weekly Time Series'].items():
  111. y, m, d = [int(x) for x in datestring.split('-')]
  112. date = datetime.datetime(y, m, d)
  113. x = date.timestamp()
  114. y = float(datapoint['1. open']) + float(datapoint['4. close']) / 2
  115. error_lower = y - float(datapoint['3. low'])
  116. error_upper = y - float(datapoint['2. high'])
  117. self.add_datapoint(x, y, error_lower=error_lower, error_upper=error_upper)
  118. class ConstrainedRandom(poobrains.svg.plot.Dataset):
  119. def fill(self, magnitude=2, length=16):
  120. magnitude, length = int(magnitude), int(length)
  121. ranges = []
  122. for i in range(0, magnitude):
  123. ranges.append(sorted((random.random(), random.random())))
  124. for i in range(0, length):
  125. y = random.random()
  126. for r in ranges:
  127. y = r[0] + (r[1] - r[0]) * y
  128. r = ranges[round((len(ranges) - 1) * random.random())] # select random range
  129. y = r[0] + (r[1] - r[0]) * y
  130. #y %= (i + 1)
  131. #y = i % y
  132. y *= math.sin(2 * math.pi * float(i) / length)
  133. self.add_datapoint(i, y) #, error_lower=y - r[0], error_upper=r[1] - y)
  134. class RandomMap(poobrains.svg.geo.GeoData):
  135. def fill(self):
  136. data = poobrains.svg.geo.geojson.MultiPolygon()
  137. for poly_num in range(0, random.randrange(1, 8)):
  138. points = []
  139. for point_num in range(0, random.randrange(3, 7)):
  140. points.append((random.randrange(-180, 181),random.randrange(-75, 76)))
  141. data.coordinates.append([points])
  142. self.data = poobrains.svg.geo.geojson.dumps(data)
  143. if __name__ == '__main__':
  144. #app.run()
  145. poobrains.app.main()