Subversion Repositories Misc

[/] [dslmap/] [forgottenislanderbot/] [fibmod.py] - Blame information for rev 15

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 15 art
#!/usr/bin/env python
2
 
3
# forgottenislanderbot - makes a DSL coverage map from Bell Aliant's website.
4
# Copyright (c) 2010 Art Ortenburger
5
#
6
# This program is free software; you can redistribute it and/or
7
# modify it under the terms of the GNU General Public License
8
# as published by the Free Software Foundation; either version 2
9
# of the License, or any later version.
10
#
11
# This program is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
# GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19
#
20
 
21
# fibmod.py
22
# by Art Ortenburger IV <utrrrongeeb a users , sf , net>
23
# written 2010-01-14 -
24
#
25
# forgottenislanderbot -- shared module functions
26
#
27
# Provides reusable generic functions to
28
# forgottenislanderbot components.
29
#
30
 
31
 
32
# ToDo:
33
# @77 == att == attn == attention == serious idea, better consider
34
#
35
# O crawl: try blocks everywhere, so won't crash after 18h stretch w/o commit
36
# X crawl: try, and recover from dead httpconnection
37
# O dbutil --list
38
# O dbutil --stats: remove dslflags, or bring them back?
39
# O *: comments, licenseblock, new headers
40
# O *: fix globals, improve code
41
# _ *: write full documentation for users, including howto/tutorial
42
# _ *: write bat/bash wrapper scripts
43
# X *: implement DIP http advice, try gzip (gzip didn't work)
44
# O crawl: put in routine long kill pause, db commit
45
# O *: move dslflags routines to processDB -- many advantages, & floatize delay
46
# _ *: decide on dslflags maxrows mess
47
# _ dbutil: fix KML icons -- small, red for NODSL, blobs?
48
# O *: all @77 notes dealt with?
49
# ^ crawl: fix Linux print status bug [ pending test ]
50
# _ dbutil: NASA World Wind KML output support
51
# _ crawl: end-of-road support & options
52
# ----
53
# _ dbutil: KMZ output (factor of 20)
54
# _ *: custom SQL, lat/lon rect submaps
55
# _ *: BUG: piping output crashes, maybe from from sys.stdout.flush()?
56
# _ crawl: try taking out hc.connect() under high-speed; maybe make auto?
57
# _ *: deploy 'with' keyword
58
# _ *: make dynamic cmd-line flags with optparse (new 'fib' frontend)
59
# _ *: port to Python 3
60
# _ confirm all server responses are recognized
61
# _ dbutil --merging
62
# _ dbutil --strip
63
# _ dbutil --diff
64
#
65
 
66
import sys
67
import sqlite3
68
 
69
if __name__ == "__main__":
70
    print sys.argv[0],"""(forgottenislanderbot shared module)    Version 0.1
71
Copyright (c) 2010 Art Ortenburger. Licensed under the GNU GPL; no warranty."""
72
 
73
 
74
def processDB(sqlcur,actionfunc,dslFlags,maxrows,sparsity,delay,excludecities):
75
    """ Loops through SQlite database, selecting rows
76
    based on parameters, and calling the specified function
77
    for each selected row.
78
    sqlcur:     sqlite3.Cursor to civic address database from fib-cadb2sql.py
79
    actionfunc: function to call for selected addresses.
80
                Must accept these parameters:
81
                sqlite3.Cursor
82
                town (string)
83
                road (string)
84
                civic number (int)
85
                seconds to pause between rows (float)
86
                dsl status of address (int)
87
                longitude (float)
88
                latitude (float)
89
    dslFlags:   4 y/n charbools in string sequence, OR
90
                4 bools in a list.
91
                Whether to call actionfunc() for rows
92
                in the EMPTY, NODSL, BASIC, or ULTRA
93
                categories. Example: "nyyy".
94
    maxrows:   bool; whether to keep rigid sparseness based on dslFlags,
95
                or not. True is desirable for dbutil --kml, where you
96
                want many results, but False is important for the crawler,
97
                to maintain high sparseness.
98
    sparsity:   int; minimum civic-number difference between
99
                houses to skip. For every house, enter 1.
100
                For about one house per road, enter 10000.
101
    delay:      float; seconds to pause between selected addresses.
102
                Delaying is actually done, if it is, by actionfunc.
103
    excludecities:  bool; whether to exclude the two major cities
104
                    from the selected rows or not."""
105
 
106
    # first, handle dslflags:
107
    dslflags = [ False, False, False, False ] # real dslflags for use
108
    dfl = len(dslFlags) # dsl flags length
109
    if dfl >= 4: # 4 or more? only use first 4.
110
        for i in range(4):
111
            dslflags[i] = char2Bool(dslFlags[i])
112
    elif dfl == 3: # hopefully this won't be used -- EMPTY, NODSL, & (BASIC+ULTRA)
113
        for i in range(3):
114
            dslflags[i] = char2Bool(dslFlags[i])
115
            dslflags[3] = dslflags[2]
116
    elif dfl == 2: # hopefully to be ignored -- EMPTY, KNOWN
117
        dslflags[0] = char2Bool(dslFlags[0])
118
        dslflags[1] = dslflags[2] = dslflags[3] = char2Bool(dslFlags[1])
119
    elif dfl == 1: # hopefully to be ignored -- EMPTY [KNOWN = True]
120
        dslflags = [char2Bool(dslFlags[0]), True, True, True]
121
    else: # easy -- all True
122
        dslflags = [ True, True, True, True ]
123
 
124
    sqlcur.execute("select town,road,civic,dsl,long,lat from dsl order by town,road,civic")
125
    lasttown = lastroad = town = road = ""
126
    lastcivic = civic = 0
127
    # this block will take a lot of ram due to fetchall() rather than fetchone().
128
    # Shouldn't be hard to fix if needed, though. Current-db ram req: 6 MB max?
129
    for cca in sqlcur.fetchall(): # current civic address
130
        town,road,civic = cca[0],cca[1],int(cca[2])# cast here is importent
131
 
132
        # skip cities -- currently only Ch'town and Summerside -- if requested
133
        if excludecities and ( town == "CHARLOTTETOWN" or town == "SUMMERSIDE" ):
134
            continue
135
 
136
        # apply the dslflags. If status doesn't match, check maxcalls
137
        # on whether to set last___ vars, to determine whether a
138
        # maximum number of addresses will be gotten, or a regular
139
        # sparseness will be maintained.
140
        sii = int(cca[3]) # status index int
141
        if sii < 0:
142
            sii = 0
143
        if not dslflags[sii]:
144
            if not maxrows:
145
                lasttown,lastroad,lastcivic = cca[0],cca[1],int(cca[2])
146
            continue;
147
 
148
        try: # loop must not crash
149
            # on the same road, make sure to skip houses for sparseness
150
            if town == lasttown and road == lastroad:
151
                if (civic - lastcivic) >= sparsity: # sparseness check
152
                    actionfunc(sqlcur,town,road,civic,delay,int(cca[3]),float(cca[4]),float(cca[5]))
153
                # if sparseness check failed, don't do anything
154
            else: # on a new road, always get the first house
155
                actionfunc(sqlcur,town,road,civic,delay,int(cca[3]),float(cca[4]),float(cca[5]))
156
        except Exception, errdet:
157
            print "> error < :",errdet
158
        # not sure how to get the last easily.
159
        # @77 Could make last(lat|lon|stat) vars, and a postcheck....
160
        lasttown,lastroad,lastcivic = cca[0],cca[1],int(cca[2])
161
 
162
 
163
 
164
 
165
def char2Bool(inchar):
166
    """ Returns a bool from a y/n char param.
167
        y:Y: True; anything else: False
168
        However, if inchar is a bool, it will be returned as is.
169
 
170
        param sequence can be any length,
171
        but only the first char gets evaluated"""
172
    if inchar == True or inchar == False:
173
        return inchar
174
    elif inchar[0] == 'y' or inchar[0] == 'Y':
175
        return True
176
    else:
177
        return False
178
 
179