shopr

Check-in [8a1ba772ee]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Get some of it running for the first time.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256:8a1ba772eea3aa81b23ea5ec6001f32d2e5c638d7fd0216bcaad57b7d4b3435d
User & Date: vandys 2019-06-20 16:37:40
Context
2019-06-20
22:36
Bringup check-in: 9f66b65036 user: vandys tags: trunk
16:37
Get some of it running for the first time. check-in: 8a1ba772ee user: vandys tags: trunk
16:23
More workup for DB design, acct/list/item org, start building out REST ops. check-in: d3092a3ba5 user: vandys tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to etc/config.

1
2
3
4
5



6
7
8
9
10
11
#
# List-with-swiping service
#
service "Swipr"




# Web interface
serve https
    port 8095
    publicCert certs/server.crt
    privateKey certs/server.key


|

|

>
>
>

|
|
<
<

1
2
3
4
5
6
7
8
9
10
11


12
#
# Shopping List
#
service "Shopr"

# sqlite3 storage
db var/shopr.db

# Web interface
serve http
    port 8085



Changes to main.py.

5
6
7
8
9
10
11







12
13
14
15
16
17
18
..
55
56
57
58
59
60
61
62
63


64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
...
103
104
105
106
107
108
109
110
111
112
113
114

115
116
117
118
119
120
121
import sys
import sqlite3
import chore
from get import GET_mixin
from post import POST_mixin
from put import PUT_mixin
import items








# Tie our various handlers together
class App_Handler(chore.handlers.Chore_Handler,
	GET_mixin, POST_mixin, PUT_mixin):
    def __init__(self, conn, tup, approot):
	chore.handlers.Chore_Handler.__init__(self, conn, tup, approot,
	    (GET_mixin.__init__,
................................................................................
	approot.uids[name] = uid

	return True

# Root of our app server
class App(chore.server.Server):

    def __init__(self, dbn):
	# sqlite3 database file


	self.dbname = dbn

	# Cache uname <-> uid
	self.uids = {}

	# In-memory list state.
	# Keyed by (uid,name) for private lists,
	#  name for public.
	self.lists = {}

	# Let Chore handle most things
	chore.server.Server.__init__(self, config, App_Handler);

    # Get list state, pulling from DB on first reference
    def get_list(self, uid, name):
	# Already known?
	res = self.lists.get( (uid,name) )
	if res is not None:
	    return res
................................................................................
	    return None
	lid = tup[0]
	res = self.lists[name] = List(self, lid, True, name)
	return res

if __name__ == "__main__":
    if len(sys.argv) != 2:
	sys.stderr.write("Usage is: %s <file.db>\n" %
	    (sys.argv[0],))
	sys.exit(1)

    # Create the server with config

    app = App(sys.argv[1])

    # It's an HTTP service
    app.start_http()

    # HTTP threads remain
    sys.exit(0)







>
>
>
>
>
>
>







 







|

>
>
|










|







 







|




>
|






5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
..
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
...
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import sys
import sqlite3
import chore
from get import GET_mixin
from post import POST_mixin
from put import PUT_mixin
import items

# Our config (pretty basic)
def load_cfg(fn):
    c = chore.config.Config()
    chore.www.add_config(c)
    c.onearg.add( ("db",) )
    return c.load_cfg(fn)

# Tie our various handlers together
class App_Handler(chore.handlers.Chore_Handler,
	GET_mixin, POST_mixin, PUT_mixin):
    def __init__(self, conn, tup, approot):
	chore.handlers.Chore_Handler.__init__(self, conn, tup, approot,
	    (GET_mixin.__init__,
................................................................................
	approot.uids[name] = uid

	return True

# Root of our app server
class App(chore.server.Server):

    def __init__(self, cfg):
	# sqlite3 database file
	if "db" not in cfg:
	    raise Exception, "No DB name specified"
	self.dbname = cfg["db"]

	# Cache uname <-> uid
	self.uids = {}

	# In-memory list state.
	# Keyed by (uid,name) for private lists,
	#  name for public.
	self.lists = {}

	# Let Chore handle most things
	chore.server.Server.__init__(self, cfg, App_Handler);

    # Get list state, pulling from DB on first reference
    def get_list(self, uid, name):
	# Already known?
	res = self.lists.get( (uid,name) )
	if res is not None:
	    return res
................................................................................
	    return None
	lid = tup[0]
	res = self.lists[name] = List(self, lid, True, name)
	return res

if __name__ == "__main__":
    if len(sys.argv) != 2:
	sys.stderr.write("Usage is: %s <config>\n" %
	    (sys.argv[0],))
	sys.exit(1)

    # Create the server with config
    cfg = load_cfg(sys.argv[1])
    app = App(cfg)

    # It's an HTTP service
    app.start_http()

    # HTTP threads remain
    sys.exit(0)

Changes to post.py.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#
# post.py
#	Mixin to implement HTML POST operations
#
# /l/<listname>
#	Create a new list
#
import urllib
import ilist, delta

# The POST part of our handling
class POST_mixin(object):

    # Configure our WPlayer GET treatment
    def __init__(self):

	# POST handlers
	self.dispatchers.append( ("POST", self.post_newlist) )
	self.dispatchers.append( ("POST", self.post_newitem) )

    # A new list requested?
    def post_newlist(self, buf):
	# /rest/l/LISTNAME
	pp = self.paths
	if (len(pp) != 3) or \
		(pp[0] != 'rest') or (pp[1] != 'l') or \
		(not pp[1]):
	    return False,None
	nm = urllib.unquote_plus(pp[2])
	if not ilist.ok_obname(nm):
	    resp = {"code": "Bad list name"}
	    return True,self.send_json(resp)

	# Can't already exist
	if nm in ilist.ilists:
	    resp = {"code": "List already exists"}
	    return True,self.send_json(resp)
	l = ilist.IList(self.user, nm)
	l.dump()

	# We're in business
	resp = {"code": "OK"}
	return True,self.send_json(resp)

    # A new item requested?
    def post_newitem(self, buf):
	# /rest/l/LISTNAME/COLUMN/ITEM
	#   0   1    2       3     4
	pp = self.paths
	if (len(pp) != 5) or \
		(pp[0] != 'rest') or (pp[1] != 'l') or \
		(not pp[2]) or (not pp[3]) or (not pp[4]):
	    return False,None

	# Verify list name
	lnm = urllib.unquote_plus(pp[2])
	l = ilist.ilists.get(lnm)
	if l is None:
	    resp = {"code": "No such list"}
	    return True,self.send_json(resp)

	# Column name
	colnm = urllib.unquote_plus(pp[3])
	col = l.getCol(colnm)
	if col is None:
	    resp = {"code": "No such column"}
	    return True,self.send_json(resp)
	colidx = l.cols.index(col)

	# Item name.  Can't already exist.
	nm = urllib.unquote_plus(pp[4])
	if nm in col.data:
	    resp = {"code": "Item already exists"}
	    return True,self.send_json(resp)
	if not ilist.ok_obname(nm):
	    resp = {"code": "Bad item name"}
	    return True,self.send_json(resp)

	# Ok, add to items and re-sort
	col.data.append(nm)
	col.data.sort()

	# Sync to filesystem
	l.dump()

	# The display of the item--for this user and all others--comes
	#  from the delta update
	col.gen += 1
	delta.changed("add", col.gen, ("l", lnm, colidx, nm))
	delta.commit()

	# We're in business
	resp = {"code": "OK"}
	return True,self.send_json(resp)




<
<
<

<













<
<
<
<
<
|
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<


<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
1
2
3
4



5

6
7
8
9
10
11
12
13
14
15
16
17
18





19




20











21
22






23









































#
# post.py
#	Mixin to implement HTML POST operations
#



import urllib


# The POST part of our handling
class POST_mixin(object):

    # Configure our WPlayer GET treatment
    def __init__(self):

	# POST handlers
	self.dispatchers.append( ("POST", self.post_newlist) )
	self.dispatchers.append( ("POST", self.post_newitem) )

    # A new list requested?
    def post_newlist(self, buf):





	return False,None
















    # A new item requested?
    def post_newitem(self, buf):






	return False,None