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.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  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. return menu
  56. class NonExposed(poobrains.auth.Administerable):
  57. text = poobrains.storage.fields.TextField()
  58. class NonExposedB(NonExposed):
  59. pass
  60. class AVeryVeryLongNameToTestMenuPositioning(poobrains.auth.Administerable):
  61. florp = poobrains.storage.fields.BooleanField()
  62. #class MultiPK(poobrains.auth.Administerable):
  63. #
  64. # class Meta:
  65. # primary_key = peewee.CompositeKey('pk_a', 'pk_b')
  66. #
  67. # pk_a = poobrains.storage.fields.IntegerField()
  68. # pk_b = poobrains.storage.fields.IntegerField()
  69. #
  70. #
  71. #class NestedHandle(poobrains.auth.Administerable):
  72. #
  73. # class Meta:
  74. # primary_key = peewee.CompositeKey('foreign', 'local')
  75. #
  76. # foreign = poobrains.storage.fields.ForeignKeyField(MultiPK)
  77. # local = poobrains.storage.fields.CharField()
  78. @app.site.listing(NonExposedB, '/custom', mode='full', title='Custom Listing')
  79. def list_nonexposed(listing):
  80. return listing
  81. class NASAApproaches(poobrains.svg.plot.Dataset):
  82. def fill(self, spkid):
  83. try:
  84. spkid = int(spkid)
  85. except ValueError:
  86. raise poobrains.errors.ValidationError("Invalid SPK ID; must be an integer.")
  87. response = requests.get('https://api.nasa.gov/neo/rest/v1/neo/%d?api_key=DEMO_KEY' % spkid)
  88. if response.status_code != 200:
  89. raise poobrains.errors.ValidationError("NASA API responded with error code %d." % response.status_code)
  90. data = json.loads(response.text)
  91. self.title = "Close approaches of %s" % (data['name_limited'] if 'name_limited' in data else data['name'])
  92. 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'])
  93. for approach in data['close_approach_data']:
  94. x = float(approach['epoch_date_close_approach'])
  95. y = float(approach['miss_distance']['kilometers'])
  96. self.add_datapoint(x, y)
  97. class StockWeekly(poobrains.svg.plot.Dataset):
  98. def fill(self, symbol='FB'):
  99. response = requests.get('https://www.alphavantage.co/query?function=TIME_SERIES_WEEKLY&symbol=%s&apikey=%s' % (symbol, app.config['ALPHAVANTAGE_API_KEY']))
  100. if response.status_code != 200:
  101. raise poobrains.errors.ValidationError("AlphaVantage API responded with error code %d." % response.status_code)
  102. data = json.loads(response.text)
  103. dates = [x for x in data['Weekly Time Series'].keys()]
  104. first_date = dates[-1]
  105. last_date = dates[0]
  106. self.title = symbol
  107. self.description = f"Data from {first_date} to {last_date}"
  108. for datestring, datapoint in data['Weekly Time Series'].items():
  109. y, m, d = [int(x) for x in datestring.split('-')]
  110. date = datetime.datetime(y, m, d)
  111. x = date.timestamp()
  112. y = float(datapoint['1. open']) + float(datapoint['4. close']) / 2
  113. error_lower = y - float(datapoint['3. low'])
  114. error_upper = y - float(datapoint['2. high'])
  115. self.add_datapoint(x, y, error_lower=error_lower, error_upper=error_upper)
  116. class ConstrainedRandom(poobrains.svg.plot.Dataset):
  117. def fill(self, magnitude=2, length=16):
  118. magnitude, length = int(magnitude), int(length)
  119. ranges = []
  120. for i in range(0, magnitude):
  121. ranges.append(sorted((random.random(), random.random())))
  122. for i in range(0, length):
  123. y = random.random()
  124. for r in ranges:
  125. y = r[0] + (r[1] - r[0]) * y
  126. r = ranges[round((len(ranges) - 1) * random.random())] # select random range
  127. y = r[0] + (r[1] - r[0]) * y
  128. #y %= (i + 1)
  129. #y = i % y
  130. y *= math.sin(2 * math.pi * float(i) / length)
  131. self.add_datapoint(i, y) #, error_lower=y - r[0], error_upper=r[1] - y)
  132. class RandomMap(poobrains.svg.geo.GeoData):
  133. def fill(self):
  134. data = poobrains.svg.geo.geojson.MultiPolygon()
  135. for poly_num in range(0, random.randrange(1, 8)):
  136. points = []
  137. for point_num in range(0, random.randrange(3, 7)):
  138. points.append((random.randrange(-180, 181),random.randrange(-75, 76)))
  139. data.coordinates.append([points])
  140. self.data = poobrains.svg.geo.geojson.dumps(data)
  141. if __name__ == '__main__':
  142. #app.run()
  143. poobrains.app.main()