2015-07-09 14:25:53 +00:00
#!/usr/bin/env python
2019-02-20 01:19:28 +00:00
import math
2019-03-06 00:19:33 +00:00
import random
2019-02-20 01:19:28 +00:00
import json
import requests
2019-02-22 00:04:29 +00:00
import datetime
2015-10-15 04:16:28 +00:00
import flask
2019-09-25 19:09:01 +00:00
import numpy
2015-10-15 04:16:28 +00:00
import poobrains
2015-06-01 03:35:15 +00:00
from flask import redirect
2016-05-16 16:22:18 +00:00
2015-06-01 03:35:15 +00:00
2015-10-23 07:39:40 +00:00
app = poobrains . app
2016-05-06 14:10:00 +00:00
2015-06-06 05:46:18 +00:00
@app.route ( ' / ' )
2015-06-01 03:35:15 +00:00
def front ( ) :
return redirect ( News . url ( ) )
2015-10-15 04:16:28 +00:00
class TestSubForm ( poobrains . form . Fieldset ) :
oink = poobrains . form . fields . Text ( label = " OMGWTF " )
foo = poobrains . form . fields . Text ( label = " SUBfoo " )
submit = poobrains . form . Button ( ' submit ' , label = " SUBSUBMIT " )
2016-09-12 18:00:11 +00:00
@app.expose ( ' /form ' )
2015-10-15 04:16:28 +00:00
class TestForm ( poobrains . form . Form ) :
foo = poobrains . form . fields . Text ( )
bar = TestSubForm ( )
2020-08-04 14:03:15 +00:00
optin = poobrains . form . fields . Checkbox ( label = " Opt-in " , default = False , required = True )
2017-10-20 01:49:57 +00:00
radio = poobrains . form . fields . Radio ( type = poobrains . form . types . INT , choices = [ ( 1 , ' One ' ) , ( 5 , ' Five ' ) , ( 23 , ' Twentythree ' ) , ( 42 , ' Fortytwo ' ) ] )
2017-10-18 19:13:25 +00:00
multicheck = poobrains . form . fields . Checkbox ( label = " Check ' em " , type = poobrains . form . types . STRING , choices = [ ( ' dubs ' , ' dubs ' ) , ( ' trips ' , ' TRIPS ' ) , ( ' quads ' , ' QUADS!1!!!! ' ) ] , multi = True )
2017-10-17 00:58:54 +00:00
completeme = poobrains . form . fields . Text ( label = " Lookit me, I can autocomplete without JS! " , choices = [ ( ' Mr. Foo ' , ' foo ' ) , ( ' Mr. Florb ' , ' florb ' ) , ( ' Ms. Bar ' , ' bar ' ) ] )
2017-10-20 01:49:57 +00:00
ranged = poobrains . form . fields . Range ( )
2015-10-15 04:16:28 +00:00
trigger = poobrains . form . Button ( ' submit ' , label = ' Hit me! ' )
2020-08-04 14:03:15 +00:00
fail = poobrains . form . Button ( ' submit ' , label = ' Fail ' )
def validate ( self , submit ) :
e = poobrains . errors . CompoundError ( )
if submit == ' fail ' :
e . append ( poobrains . errors . ValidationError ( " FAIL! " , self [ ' foo ' ] ) )
if len ( e ) :
raise e
2015-10-15 04:16:28 +00:00
2017-10-18 19:13:25 +00:00
def process ( self , submit ) :
2017-08-09 18:34:50 +00:00
flask . flash ( ' TestForm.process called! ' )
2016-09-12 18:00:11 +00:00
return self
2015-10-15 04:16:28 +00:00
2016-06-12 10:34:10 +00:00
@app.expose ( ' /news ' , mode = ' full ' )
2017-01-19 22:25:57 +00:00
class News ( poobrains . commenting . Commentable ) :
2015-06-01 03:35:15 +00:00
2021-03-19 09:21:43 +00:00
"""
A * news article * .
Has a nice human - readable title and markdown - enabled text .
Also , here ' s a random list of things to test markdown in class docstrings:
* Jane Fondas Legwarmers
* Gary Buseys Glass - eye
* Peter Thiels head on a pike
"""
2017-03-26 13:55:56 +00:00
2017-08-04 06:24:28 +00:00
class Meta :
search_fields = [ ' title ' , ' name ' , ' text ' ]
2016-06-01 05:30:05 +00:00
title = poobrains . storage . fields . CharField ( )
2017-04-07 07:35:04 +00:00
text = poobrains . md . MarkdownField ( )
2015-06-01 03:35:15 +00:00
2016-06-12 10:34:10 +00:00
@app.expose ( ' /paste ' , mode = ' full ' , title = ' Copypasta ' )
2016-12-18 23:54:03 +00:00
class Paste ( poobrains . tagging . Taggable ) :
2015-06-01 03:35:15 +00:00
2015-10-27 04:43:03 +00:00
type = poobrains . storage . fields . CharField ( )
text = poobrains . storage . fields . TextField ( )
2015-06-01 03:35:15 +00:00
2015-07-06 03:55:34 +00:00
@app.site.box ( ' menu_main ' )
2015-06-01 03:35:15 +00:00
def menu_main ( ) :
2015-10-27 04:43:03 +00:00
menu = poobrains . rendering . Menu ( ' main ' )
2017-03-21 05:58:54 +00:00
try :
News . permissions [ ' read ' ] . check ( flask . g . user )
menu . append ( News . url ( ) , ' News ' )
except poobrains . auth . AccessDenied :
pass
try :
Paste . permissions [ ' read ' ] . check ( flask . g . user )
menu . append ( Paste . url ( ) , ' Pastes ' )
except poobrains . auth . AccessDenied :
pass
2015-06-01 03:35:15 +00:00
2019-06-21 17:05:53 +00:00
for url , caption in poobrains . auth . Page . main_menu_entries ( ) :
menu . append ( url , caption )
2015-06-01 03:35:15 +00:00
return menu
2016-05-16 16:22:18 +00:00
class NonExposed ( poobrains . auth . Administerable ) :
2015-06-08 13:26:42 +00:00
2015-10-27 04:43:03 +00:00
text = poobrains . storage . fields . TextField ( )
2015-06-08 13:26:42 +00:00
class NonExposedB ( NonExposed ) :
pass
2017-03-16 22:56:38 +00:00
class AVeryVeryLongNameToTestMenuPositioning ( poobrains . auth . Administerable ) :
2018-05-07 14:07:08 +00:00
florp = poobrains . storage . fields . BooleanField ( )
2015-06-08 13:26:42 +00:00
2016-12-08 08:57:23 +00:00
#class MultiPK(poobrains.auth.Administerable):
#
# class Meta:
# primary_key = peewee.CompositeKey('pk_a', 'pk_b')
#
# pk_a = poobrains.storage.fields.IntegerField()
# pk_b = poobrains.storage.fields.IntegerField()
#
#
#class NestedHandle(poobrains.auth.Administerable):
#
# class Meta:
# primary_key = peewee.CompositeKey('foreign', 'local')
#
# foreign = poobrains.storage.fields.ForeignKeyField(MultiPK)
# local = poobrains.storage.fields.CharField()
2015-06-08 23:39:42 +00:00
@app.site.listing ( NonExposedB , ' /custom ' , mode = ' full ' , title = ' Custom Listing ' )
2015-06-08 13:26:42 +00:00
def list_nonexposed ( listing ) :
return listing
2020-06-29 08:03:34 +00:00
class NEO_Approaches ( poobrains . analysis . EphemeralDataset ) :
2019-02-20 01:19:28 +00:00
2020-06-29 08:03:34 +00:00
title = ' NASA Near Earth Orbits '
@classmethod
def load ( cls , spkid : int = 2099942 ) : # default spkid for apophis
try :
spkid = int ( spkid )
except ValueError :
raise poobrains . errors . ValidationError ( " Invalid SPK ID; must be an integer. " )
response = requests . get ( ' https://api.nasa.gov/neo/rest/v1/neo/ %d ?api_key=DEMO_KEY ' % spkid )
if response . status_code != 200 :
raise poobrains . errors . ValidationError ( " NASA API responded with error code %d . " % response . status_code )
data = json . loads ( response . text )
ds = cls ( )
ds . title = " Close approaches of %s " % ( data [ ' name_limited ' ] if ' name_limited ' in data else data [ ' name ' ] )
ds . 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 ' ] )
ds . plot_data = {
2020-07-17 14:09:39 +00:00
' kind ' : ' LinePlot ' ,
2020-06-29 08:03:34 +00:00
' layers ' : {
' approaches ' : {
' x ' : ' time ' ,
' y ' : ' distance '
}
}
}
ds [ ' time ' ] = {
' title ' : ' Time ' ,
2021-03-16 05:11:48 +00:00
' description ' : ' Time of close approach ' ,
2020-06-29 08:03:34 +00:00
' dtype ' : ' datetime64 ' ,
' color ' : None ,
' observations ' : { } ,
}
2019-02-20 01:19:28 +00:00
2020-06-29 08:03:34 +00:00
ds [ ' distance ' ] = {
' title ' : ' Distance (km) ' ,
2021-03-16 05:11:48 +00:00
' description ' : ' Distance of close approach ' ,
2020-06-29 08:03:34 +00:00
' dtype ' : ' float64 ' ,
' color ' : None ,
' observations ' : { } ,
}
2019-11-11 23:17:51 +00:00
2020-06-29 08:03:34 +00:00
for index , observation in enumerate ( data [ ' close_approach_data ' ] ) :
2019-02-20 01:19:28 +00:00
2021-03-16 05:11:48 +00:00
observation_time = numpy . datetime64 ( datetime . datetime . fromtimestamp ( observation [ ' epoch_date_close_approach ' ] / 1000 ) )
observation_distance = numpy . float64 ( observation [ ' miss_distance ' ] [ ' kilometers ' ] )
2019-11-11 23:17:51 +00:00
2020-07-09 18:25:56 +00:00
ds [ ' time ' ] [ ' observations ' ] [ index ] = observation_time
ds [ ' distance ' ] [ ' observations ' ] [ index ] = observation_distance
2019-02-20 01:19:28 +00:00
2020-06-29 08:03:34 +00:00
return ds
2019-02-20 01:19:28 +00:00
2019-02-22 00:04:29 +00:00
2020-06-29 08:03:34 +00:00
class Stock_Weekly ( poobrains . analysis . EphemeralDataset ) :
2019-02-22 00:04:29 +00:00
2020-06-29 08:03:34 +00:00
title = ' Stock (weekly) '
2019-02-22 00:04:29 +00:00
2020-06-29 08:03:34 +00:00
@classmethod
def load ( cls , symbol = ' FB ' ) :
2019-02-22 00:04:29 +00:00
2020-06-29 08:03:34 +00:00
response = requests . get ( ' https://www.alphavantage.co/query?function=TIME_SERIES_WEEKLY&symbol= %s &apikey= %s ' % ( symbol , app . config [ ' ALPHAVANTAGE_API_KEY ' ] ) )
2019-02-22 00:04:29 +00:00
2020-06-29 08:03:34 +00:00
if response . status_code != 200 :
raise poobrains . errors . ValidationError ( " AlphaVantage API responded with error code %d . " % response . status_code )
2019-02-22 00:04:29 +00:00
2020-06-29 08:03:34 +00:00
data = json . loads ( response . text )
2019-02-22 00:04:29 +00:00
2020-06-29 08:03:34 +00:00
dates = [ x for x in data [ ' Weekly Time Series ' ] . keys ( ) ]
first_date = dates [ - 1 ]
last_date = dates [ 0 ]
2019-02-22 00:04:29 +00:00
2020-06-29 08:03:34 +00:00
ds = cls ( )
ds . title = symbol
ds . description = f " Data for stock symbol ** { symbol } ** from * { first_date } * to * { last_date } *. "
2019-02-22 00:04:29 +00:00
2020-06-29 08:03:34 +00:00
ds . plot_data = {
2020-07-17 14:09:39 +00:00
' kind ' : ' LinePlot ' ,
2020-06-29 08:03:34 +00:00
' layers ' : {
symbol : {
' x ' : ' time ' ,
' y ' : ' price '
}
}
}
2019-11-11 23:17:51 +00:00
2020-06-29 08:03:34 +00:00
ds [ ' time ' ] = {
' title ' : ' Time ' ,
' description ' : f " Data for stock symbol ** { symbol } ** from * { first_date } * to * { last_date } *. " ,
2021-03-16 05:11:48 +00:00
' dtype ' : ' datetime64 ' ,
2020-06-29 08:03:34 +00:00
' color ' : None ,
' observations ' : { }
}
2019-11-11 23:17:51 +00:00
2020-06-29 08:03:34 +00:00
ds [ ' price ' ] = {
' title ' : ' Price ($) ' ,
' description ' : f " Data for stock symbol ** { symbol } ** from * { first_date } * to * { last_date } *. " ,
' dtype ' : ' float64 ' ,
' color ' : None ,
' observations ' : { }
}
2019-03-06 00:19:33 +00:00
2020-06-29 08:03:34 +00:00
for index , ( datestring , datapoint ) in enumerate ( data [ ' Weekly Time Series ' ] . items ( ) ) :
2019-03-06 00:19:33 +00:00
2020-06-29 08:03:34 +00:00
y , m , d = [ int ( x ) for x in datestring . split ( ' - ' ) ]
date = datetime . datetime ( y , m , d )
2019-03-06 00:19:33 +00:00
2021-03-16 05:11:48 +00:00
ds [ ' time ' ] [ ' observations ' ] [ index ] = numpy . datetime64 ( date )
ds [ ' price ' ] [ ' observations ' ] [ index ] = numpy . float64 ( datapoint [ ' 4. close ' ] )
2020-06-29 08:03:34 +00:00
#error_lower = y - float(datapoint['3. low'])
#error_upper = y - float(datapoint['2. high'])
return ds
class ConstrainedRandom ( poobrains . analysis . EphemeralDataset ) :
title = ' Constrained random '
2019-11-16 22:46:04 +00:00
2020-06-29 08:03:34 +00:00
@classmethod
def load ( cls , magnitude : int = 2 , length : int = 16 ) :
2019-03-06 00:19:33 +00:00
2020-06-29 08:03:34 +00:00
magnitude , length = int ( magnitude ) , int ( length )
2019-03-06 00:19:33 +00:00
2020-06-29 08:03:34 +00:00
ranges = [ ]
for i in range ( 0 , magnitude ) :
ranges . append ( sorted ( ( random . random ( ) , random . random ( ) ) ) )
2020-05-18 21:06:15 +00:00
2020-06-29 08:03:34 +00:00
ds = cls ( )
ds . title = f " Constrained random ( { magnitude } , { length } ) "
ds . description = f " ConstrainedRandom of magnitude { magnitude } and length { length } . "
2019-03-06 00:19:33 +00:00
2020-06-29 08:03:34 +00:00
ds . plot_data = {
2020-07-17 14:09:39 +00:00
' kind ' : ' LinePlot ' ,
2020-06-29 08:03:34 +00:00
' layers ' : {
' plot ' : {
' x ' : ' x ' ,
' y ' : ' y '
}
}
}
2019-03-06 00:19:33 +00:00
2020-06-29 08:03:34 +00:00
ds [ ' x ' ] = {
' title ' : " X " ,
' description ' : " Equidistant steps for X-axis. " ,
' dtype ' : ' int64 ' ,
' color ' : None ,
' observations ' : { } ,
}
ds [ ' y ' ] = {
' title ' : " Y " ,
' description ' : " Random values for Y-axis. " ,
' dtype ' : ' float64 ' ,
' color ' : None ,
' observations ' : { } ,
}
for index , x in enumerate ( range ( 0 , length ) ) :
y = random . random ( )
for r in ranges :
y = r [ 0 ] + ( r [ 1 ] - r [ 0 ] ) * y
r = ranges [ round ( ( len ( ranges ) - 1 ) * random . random ( ) ) ] # select random range
2019-03-06 00:19:33 +00:00
y = r [ 0 ] + ( r [ 1 ] - r [ 0 ] ) * y
2020-06-29 08:03:34 +00:00
y * = math . sin ( 2 * math . pi * float ( i ) / length )
2021-03-16 05:11:48 +00:00
ds [ ' x ' ] [ ' observations ' ] [ index ] = numpy . int64 ( x )
ds [ ' y ' ] [ ' observations ' ] [ index ] = numpy . float64 ( y )
2020-06-29 08:03:34 +00:00
return ds
2019-09-25 19:09:01 +00:00
2020-06-29 08:03:34 +00:00
class Sine ( poobrains . analysis . EphemeralDataset ) :
2019-09-25 19:09:01 +00:00
2020-06-29 08:03:34 +00:00
title = ' Sine '
2019-02-22 00:04:29 +00:00
2020-06-29 08:03:34 +00:00
@classmethod
def load ( cls , length : int = 10 ) :
2019-02-22 20:23:07 +00:00
2020-06-29 08:03:34 +00:00
ds = cls ( )
ds . title = f " Sine ( { length } ) "
ds . description = f " A full sine wave out of { length } points. "
ds . plot_data = {
2020-07-17 14:09:39 +00:00
' kind ' : ' LinePlot ' ,
2020-06-29 08:03:34 +00:00
' layers ' : {
' plot ' : {
' x ' : ' x ' ,
' y ' : ' y '
}
}
}
2020-05-14 09:26:30 +00:00
2020-06-29 08:03:34 +00:00
inc = ( 2 * math . pi ) / ( length - 1 )
2020-05-14 09:26:30 +00:00
2020-06-29 08:03:34 +00:00
ds [ ' x ' ] = {
' title ' : " X " ,
' description ' : f " x for `sin(x)`; spaced at equidistance intervals of { inc } . " ,
' dtype ' : ' float64 ' ,
' color ' : None ,
' observations ' : { }
}
2020-05-14 09:26:30 +00:00
2020-06-29 08:03:34 +00:00
ds [ ' y ' ] = {
' title ' : " Y " ,
' description ' : " Result of `sin(x)` " ,
' dtype ' : ' float64 ' ,
' color ' : None ,
' observations ' : { }
}
2020-05-14 09:26:30 +00:00
2020-06-29 08:03:34 +00:00
x = 0
for index in range ( 0 , length ) :
2021-03-16 05:11:48 +00:00
ds [ ' x ' ] [ ' observations ' ] [ index ] = numpy . float64 ( x )
ds [ ' y ' ] [ ' observations ' ] [ index ] = numpy . float64 ( math . sin ( x ) )
2020-06-29 08:03:34 +00:00
x + = inc
return ds
2020-05-14 09:26:30 +00:00
2020-07-10 12:27:53 +00:00
#class RandomMap(poobrains.analysis.geo.EphemeralGeoData):
#
# @classmethod
# def load(cls):
#
# ds = cls()
#
# data = poobrains.analysis.geo.geojson.MultiPolygon()
#
# for poly_num in range(0, random.randrange(1, 8)):
#
# points = []
#
# for point_num in range(0, random.randrange(3, 7)):
# points.append((random.randrange(-180, 181),random.randrange(-75, 76)))
#
# data.coordinates.append([points])
#
# ds.data = poobrains.analysis.geo.geojson.dumps(data)
#
# return ds
2019-03-06 02:48:47 +00:00
2015-06-01 03:35:15 +00:00
if __name__ == ' __main__ ' :
2017-07-08 00:45:14 +00:00
#app.run()
2018-11-23 03:46:10 +00:00
poobrains . app . main ( )