a little side project by Flask(?) and bootstrap
idea from: BlockyTime - anniapp
##requirement
build a easy-using time tracking web application
- We can switch the date of recording
- Everyday was divided to \(24*2=48\) blocks, 30mins for each
- Intially, every block was filled by "Sleeping time"
- Users can choose every block, multiple choosing was supported too.
- no drag function in first version
- We can added category to blocky time
- Everyday's data will be saved on server
##UI
main page
back-end
- datebase issues on first running
- support for multiple users
front-end
- support for bad internet connection situation
- function of add category
-
- UI and UX redesign
##Devoloper notes:
- specifying the requiremnt
- initialized git repo
- Copied a templated from bootstrap
##12.23
Goal:
finish the main UI: select time, set time
Note:
Add data-toggle="button" to activate toggling on a single button
for button <label>
should be contained in <div>
, otherwise the check box will not perform correctly.
if I create a new column, this colum will be splited to 12 columns automatically.
for example, if I created a column col-xs-6
, and I want to divide this to two parts, I should create two col-xs-6
columns in that columns.
I cannot use padding or margin, so I used a placeholder div
to make the main page shift down some distance.
Avoiding the collapse of mainpage and nav bar
##12.24
Happy X'mas Eve
Learned something about REST API
some useful links:
Learn REST: A RESTful Tutorial
using MVC framework
Model: data base interacting
Controller
Viewer: rendering page,Javascript, connecting with others by REST API
funny thing
Vim for python settings:
VIM and Python - a Match Made in Heaven
get function name in Python
import sys
def foo():
print sys._getframe().f_code.co_name
jsonify a SQLAlchemy result set in Flask
we should store following data:
Primary-Category
id | Category name | color set | logo |
---|---|---|---|
0 | Sport | red | a.png |
1 | study | green | b.png |
second-Category
id|parent_id|category name | color| logo| |---|---|---|---|---|---| |0|joging|origin|jog.png|
date
id | date | last-changed-time |
---|---|---|
0 | 12-28-2016 | 01-01-2016 20:00 |
Block
|id|date_id|show_time|position|second-category-shid| |---|---|---|----|----|---| 0|2|12:30|12|3
##12.26
Added a datepicker:
uxsolutions/bootstrap-datepicker
notes:
- there a lot of useless files in downloaded package for my project. following is useful:
- bootstrap-datepicker.js
- bootstrap-datepicker.css
- I should review the knowledge of jQuery
It is better not to put lots of rows in a column..
I found a margin issue, but after cutting down the number of rows from 10+ to 1. That issue has been gone.
Weird.
##12.28
Goal: create database of backend
I obtained some class as Singleton, such initialization and datebase model.
tutorial:
Note:
python is a scriping language, actually, the codes on the first line will be executed first.
Totally different from C...
Time issue
There are some type of "Time" description in SQL
- DATE
- TIME
- DATETIME
If you set a column to "DATE", you can only write date with datetime.date(year,mon,date)
For "DATETIME", using datetime.datetime(year,mon,date,hour,minus, second)
if you want to get current time, please use time.localtime()
you will get a structure like this:
time.struct_time(tm_year=2016, tm_mon=12, tm_mday=28, tm_hour=18, tm_min=22, tm_sec=7, tm_wday=2, tm_yday=363, tm_isdst=0)
Each property of that structure is read-only.
If you want to customize a time structure, you can use time.strptime("2016-12-28 00:00:00", "%Y-%m-%d %H:%M:%S")
what is forginKey
##12.29
Goal:
finish backend programming, if possible, write api
Serialize the query result to JSON
jsonify a SQLAlchemy result set in Flask
Little tricks
is
= ==
is not
= !=
... the built-in class datetime
can also get current time
remove microsecond from `datetime.datetime.now()'
>>> import datetime
>>> now = datetime.datetime.now()
>>> print unicode(now.replace(microsecond=0))
2011-11-03 11:19:07
Python datetime to string without microsecond component
second answer
##12.30
kind of finished!
met a weird 405 http issue, at last find it is not the problem of CORS.
##01. 05
Happy new year!
Goal: To add flask manager, mutiple users
Primary-Category
uid | id | Category name | color set | logo |
---|---|---|---|---|
0 | 0 | Sport | red | a.png |
0 | 1 | study | green | b.png |
second-Category
uid|id|parent_id|category name | color| logo| |---|---|---|---|---|---|---| |0|0|joging|origin|jog.png|
date
uid | id | date | last-changed-time |
---|---|---|---|
0 | 0 | 12-28-2016 | 01-01-2016 20:00 |
Block
|uid|id|date_id|show_time|position|second-category-shid| |---|---|---|---|----|----|---| |0|0|2|12:30|12|3
users
uid | nick_name | password |
---|---|---|
1 | abc | abcdefg |
I can use User.query.get(id) to get an item of a table
get(ident)
Return an instance based on the given primary key identifier, or None if not found.
E.g.:
my_user = session.query(User).get(5)
some_object = session.query(VersionedFoo).get((5, 10))
good git repo of flask app
##03.02
UI improvement
made a static for this application.
met some issue while trying to build a horizontal bar chart.
how to make div blocks inline
- set
white-space: nowrap
anddisplay:inline
in ul - set
display:line
for li - set
display: line-block
for div important!!!
##03.03
do not use height:80%
. the better way to set presentage height is height:100%;max-height:80%
##03.05
###refining requirements
- multiple users
- User interface: login page and sign in page
- !!!Backend: re-organizing the database
- Behavior:
- Users can sign up for a new account
- Users can sign up a new account with an email
- Users can login to their account with email name & password
- Users can log out their account on setting page
- Users are able to change the password on setting page
- Users can login as a guest accout, for demo.
- users can modify categories
- UI: setting page
- Behaviors:
- Users can view all categories on setting page
- on default, all categories are marked as "no records?" or other name
- Users can remove a primary category,
- User will receive a warnning.
- if they do that, all blocks with that category turn to "no records"
- Users can add a new primary category.
- every primary category always have an item "other", which is unable to be remove
- Users are able to remove a second category
- User will receive a warnning.
- after removing, there is no influence for primary categories.
- change all blocks with the same category name to "other"
- Users can add a new second category
- About add operation:
- The user must give a valid name to a category
- The user must assign a new color to a category
- Optional: user need to add a icon for the category
- Think: what design pattern should I use in case of more requirement.
- Users can change the sequence of all categories.
- Users can change the name and color of all categories.
- data analysis and display
- UI: display page
- Behavior:
- Users can view the data in different charts:
- Optional:pie chart
- bar chart
- The sequence of bars will be adjusted according to the presentage.
- Optional:line chart
- For each type of charts, users may be able to set the scope between a day and a year
- As for data, at beginning, users will see the presentage of the primary category.
- users are able to check the detialed information of each primary category.
- Users are able to view the trend of a primary category
- Optional: Divide all primary categories into 3 parts: Positive, Neutural, Nagetive. View the trend of them.
- Users can view the data in different charts:
- Main page:
- Behavior:
- User will see a simple static of today's statics information
- User can jump to another Date to see what happened on that date.
- Users are only able to assign second category to a block
- every primary category have a default second category named "other"
- Behavior:
###Code Structure of Backend
4 Parts
- Global Initialization & Utilities
- Interface to Fontend
- Database Operation
- Data Controller
Calling flow:
Fontend ===query===> Interface ===> data Controller ===> Database
####Interface to Fontend
MAIN PAGE
#####GET: /MainPage/uid/DATE/2017-03-05
return:
- UID
- Date: 2017-03-05
- Blocks: {Block: Primary.secondCategory, Block: Primary.secondCategory.color}
- Statics: {Primary:Presentage}
#####POST: /MainPage/Date/2017-03-05/
parameter:
- UID
- Date: 2017-03-05
- Blocks: {Block: Primary.secondCategory}
return:
- user information
- new date
- blocks
Sign in page
#####POST: /SIGNIN
parameter:
- Username
- password
return:
- UID
- success
- failed or non-exist user
- redirect url
Sign up Page
#####POST: /SIGNUP
parameter:
- username
- password
return:
- UID
- success
- failed
- redirect url
Statics Page
#####GET: /StaticsPage/Day/2017-03-05?uid=UID
return:
- UID
- Date: 2017-03-05
- Statics: {Primary: presentage, primary:hours}
#####GET: /StaticsPage/Month/2017-03?uid=UID
return:
- UID
- Month: 2017-03
- Statics: {Primary: presentage, primary:hours}
#####GET: /StaticsPage/Year/2017?uid=UID
return:
- UID
- Date: 2017
- Statics: {Primary: presentage,primary: hours}
#####GET: /StaticPage/PrimaryCategory?uid=UID&&primary_category=Primary Category
return:
- UID
- Primary_category {Name, second:{second:persentage, second:hours}}
Setting Page
#####GET: /SettingPage/account?uid=UID
return:
- UID
- account name
#####POST: /SettingPage/account/changepassword
parameters
- UID
- old password
- new password
return:
- UID
- success
- failed
#####POST: /SettingPage/account/logout
parameter:
- UID
return:
- UID
- success/failed
#####GET: /CategoriesPage
return
- UID
- categories: {Primary:{second:name, id....}}
Two solutions:
- query data on every time
- query the data once, and then renew the data
#####POST: /CategoriesPage
####Data Controller
class Block
{
@properties
int block_id,
Date
PrimaryCategory Primary_category_id,
SecondCategory Second_category,
@methods
int set_second_category
}
class Date
{
@properties
int date_id
string last_change_time
Block[] blocks
@method
int generate_empty_date
}
class Category
{
@properties
int color,
int name,
@method
int set_name
int set_color
int remove_this
}
class PrimaryCategory:Category
{
@properties
int primary_id
SecondCategory[] second_categories
@method
int remove_this
SecondCategory get_child_by_id()
SecondCategory get_child_by_name()
}
class SecondCategory:Category
{
@property
int second_id
PrimaryCategory primary_category
@method
int remove_this
PrimaryCategory get_parent()
}
####Database Operation
##3.06
Ineffective all day, used a whole afternoon to fix the issue of the sqlite cannot create database on my computer.
Finally, found it is because I have a typo on database_path
:( got very depressive today..
##3.31
met some issue about how to align an element in vertical direction.
solved with using display: table
HTML
<div id="wrapper">
<div id="cell">
<div class="content">Content goes here</div>
</div>
</div>
CSS
#wrapper {
display: table;
}
#cell {
display: table-cell;
vertical-align: middle;
}