Pārlūkot izejas kodu

merge database routines into a single script

George C. Privon 8 gadi atpakaļ
vecāks
revīzija
5db31e9b37
5 mainītis faili ar 346 papildinājumiem un 350 dzēšanām
  1. 8 0
      CHANGELOG.md
  2. 4 4
      README.md
  3. 0 202
      create_database.py
  4. 334 0
      manage_database.py
  5. 0 144
      update_database.py

+ 8 - 0
CHANGELOG.md

@@ -1,5 +1,13 @@
 # Changelog
 
+## 0.3 Series
+
+### 0.3.0 (future)
+
+#### Enhancements
+
+* new `manage_database.py` script to create and maintain the database
+
 ## 0.2 Series
 
 ### 0.2.0

+ 4 - 4
README.md

@@ -13,7 +13,7 @@ Score keeping software for [Carcassonne](https://boardgamegeek.com/boardgame/822
 Before your first game you will need to initialize the sqlite database:
 
 ```
-$ python create_database.py
+$ python manage_database.py --init
 ```
 
 ### Score keeping
@@ -28,13 +28,13 @@ This launches the interactive shell. Press `?` for a list of commands.
 
 ### Database Maintenance
 
-To update the database (add new players toggle availability of expansions), use the `update_database.py` command. For example, to add a new player:
+To update the database (add new players toggle availability of expansions), use the `manage_database.py` command. For example, to add a new player:
 
 ```
-$ python update_database.py -n NEW PLAYER
+$ python manage_database.py -n NEW PLAYER
 ```
 
-Use `python update_database.py -h` to see the full list of options.
+Use `python manage_database.py -h` to see the full list of options.
 
 
 ### Analysis

+ 0 - 202
create_database.py

@@ -1,202 +0,0 @@
-#!/usr/bin/env python
-"""
-Database initialization for Carcassonne score keeping system.
-
-Copyright 2018 George C. Privon
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program.  If not, see <http://www.gnu.org/licenses/>.
-"""
-
-import sqlite3
-
-conn = sqlite3.connect('CarcassonneScore.db')
-c = conn.cursor()
-
-# player table
-c.execute('''CREATE TABLE players (playerID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
-                                   name TEXT NOT NULL DEFAULT "")''')
-# player names
-c.execute('''INSERT INTO players values (0,
-                                         "John Smith")''')
-c.execute('''INSERT INTO players values (1,
-                                         "Jane Doe")''')
-
-# games table
-# gameID - unique ID
-# location - free text
-# starttime - timecode
-# endtime - timecode
-# expansions - comma-separated list of expansions used (by expansionID)
-c.execute('''CREATE TABLE games (gameID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
-                                 location TEXT NOT NULL DEFAULT "",
-                                 starttime TEXT NOT NULL DEFAULT "",
-                                 endtime TEXT NOT NULL DEFAULT "",
-                                 expansions TEXT NOT NULL DEFAULT "")''')
-
-
-# turns table
-# gameID - corresponds to games table
-# turnNum - incremented turn number (corresponds to a tile placement)
-# time - time at which the placement was made
-# builder - 0 if tile was placed as part of normal turn, 1 if placed
-#           as a result of a builder token
-# playerID - player who made the turn
-c.execute('''CREATE TABLE turns (gameID INTEGER NOT NULL,
-                                 turnNum INTEGER NOT NULL,
-                                 time TEXT NOT NULL,
-                                 builder INTEGER NOT NULL,
-                                 playerID INTEGER NOT NULL)''')
-
-# individual scores
-# gameID - unique per game
-# playerID - corresponds to entry from players table
-# turnNum - turn number (corresponds to number in turns table)
-# scoreID - ID number for the score (unique to game?)
-# ingame - 1 if scored during regular play, 0 if scored after tiles are gone
-# points - number of points awarded
-# scoretype - road, city, meadow, etc.
-# sharedscore - was this score shared with another player?
-# token - token(s) used for score (e.g., meeple, wagon, pig)
-# extras - any other items (e.g., trade goods)
-# comments - text annotation
-c.execute('''CREATE TABLE scores (gameID INTEGER NOT NULL,
-                                  playerID INTEGER NOT NULL,
-                                  turnNum INTEGER NOT NULL,
-                                  scoreID INTEGER NOT NULL,
-                                  ingame INTEGER NOT NULL,
-                                  points INTEGER NOT NULL,
-                                  scoretype TEXT NOT NULL,
-                                  sharedscore INTEGER NOT NULL,
-                                  token TEXT NOT NULL,
-                                  extras NOT NULL,
-                                  comments TEXT)''')
-
-# list of expansions
-# mini - 1 if a mini expanion, otherwise 0
-# active - 1 if it can be played, otherwise 0
-# tokens - additional tokens provided beyond the base game
-# scoretypes - additional classes of scoring enabled
-# Ntiles - number of tiles added
-# tiletypes - special scorable tiles added
-c.execute('''CREATE TABLE expansions (expansionID INTEGER PRIMARY KEY,
-                                      name TEXT NOT NULL,
-                                      mini INTEGER,
-                                      active INTEGER,
-                                      tokens TEXT,
-                                      scoretypes TEXT,
-                                      Ntiles INTEGER,
-                                      tiletypes TEXT)''')
-# large expansions
-# taken from http://carcassonne.wikia.com/wiki/Official_expansions
-# Only 1, 2, and 5 are currently populated
-c.execute('''INSERT INTO expansions values (1,
-                                            "Inns & Cathedrals",
-                                            0,
-                                            1,
-                                            "BigMeeple",
-                                            "",
-                                            18,
-                                            "Cathedral,InnonLake")''')
-c.execute('''INSERT INTO expansions values (2,
-                                            "Traders & Builders",
-                                            0,
-                                            1,
-                                            "Pig,Builder",
-                                            "",
-                                            24,
-                                            "TradeGoods")''')
-c.execute('''INSERT INTO expansions values (3,
-                                            "Princess & Dragon",
-                                            0,
-                                            0,
-                                            "",
-                                            "",
-                                            0,
-                                            "")''')
-c.execute('''INSERT INTO expansions values (4,
-                                            "The Tower",
-                                            0,
-                                            0,
-                                            "",
-                                            "",
-                                            0,
-                                            "")''')
-c.execute('''INSERT INTO expansions values (5,
-                                            "Abbey & Mayor",
-                                            0,
-                                            1,
-                                            "Mayor,Wagon,Barn",
-                                            "",
-                                            12,
-                                            "Abbey")''')
-c.execute('''INSERT INTO expansions values (6,
-                                            "Count, King & Robber",
-                                            0,
-                                            0,
-                                            "",
-                                            "",
-                                            0,
-                                            "")''')
-c.execute('''INSERT INTO expansions values (7,
-                                            "The Catapult",
-                                            0,
-                                            0,
-                                            "",
-                                            "",
-                                            0,
-                                            "")''')
-c.execute('''INSERT INTO expansions values (8,
-                                            "Bridges, Castles & Bazaars",
-                                            0,
-                                            0,
-                                            "",
-                                            "",
-                                            0,
-                                            "")''')
-c.execute('''INSERT INTO expansions values (9,
-                                            "Hills & Sheep",
-                                            0,
-                                            0,
-                                            "",
-                                            "",
-                                            0,
-                                            "")''')
-c.execute('''INSERT INTO expansions values (10,
-                                            "Under the Big Top",
-                                            0,
-                                            0,
-                                            "",
-                                            "",
-                                            0,
-                                            "")''')
-#mini expansions
-c.execute('''INSERT INTO expansions values(101,
-                                           "The River",
-                                           1,
-                                           1,
-                                           "",
-                                           "",
-                                           12,
-                                           "")''')
-c.execute('''INSERT INTO expansions values(102,
-                                           "The Abbott",
-                                           1,
-                                           1,
-                                           "Abbott",
-                                           "Garden",
-                                           0,
-                                           "")''')
-
-conn.commit()
-conn.close()

+ 334 - 0
manage_database.py

@@ -0,0 +1,334 @@
+#!/usr/bin/env python
+"""
+Database management for Carcassonne score keeping system.
+
+Copyright 2018 George C. Privon
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+"""
+
+import sys
+import os
+import argparse
+import re
+import sqlite3
+
+
+def parseArgs():
+    """
+    Command line arguments
+    """
+
+    parser = argparse.ArgumentParser(description="Update the Carcassonne \
+scoring database.")
+    cmds = parser.add_mutually_exclusive_group(required=True)
+    cmds.add_argument('--init', default=False, action='store_true',
+                      help='Create a fresh database.')
+    cmds.add_argument('-n', '--newplayer', type=str, default=None,
+                      nargs='+',
+                      help='Add a new player.')
+    cmds.add_argument('-e', '--enableexpansion', action='store_true',
+                      default=False,
+                      help='Enable an expansion.')
+    cmds.add_argument('-d', '--disableexpansion', action='store_true',
+                      default=False,
+                      help='Disable an expansion.')
+
+    return parser.parse_args()
+
+
+def initializeDB(c):
+    """
+    Initialize Database
+    """
+
+    # player table
+    c.execute('''CREATE TABLE players (playerID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+                                       name TEXT NOT NULL DEFAULT "")''')
+    # player names
+    c.execute('''INSERT INTO players values (0,
+                                             "John Smith")''')
+    c.execute('''INSERT INTO players values (1,
+                                             "Jane Doe")''')
+
+    # games table
+    # gameID - unique ID
+    # location - free text
+    # starttime - timecode
+    # endtime - timecode
+    # expansions - comma-separated list of expansions used (by expansionID)
+    c.execute('''CREATE TABLE games (gameID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+                                     location TEXT NOT NULL DEFAULT "",
+                                     starttime TEXT NOT NULL DEFAULT "",
+                                     endtime TEXT NOT NULL DEFAULT "",
+                                     expansions TEXT NOT NULL DEFAULT "")''')
+
+
+    # turns table
+    # gameID - corresponds to games table
+    # turnNum - incremented turn number (corresponds to a tile placement)
+    # time - time at which the placement was made
+    # builder - 0 if tile was placed as part of normal turn, 1 if placed
+    #           as a result of a builder token
+    # playerID - player who made the turn
+    c.execute('''CREATE TABLE turns (gameID INTEGER NOT NULL,
+                                     turnNum INTEGER NOT NULL,
+                                     time TEXT NOT NULL,
+                                     builder INTEGER NOT NULL,
+                                     playerID INTEGER NOT NULL)''')
+
+    # individual scores
+    # gameID - unique per game
+    # playerID - corresponds to entry from players table
+    # turnNum - turn number (corresponds to number in turns table)
+    # scoreID - ID number for the score (unique to game?)
+    # ingame - 1 if scored during regular play, 0 if scored after tiles are gone
+    # points - number of points awarded
+    # scoretype - road, city, meadow, etc.
+    # sharedscore - was this score shared with another player?
+    # token - token(s) used for score (e.g., meeple, wagon, pig)
+    # extras - any other items (e.g., trade goods)
+    # comments - text annotation
+    c.execute('''CREATE TABLE scores (gameID INTEGER NOT NULL,
+                                      playerID INTEGER NOT NULL,
+                                      turnNum INTEGER NOT NULL,
+                                      scoreID INTEGER NOT NULL,
+                                      ingame INTEGER NOT NULL,
+                                      points INTEGER NOT NULL,
+                                      scoretype TEXT NOT NULL,
+                                      sharedscore INTEGER NOT NULL,
+                                      token TEXT NOT NULL,
+                                      extras NOT NULL,
+                                      comments TEXT)''')
+
+    # list of expansions
+    # mini - 1 if a mini expanion, otherwise 0
+    # active - 1 if it can be played, otherwise 0
+    # tokens - additional tokens provided beyond the base game
+    # scoretypes - additional classes of scoring enabled
+    # Ntiles - number of tiles added
+    # tiletypes - special scorable tiles added
+    c.execute('''CREATE TABLE expansions (expansionID INTEGER PRIMARY KEY,
+                                          name TEXT NOT NULL,
+                                          mini INTEGER,
+                                          active INTEGER,
+                                          tokens TEXT,
+                                          scoretypes TEXT,
+                                          Ntiles INTEGER,
+                                          tiletypes TEXT)''')
+    # large expansions
+    # taken from http://carcassonne.wikia.com/wiki/Official_expansions
+    # Only 1, 2, and 5 are currently populated
+    c.execute('''INSERT INTO expansions values (1,
+                                                "Inns & Cathedrals",
+                                                0,
+                                                1,
+                                                "BigMeeple",
+                                                "",
+                                                18,
+                                                "Cathedral,InnonLake")''')
+    c.execute('''INSERT INTO expansions values (2,
+                                                "Traders & Builders",
+                                                0,
+                                                1,
+                                                "Pig,Builder",
+                                                "",
+                                                24,
+                                                "TradeGoods")''')
+    c.execute('''INSERT INTO expansions values (3,
+                                                "Princess & Dragon",
+                                                0,
+                                                0,
+                                                "",
+                                                "",
+                                                0,
+                                                "")''')
+    c.execute('''INSERT INTO expansions values (4,
+                                                "The Tower",
+                                                0,
+                                                0,
+                                                "",
+                                                "",
+                                                0,
+                                                "")''')
+    c.execute('''INSERT INTO expansions values (5,
+                                                "Abbey & Mayor",
+                                                0,
+                                                1,
+                                                "Mayor,Wagon,Barn",
+                                                "",
+                                                12,
+                                                "Abbey")''')
+    c.execute('''INSERT INTO expansions values (6,
+                                                "Count, King & Robber",
+                                                0,
+                                                0,
+                                                "",
+                                                "",
+                                                0,
+                                                "")''')
+    c.execute('''INSERT INTO expansions values (7,
+                                                "The Catapult",
+                                                0,
+                                                0,
+                                                "",
+                                                "",
+                                                0,
+                                                "")''')
+    c.execute('''INSERT INTO expansions values (8,
+                                                "Bridges, Castles & Bazaars",
+                                                0,
+                                                0,
+                                                "",
+                                                "",
+                                                0,
+                                                "")''')
+    c.execute('''INSERT INTO expansions values (9,
+                                                "Hills & Sheep",
+                                                0,
+                                                0,
+                                                "",
+                                                "",
+                                                0,
+                                                "")''')
+    c.execute('''INSERT INTO expansions values (10,
+                                                "Under the Big Top",
+                                                0,
+                                                0,
+                                                "",
+                                                "",
+                                                0,
+                                                "")''')
+    #mini expansions
+    c.execute('''INSERT INTO expansions values(101,
+                                               "The River",
+                                               1,
+                                               1,
+                                               "",
+                                               "",
+                                               12,
+                                               "")''')
+    c.execute('''INSERT INTO expansions values(102,
+                                               "The Abbott",
+                                               1,
+                                               1,
+                                               "Abbott",
+                                               "Garden",
+                                               0,
+                                               "")''')
+
+
+def getExpans(cur, active=True):
+    """
+    Get a list of (in)active expansions
+    """
+
+    command = 'SELECT expansionID,name FROM expansions WHERE active='
+    if active:
+        command = command + '1'
+    else:
+        command = command + '0'
+
+    return cur.execute(command).fetchall()
+
+
+def toggleExpan(cur, ID, activate=True):
+    """
+    Change the active status for an expansion
+    """
+    command = 'UPDATE expansions SET active='
+    if activate:
+        command = command + '1'
+    elif not activate:
+        command = command + '0'
+    else:
+        sys.stderr.write("What have you done?\n")
+        sys.exit(-1)
+
+    command = command + ' where expansionID={0:1.0f}'.format(ID)
+
+    cur.execute(command)
+
+
+def main():
+    """
+    main routine
+    """
+
+    args = parseArgs()
+
+    if args.init and os.path.isfile('CarcassonneScore.db'):
+        sys.stderr.write("Error: 'CarcassonneScore.db' already exists. Exiting.\n")
+        sys.exit()
+
+    conn = sqlite3.connect('CarcassonneScore.db')
+    cur = conn.cursor()
+
+    VALID = False
+
+    if args.init:
+        initializeDB(cur)
+    elif args.newplayer:
+        pname = ' '.join(args.newplayer)
+        sys.stdout.write("Adding new player: " + pname)
+        sys.stdout.write(" to the database.\n")
+        while not VALID:
+            ans = input("Is this correct (y/n)? ")
+            if re.match('y', ans, re.IGNORECASE):
+                cur.execute('INSERT INTO players (name) VALUES ("' + \
+                            pname + '")')
+                sys.stdout.write(pname + ' added to the database.\n')
+                VALID = True
+            elif re.match('n', ans, re.IGNORECASE):
+                sys.stdout.write('Canceling.\n')
+                VALID = True
+
+    elif args.enableexpansion:
+        expans = getExpans(cur, active=False)
+        kwds = ("enable", "inactive")
+        activate = True
+    elif args.disableexpansion:
+        expans = getExpans(cur, active=True)
+        kwds = ("disable", "active")
+        activate = False
+
+    if args.enableexpansion or args.disableexpansion:
+        expnumlist = []
+        for expan in expans:
+            expnumlist.append(int(expan[0]))
+            sys.stdout.write("{0:1.0f}) ".format(expan[0]) + expan[1] + "\n")
+        try:
+            toggleexp = input("Please enter the " + kwds[1] + ' expansion to ' + kwds[0] + ': ')
+            if not list:
+                sys.stderr.write("No expansions specified. Exiting.\n")
+        except (EOFError, KeyboardInterrupt):
+            conn.close()
+            sys.exit()
+        #TODO actually update the expansions
+        try:
+            toggleexp = int(toggleexp)
+        except:
+            sys.stderr.write("Error: invalid input. Please enter a number from the list next time.\n")
+            sys.exit()
+        if toggleexp not in expnumlist:
+            sys.stderr.write("Error: invalid input. Please enter a number from the list next time.\n")
+            sys.exit()
+        toggleExpan(cur, toggleexp, activate=activate)
+
+    conn.commit()
+    conn.close()
+
+
+if __name__ == "__main__":
+    main()

+ 0 - 144
update_database.py

@@ -1,144 +0,0 @@
-#!/usr/bin/env python
-"""
-Database management for Carcassonne score keeping system.
-
-Copyright 2018 George C. Privon
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program.  If not, see <http://www.gnu.org/licenses/>.
-"""
-
-import sys
-import argparse
-import re
-import sqlite3
-
-
-def parseArgs():
-    """
-    Command line arguments
-    """
-
-    parser = argparse.ArgumentParser(description="Update the Carcassonne \
-scoring database.")
-    cmds = parser.add_mutually_exclusive_group(required=True)
-    cmds.add_argument('-n', '--newplayer', type=str, default=None,
-                      nargs='+',
-                      help='Add a new player.')
-    cmds.add_argument('-e', '--enableexpansion', action='store_true',
-                      default=False,
-                      help='Enable an expansion.')
-    cmds.add_argument('-d', '--disableexpansion', action='store_true',
-                      default=False,
-                      help='Disable an expansion.')
-
-    return parser.parse_args()
-
-
-def getExpans(cur, active=True):
-    """
-    Get a list of (in)active expansions
-    """
-
-    command = 'SELECT expansionID,name FROM expansions WHERE active='
-    if active:
-        command = command + '1'
-    else:
-        command = command + '0'
-
-    return cur.execute(command).fetchall()
-
-
-def toggleExpan(cur, ID, activate=True):
-    """
-    Change the active status for an expansion
-    """
-    command = 'UPDATE expansions SET active='
-    if activate:
-        command = command + '1'
-    elif not activate:
-        command = command + '0'
-    else:
-        sys.stderr.write("What have you done?\n")
-        sys.exit(-1)
-
-    command = command + ' where expansionID={0:1.0f}'.format(ID)
-
-    cur.execute(command)
-
-
-def main():
-    """
-    main routine
-    """
-
-    args = parseArgs()
-
-    conn = sqlite3.connect('CarcassonneScore.db')
-    cur = conn.cursor()
-
-    VALID = False
-
-    if args.newplayer:
-        pname = ' '.join(args.newplayer)
-        sys.stdout.write("Adding new player: " + pname)
-        sys.stdout.write(" to the database.\n")
-        while not VALID:
-            ans = input("Is this correct (y/n)? ")
-            if re.match('y', ans, re.IGNORECASE):
-                cur.execute('INSERT INTO players (name) VALUES ("' + \
-                            pname + '")')
-                sys.stdout.write(pname + ' added to the database.\n')
-                VALID = True
-            elif re.match('n', ans, re.IGNORECASE):
-                sys.stdout.write('Canceling.\n')
-                VALID = True
-
-    if args.enableexpansion:
-        expans = getExpans(cur, active=False)
-        kwds = ("enable", "inactive")
-        activate = True
-    elif args.disableexpansion:
-        expans = getExpans(cur, active=True)
-        kwds = ("disable", "active")
-        activate = False
-
-    if args.enableexpansion or args.disableexpansion:
-        expnumlist = []
-        for expan in expans:
-            expnumlist.append(int(expan[0]))
-            sys.stdout.write("{0:1.0f}) ".format(expan[0]) + expan[1] + "\n")
-        try:
-            toggleexp = input("Please enter the " + kwds[1] + ' expansion to ' + kwds[0] + ': ')
-            if not list:
-                sys.stderr.write("No expansions specified. Exiting.\n")
-        except (EOFError, KeyboardInterrupt):
-            conn.close()
-            sys.exit()
-        #TODO actually update the expansions
-        try:
-            toggleexp = int(toggleexp)
-        except:
-            sys.stderr.write("Error: invalid input. Please enter a number from the list next time.\n")
-            sys.exit()
-        if toggleexp not in expnumlist:
-            sys.stderr.write("Error: invalid input. Please enter a number from the list next time.\n")
-            sys.exit()
-        toggleExpan(cur, toggleexp, activate=activate)
-
-    conn.commit()
-    conn.close()
-
-
-if __name__ == "__main__":
-    main()