src/extras/examples/Sports_diary.py
changeset 0 ca70ae20a155
equal deleted inserted replaced
-1:000000000000 0:ca70ae20a155
       
     1 # Database example application: a sports diary.
       
     2 
       
     3 # Copyright (c) 2005 Nokia Corporation
       
     4 #
       
     5 # Licensed under the Apache License, Version 2.0 (the "License");
       
     6 # you may not use this file except in compliance with the License.
       
     7 # You may obtain a copy of the License at
       
     8 #
       
     9 #     http://www.apache.org/licenses/LICENSE-2.0
       
    10 #
       
    11 # Unless required by applicable law or agreed to in writing, software
       
    12 # distributed under the License is distributed on an "AS IS" BASIS,
       
    13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       
    14 # See the License for the specific language governing permissions and
       
    15 # limitations under the License.
       
    16 
       
    17 
       
    18 import time
       
    19 
       
    20 import e32
       
    21 import e32db
       
    22 import appuifw
       
    23 
       
    24 class SportsDiary:
       
    25     def __init__(self, db_name):
       
    26         try:
       
    27             self.native_db = e32db.Dbms()
       
    28             self.native_db.open(db_name)
       
    29         except:
       
    30             self.native_db.create(db_name)
       
    31             self.native_db.open(db_name)
       
    32             self.native_db.execute(SportsDiaryEntry.sql_create)
       
    33     
       
    34     def get_all_entries(self):
       
    35         dbv = e32db.Db_view()
       
    36         dbv.prepare(self.native_db,
       
    37                     u"SELECT * from events ORDER BY date DESC")
       
    38         dbv.first_line()
       
    39         results = []
       
    40         for i in range(dbv.count_line()):
       
    41             dbv.get_line()
       
    42             e = SportsDiaryEntry(dbv)
       
    43             results.append(e)
       
    44             dbv.next_line()
       
    45         return results
       
    46     
       
    47     def add(self, e):
       
    48         self.native_db.execute(e.sql_add())
       
    49 
       
    50     def delete(self, e):
       
    51         self.native_db.execute(e.sql_delete())
       
    52 
       
    53     def close(self):
       
    54         self.native_db.close()
       
    55 
       
    56 class SportsDiaryEntry:
       
    57     sports = [u"Running", u"Skating", u"Biking", u"Skiing", u"Swimming"]
       
    58     sql_create = u"CREATE TABLE events (date TIMESTAMP, duration FLOAT, distance FLOAT, sport INTEGER, comment VARCHAR)"
       
    59     
       
    60     # Initialize with a row from Sport_diary_db
       
    61     def __init__(self, r=None):
       
    62         if r:            
       
    63             self.timestamp  = r.col(1)
       
    64             self.duration   = r.col(2)
       
    65             self.distance   = r.col(3)
       
    66             self.sport      = r.col(4)
       
    67             self.comment    = r.col(5)
       
    68         else:
       
    69             self.timestamp  = time.time()
       
    70             self.duration   = 0.0
       
    71             self.distance   = 0.0
       
    72             self.sport      = None
       
    73             self.comment    = u""
       
    74 
       
    75     def sql_add(self):
       
    76         sql = "INSERT INTO events (date, duration, distance, sport, comment) VALUES (#%s#,%d,%d,%d,'%s')"%(
       
    77             e32db.format_time(self.timestamp),
       
    78             self.duration,
       
    79             self.distance,
       
    80             self.sport,
       
    81             self.comment)
       
    82         return unicode(sql)
       
    83     
       
    84     def sql_delete(self):
       
    85         sql = "DELETE FROM events WHERE date=#%s#"%\
       
    86               e32db.format_time(self.timestamp)
       
    87         return unicode(sql)
       
    88     
       
    89     def unixtime(self):
       
    90         return self.timestamp
       
    91     
       
    92     def get_sport_text(self):
       
    93         return self.sports[self.sport]
       
    94 
       
    95     def get_form(self):
       
    96         # Convert Unix timestamp into the form the form accepts.
       
    97         (yr, mo, da, h, m, s, wd, jd, ds) = \
       
    98              time.localtime(self.timestamp)
       
    99         m += 60*h # 60 minutes per hour
       
   100         s += 60*m # 60 seconds per minute
       
   101         result = [(u"Date", 'date', float(self.timestamp-s)),
       
   102                   (u"Time", 'time', float(s)),
       
   103                   (u"Duration", 'time', float(self.duration)),
       
   104                   (u"Distance", 'number', int(self.distance))]
       
   105         if self.sport == None:
       
   106             result.append((u"Sport", 'combo', (self.sports, 0)))
       
   107         else:
       
   108             result.append((u"Sport", 'combo', (self.sports, self.sport)))
       
   109         result.append((u"Comment", 'text', self.comment))
       
   110         return result
       
   111     
       
   112     def set_from_form(self, form):
       
   113         self.timestamp = form[0][2]+form[1][2]
       
   114         self.duration  = form[2][2]
       
   115         self.distance  = form[3][2]
       
   116         self.sport     = form[4][2][1]
       
   117         self.comment   = form[5][2]
       
   118         
       
   119 
       
   120 class SportsDiaryApp:
       
   121     def __init__(self):
       
   122         self.lock = e32.Ao_lock()
       
   123         self.exit_flag = False
       
   124         appuifw.app.exit_key_handler = self.abort
       
   125         self.main_view = appuifw.Listbox([(u"Loading...", u"")], 
       
   126                                          self.handle_view_entry)
       
   127         appuifw.app.body = self.main_view
       
   128         self.entry_list = []
       
   129         self.menu_add = (u"Add", self.handle_add)
       
   130         self.menu_summary = (u"Summary", self.handle_summary)
       
   131         self.menu_delete = (u"Delete", self.handle_delete)
       
   132         appuifw.app.menu = []
       
   133 
       
   134     def initialize_db(self, db_name):
       
   135         self.sports_diary = SportsDiary(db_name)
       
   136         
       
   137     def run(self):
       
   138         while not self.exit_flag:
       
   139             self.show_main_view()
       
   140             self.lock.wait()
       
   141         self.close()
       
   142 
       
   143     def close(self):
       
   144         appuifw.app.menu = []
       
   145         appuifw.app.body = None
       
   146         appuifw.app.exit_key_handler = None
       
   147         self.sports_diary.close()
       
   148 
       
   149     def abort(self):
       
   150         self.exit_flag = True
       
   151         self.lock.signal()
       
   152 
       
   153     def update_entry_list(self):
       
   154         self.entry_list = self.sports_diary.get_all_entries()
       
   155     
       
   156     def show_main_view(self):
       
   157         self.update_entry_list()
       
   158         if not self.entry_list:
       
   159             content = [(u"(Empty)", u"")]
       
   160         else:
       
   161             content = [(unicode(time.ctime(item.unixtime())), 
       
   162                         item.get_sport_text()) for item in self.entry_list]
       
   163 
       
   164         self.main_view.set_list(content)
       
   165 
       
   166         if not self.entry_list:
       
   167             appuifw.app.menu = [self.menu_add]
       
   168         else:
       
   169             appuifw.app.menu = [self.menu_add,
       
   170                                 self.menu_delete,
       
   171                                 self.menu_summary]
       
   172 
       
   173     def handle_add(self):
       
   174         new_entry = SportsDiaryEntry()
       
   175         data = new_entry.get_form()
       
   176         flags = appuifw.FFormEditModeOnly
       
   177         f = appuifw.Form(data, flags)
       
   178         f.execute()
       
   179         new_entry.set_from_form(f)
       
   180         self.sports_diary.add(new_entry)
       
   181         self.lock.signal()
       
   182 
       
   183     def handle_delete(self):
       
   184         if self.entry_list:
       
   185             index = self.main_view.current()
       
   186         if appuifw.query(u"Delete entry?", 'query'):
       
   187             self.sports_diary.delete(self.entry_list[index])
       
   188         self.lock.signal()
       
   189 
       
   190     def handle_summary(self):
       
   191         sum = 0
       
   192         for e in self.entry_list:
       
   193             sum += e.distance
       
   194         appuifw.note(u"Total distance is "+str(sum), 'info')
       
   195             
       
   196     def handle_view_entry(self):
       
   197         if self.entry_list:
       
   198             index = self.main_view.current()
       
   199             self.show_entry(self.entry_list[index])
       
   200         self.lock.signal()
       
   201 
       
   202     def show_entry(self, entry):
       
   203         data = entry.get_form()
       
   204         flags = appuifw.FFormViewModeOnly
       
   205         f = appuifw.Form(data, flags)
       
   206         f.execute()
       
   207 
       
   208 def main():
       
   209     app = SportsDiaryApp()
       
   210     app.initialize_db(u"c:\\SportsDiary.db")
       
   211     app.run()
       
   212 
       
   213 if __name__ == '__main__':
       
   214     old_title = appuifw.app.title
       
   215     try:
       
   216         appuifw.app.title = u"Sports diary"
       
   217         e32.ao_yield()
       
   218         main()
       
   219     finally:
       
   220         appuifw.app.title = old_title