I'm trying to create a plugin for a Uni-subject which will receive a zipcode from a user and return the name of the corresponding location.
I have created the plugin layout, through the Plugin Builder and have designed the graphical interface with QtDesigner https://i.stack.imgur.com/h6k6Q.png . I have also added the .txt file that contains the zipcodes database to the plugin folder.
However, when I reload the plugin it gives me the error "object has no attribute 'dlg'" error message
Could you give me some guidance here and point me to where the problem could be? I am new to plugin development and python. Thanks
The code is this one:
import os
import sys
import qgis.core
from qgis.PyQt import uic
from qgis.PyQt import (
QtCore,
QtWidgets
)
import geocoder
# This loads your .ui file so that PyQt can populate your plugin with the elements from Qt Designer
FORM_CLASS, _ = uic.loadUiType(os.path.join(
os.path.dirname(__file__), 'example_dialog_base.ui'))
class ExampleDialog(QtWidgets.QDialog, FORM_CLASS):
POSTAL_CODES_PATH = ":/plugins/example/todos_cp.txt"
def __init__(self, parent=None):
"""Constructor."""
super(ExampleDialog, self).__init__(parent)
# Set up the user interface from Designer through FORM_CLASS.
# After self.setupUi() you can access any designer object by doing
# self.<objectname>, and you can use autoconnect slots - see
# http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
# #widgets-and-dialogs-with-auto-connect
self.setupUi(self)
#self.QpushButton.clicked.connect(self.print_hello_world)
self.QlineEdit.textChanged.connect(self.toggle_find_button)
self.find_code_btn.clicked.connect(self.execute)
#def print_hello_world(self):
#print('Hello World!')
def toggle_find_button(self):
if self.QlineEdit.text() == "":
self.find_code_btn.setEnabled(False)
else:
self.find_code_btn.setEnabled(True)
def find_record(self, main_code, extension):
file_handler = QtCore.QFile(self.POSTAL_CODES_PATH)
file_handler.open(QtCore.QIODevice.ReadOnly)
stream = QtCore.QTextStream(file_handler)
while not stream.atEnd():
line = stream.readLine()
info = line.split(";")
code1 = info[-3]
code2 = info[-2]
if code1 == main_code and code2 == extension:
result = info
break
else:
raise RuntimeError("Sem resultados")
return result
def handle_layer_creation(self, record):
place_name = record[3]
point = geocode_place_name(place_name)
print("lon: {} - lat: {}".format(point.x(), point.y()))
layer = create_point_layer(
point,
f"found_location_for_{record[-3]}_{record[-2]}",
place_name
)
current_project = qgis.core.QgsProject.instance()
current_project.addMapLayer(layer)
def show_error(self, message):
message_bar = self.iface.messageBar()
message_bar.pushMessage("Error", message, level=message_bar.Critical)
def validate_postal_code(raw_postal_code):
code1, code2 = raw_postal_code.partition("-")[::2]
if code1 == "" or code2 == "":
raise ValueError(
"Incorrect postal code: {!r}".format(raw_postal_code))
return code1, code2
def geocode_place_name(place_name):
geocoder_object = geocoder.osm(place_name)
lon = geocoder_object.json.get("lng")
lat = geocoder_object.json.get("lat")
if lat is None or lon is None:
raise RuntimeError(
"Could not retrieve lon/lat for "
"place: {!r}".format(place_name)
)
point = qgis.core.QgsPointXY(lon, lat)
return point
def create_point_layer(point, layer_name, place_name):
layer = qgis.core.QgsVectorLayer(
"Point?crs=epsg:4326&field=address:string(100)",
layer_name,
"memory"
)
provider = layer.dataProvider()
geometry = qgis.core.QgsGeometry.fromPointXY(point)
feature = qgis.core.QgsFeature()
feature.setGeometry(geometry)
feature.setAttributes([place_name])
provider.addFeatures([feature])
layer.updateExtents()
return layer
Related
New here and to the world of python.
Generating a histogram plot where it changes color when a postcode is selected.
Now I have the main histogram but when the postcode is selected from the dropdown it gives the error. Unable to figure out how to resolve this. I have provided my full code below.
Let me know if more info is required to figure out the error. Something to do with input
import pandas as pd
import plotly.express as px
from dash import Dash, html, dcc, Input, Output
app = Dash(__name__)
app.title = "EGMs in NSW"
# Load your data : br = .....
datalist=pd.read_excel('premises-list-Aug-2022.xlsx',skiprows=[0,1,2])
datalist['Licence type'] = datalist['Licence type'].str.split(" - ").str.get(1)
datalist['Licence type'] = datalist['Licence type'].str.title()
postcode = datalist['Postcode']
postcode = postcode.sort_values(ascending=True)
postcode=list(dict.fromkeys(postcode))
pd.Series(datalist['Postcode'].unique()).sort_values(ascending=True)
def make_histogram_plot():
# Create scatter plot
fig=px.histogram(
data_frame = datalist,
x='Licence type',y='EGMs',color='Postcode',title='EGMs by Licence Type in NSW',
histfunc='avg'
)
fig.update_traces(marker=dict(color="#002664"))
fig.update_layout(
plot_bgcolor='#EAEDF4',
xaxis_title=None,
yaxis_title='Average EGMs'
)
return fig
app.layout = html.Div(children=[
html.Div([
dcc.Dropdown(postcode,value=[], placeholder="Select postcodes", multi=True, id='postcodes')
]),
dcc.Graph(id = 'graph',figure = make_histogram_plot())
])
#app.callback(
Output('graph','figure'),
Input('postcodes','value')
)
def dropdown_changed(postcodes):
if postcodes==[]:
fig = make_histogram_plot()
else:
datalist2 = datalist[datalist['Postcode'].isin(postcodes)],
# Create scatter plot
fig=px.histogram(
data_frame = datalist2,
x='Licence type',y='EGMs',color='Postcode',title='EGMs by Licence Type in NSW',
histfunc='avg'
)
fig.update_traces(marker=dict(color="#002664"))
fig.update_layout(
plot_bgcolor='#EAEDF4',
xaxis_title=None,
yaxis_title='Average EGMs'
)
return fig
# Start the server
if __name__ == '__main__':
app.run_server(debug=True)
I'm trying to learn Flask and use postgresql with it. I'm following this tutorial https://realpython.com/flask-by-example-part-2-postgres-sqlalchemy-and-alembic/, but I keep getting error.
Cannot import name 'AorticStenosis' from partially initialized module 'models' (most likely due to a circular import)
I understand the problem, but I can't figure out how to fix it. So, I started playing around and try to use the steps by step tutorial on something that I'm working on, but I still get the same problem.
Here's my attempt:
Models.py
from app import db
class AorticStenosis(db.Model):
__tablename__ = 'wvu-model'
id = db.Column(db.Integer, primary_key=True)
ip_address = db.Column(db.String())
date_created = db.Column(db.DateTime, default=datetime.utcnow)
e_prime = db.Column(db.Float())
LVMi = db.Column(db.Float())
A = db.Column(db.Float())
LAVi = db.Column(db.Float())
E_e_prime = db.Column(db.Float())
EF = db.Column(db.Float())
E = db.Column(db.Float())
E_A = db.Column(db.Float())
TRV = db.Column(db.Float())
prediction = db.Column(db.String())
def __init__(self, ip_address, e_prime, LVMi, A, E_e_prime, EF, E, E_A, TRV, prediction):
print('initialized')
self.ip_address = ip_address
self.e_prime = e_prime
self.LVMi = LVMi
self.A = A
self.LAVi = LAVi
self.E_e_prime = E_e_prime
self.EF = EF
self.E = E
self.E_A = E_A
self.TRV = TRV
self.prediction = prediction
def __repr__(self):
return '<id {}>'.format(self.id)
app.py
import os
import ast
import bcrypt
from flask import Flask, redirect, render_template, request, session, url_for
import flask_login
from flask_sqlalchemy import SQLAlchemy
from bigml.deepnet import Deepnet
from bigml.api import BigML
import pickle as pkl
import sklearn
app = Flask(__name__)
if app.config['ENV'] == 'production':
app.config.from_object('as_config.ProductionConfig')
else:
app.config.from_object("config.DevelopmentConfig")
# app.config.from_pyfile('as_config.py')
# app.config.from_object(os.environ['APP_SETTINGS'])
# app.config.from_object('as_config.DevelopmentConfig')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
from models import AorticStenosis
login_key = app.config['LOGIN_KEY']
api_key = app.config['API_KEY']
model = app.config['MODEL']
api = BigML(login_key, api_key)
deepnet = Deepnet(model, api=api)
scaler = pkl.load(open("scaler.pkl", "rb"))
#app.route("/", methods=["GET", "POST"])
def home():
prediction = None
if request.method == "POST":
form_data = [
float(request.form.get("e_prime")),
float(request.form.get("LVMi")),
float(request.form.get("A")),
float(request.form.get("LAVi")),
float(request.form.get("E_e_prime")),
float(request.form.get("EF")),
float(request.form.get("E")),
float(request.form.get("E_A")),
float(request.form.get("TRV"))
]
form_data = scaler.transform([form_data])[0]
print(form_data)
prediction = str(deepnet.predict({
"e_prime": form_data[0],
"LVMi": form_data[1],
"A": form_data[2],
"LAVi": form_data[3],
"E_e_prime": form_data[4],
"EF": form_data[5],
"E": form_data[6],
"E_A": form_data[7],
"TRV": form_data[8]
}, full=True))
prediction = ast.literal_eval(prediction)
print(prediction)
## get ip address from the user
ip_address = request.environ['REMOTE_ADDR']
print("ip_address: ", ip_address)
try:
aorticStenosis = AorticStenosis(
ip_address = ip_address,
e_prime = form_data[0],
LVMi = form_data[1],
A = form_data[2],
LAVi = form_data[3],
E_e_prime = form_data[4],
EF = form_data[5],
E = form_data[6],
E_A = form_data[7],
TRV = form_data[8]
)
db.session.add(aorticStenosis)
db.session.commit()
except Exception as e:
print(str(e))
if prediction["prediction"] == "1":
prediction["prediction"] = "Low Risk"
prediction["probability"] = round(
1 - prediction["probability"], 6)
elif prediction["prediction"] == "2":
prediction["prediction"] = "High Risk"
else:
prediction["prediction"] = "No prediction was made!"
return render_template("home.html",
prediction=prediction["prediction"],
probability=prediction["probability"])
else:
return render_template("home.html")
if __name__ == "__main__":
app.run(host="0.0.0.0", port="8000")
I made a new file database.py and defined db there.
database.py
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
def init_app(app):
db.init_app(app)
app.py
import database
...
database.init_app(app)
models.py
from database import db
...
I would like to access variable lotId & qty_selected in class 'InputDialog' and to be use in class 'Mainwindow'. I did tried to find a solution in net but unable to solve it until now. can anyone show how to make it?
Here is my current code:
from __future__ import division
from skimage.measure import compare_ssim as ssim
import matplotlib.pyplot as plt
import numpy as np
import sys
import os, glob
import cv2
from PyQt4 import QtCore, QtGui, uic
from PyQt4.QtGui import *
from inputdialog import Ui_inputDialog
from mainwindow import Ui_mainWindow
from tkinter import messagebox
class MainWindow(QtGui.QMainWindow, Ui_mainWindow):
def __init__(self, class_input):
QtGui.QMainWindow.__init__(self)
Ui_mainWindow.__init__(self)
Ui_inputDialog.__init__(self)
self.setupUi(self)
self.capture_button.clicked.connect(self.captureImage)
self.display_button.clicked.connect(self.displayImage)
self.deviceBox.activated.connect(self.selectDeviceCombo)
self.startInspectionBtn.clicked.connect(self.enterLotID)
self.display_button.clicked.connect(self.displayResults)
#self.viewResultBtn.clicked.connect(self.viewResults)
self.window2 = None
def enterLotID(self): # Dialog box will ask user to enter lot ID and wafer qty
if self.window2 is None:
self.window2 = InputDialog(self)
self.window2.isModal()
self.window2.show()
# Program need to be loop through a image file in directory
def displayImage(self, ):
os.chdir('c:\\Users\\mohd_faizal4\\Desktop\\Python\\Testing' + '\\' + lotId )
for lotId in glob.glob('*.jpeg'):
print(lotId)
sample_label = 'c:/Users/mohd_faizal4/Desktop/Python/Image/Picture 6.jpg' # Sample image must read from current folder lot ID running the inspection
self.sample_label.setScaledContents(True)
self.sample_label.setPixmap(QtGui.QPixmap(sample_label))
def selectDeviceCombo(self):
self.var_Selected = self.deviceBox.currentText()
#print('The user selected value now is:')
print('Device = ' + self.var_Selected)
if self.var_Selected.lower() == 'xf35':
print("Great! Device Id is - " + self.var_Selected + '!')
source_label ='c:/Users/mohd_faizal4/Desktop/Python/Image/Picture 4.jpg'
self.source_label.setScaledContents(True)
self.source_label.setPixmap(QtGui.QPixmap(source_label))
elif self.var_Selected.lower() == 'xf38':
print("Great! Device Id is - " + self.var_Selected + '!')
source_label ='c:/Users/mohd_faizal4/Desktop/Python/Image/Picture 5.jpg'
self.source_label.setScaledContents(True)
self.source_label.setPixmap(QtGui.QPixmap(source_label))
elif self.var_Selected.lower() == 'x38c':
print("Great! Device Id is - " + self.var_Selected + '!')
source_label ='c:/Users/mohd_faizal4/Desktop/Python/Image/Picture 7.jpg'
self.source_label.setScaledContents(True)
self.source_label.setPixmap(QtGui.QPixmap(source_label))
else:
print("Pls select device id. It's compulsory field!")
def captureImage(self): # Capture image and display on 'Sample' column under Inspection
cam = cv2.VideoCapture(0)
i = 1
while i < int(input(qty_selected)):
ret, frame = cam.read()
cv2.imshow('Please review an image', frame)
if not ret:
break
k = cv2.waitKey(0)
if k%256 == 27:
# ESC pressed
print("Escape hit, closing...")
break
if k % 256 == 32:
# SPACE pressed
img_name = "_{}.jpeg".format(i)
#print (img_name)
cv2.imwrite(img_name, frame)
#cv2.imwrite(os.path.join(dirname, img_name), frame)
print("{}".format(img_name))
i += 1
cam.release()
cv2.destroyAllWindows()
def displayResults(self): #Display image of wafer at 'Result' tab. Simultaneously with 'Inspect'
label_vid01 = 'c:/Users/mohd_faizal4/Desktop/Python/Image/Picture 7.jpg'
self.label_vid01.setScaledContents(True)
self.label_vid01.setPixmap(QtGui.QPixmap(label_vid01))
# A new class for user input dialog to enter lot information
class InputDialog (QtGui.QDialog, Ui_inputDialog):
def __init__(self, parent):
QtGui.QWidget.__init__(self, parent)
self.setupUi(self)
self.okButton.clicked.connect(self.addLotId)
self.okButton.clicked.connect(self.selectWaferQty)
def addLotId(self):
lotId = str(self.strLotId.toPlainText())
self.strLotId.setText(lotId)
print(lotId)
path = 'c:\\Users\\mohd_faizal4\\Desktop\\Python\\Testing' + '\\' + lotId
if not os.path.exists(path):
os.makedirs(path)
else:
messagebox.showwarning('Error','Please enter required information')
QtGui.QMessageBox.show(self)
# User require to select wafer quantity upon enter the lot ID
def selectWaferQty(self):
qty_selected = self.waferQty.currentText()
#print ('The user selected value now is:')
print ('Wafer Qty = ' + qty_selected)
#if self.qty_selected() == '1':
# print('Great! Wafer Qty is - ' + self.qty_selected + '!')
#else:
# print ('Pls select wafer quantity!')
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
Window = MainWindow()
Window.show()
sys.exit()
Under the class InputDialog, change lotId and qty_selected to self.lotId and self.qty_selected, respectively. And to access it inside your WindowMain class, try self.window2.lotId and self.window2.qty_selected.
I try to use the django REST-framework's tutorial http://django-rest-framework.org/#django-rest-framework to administrate users. (I also use the Neo4j database and the neo4django mapper https://github.com/scholrly/neo4django to acces data via python.)
Whatever, wen I call localhost:8000/users an AttributeError appears.
models.py
from django.utils import timezone
from django.conf import settings
from django.contrib.auth import models as django_auth_models
from ..db import models
from ..db.models.manager import NodeModelManager
from ..decorators import borrows_methods
class UserManager(NodeModelManager, django_auth_models.UserManager):
pass
# all non-overriden methods of DjangoUser are called this way instead.
# inheritance would be preferred, but isn't an option because of conflicting
# metaclasses and weird class side-effects
USER_PASSTHROUGH_METHODS = (
"__unicode__", "natural_key", "get_absolute_url",
"is_anonymous", "is_authenticated", "get_full_name", "set_password",
"check_password", "set_unusable_password", "has_usable_password",
"get_group_permissions", "get_all_permissions", "has_perm", "has_perms",
"has_module_perms", "email_user", 'get_profile','get_username')
#borrows_methods(django_auth_models.User, USER_PASSTHROUGH_METHODS)
class User(models.NodeModel):
objects = UserManager()
username = models.StringProperty(indexed=True, unique=True)
first_name = models.StringProperty()
last_name = models.StringProperty()
email = models.EmailProperty(indexed=True)
password = models.StringProperty()
is_staff = models.BooleanProperty(default=False)
is_active = models.BooleanProperty(default=False)
is_superuser = models.BooleanProperty(default=False)
last_login = models.DateTimeProperty(default=timezone.now())
date_joined = models.DateTimeProperty(default=timezone.now())
USERNAME_FIELD = 'username'
REQUIRED_FIELDS=['email']
serializers.py
from neo4django.graph_auth.models import User
from rest_framework import serializers
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ('url', 'username', 'email')
views.py
from neo4django.graph_auth.models import User
from rest_framework import viewsets
from api.serializers import UserSerializer
class UserViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows users to be viewed or edited.
"""
queryset = User.objects.all()
serializer_class = UserSerializer
I get this:
Environment:
Request Method: GET
Request URL: http://localhost:8000/users/
Django Version: 1.5.3
Python Version: 2.7.3
Installed Applications:
('core.models',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'neo4django.graph_auth',
'rest_framework')
Installed Middleware:
('django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware')
Traceback:
File "/opt/phaidra/env/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
115. response = callback(request, *callback_args, **callback_kwargs)
File "/opt/phaidra/env/local/lib/python2.7/site-packages/rest_framework/viewsets.py" in view
78. return self.dispatch(request, *args, **kwargs)
File "/opt/phaidra/env/local/lib/python2.7/site-packages/django/views/decorators/csrf.py" in wrapped_view
77. return view_func(*args, **kwargs)
File "/opt/phaidra/env/local/lib/python2.7/site-packages/rest_framework/views.py" in dispatch
399. response = self.handle_exception(exc)
File "/opt/phaidra/env/local/lib/python2.7/site-packages/rest_framework/views.py" in dispatch
396. response = handler(request, *args, **kwargs)
File "/opt/phaidra/env/local/lib/python2.7/site-packages/rest_framework/mixins.py" in list
92. serializer = self.get_pagination_serializer(page)
File "/opt/phaidra/env/local/lib/python2.7/site-packages/rest_framework/generics.py" in get_pagination_serializer
113. return pagination_serializer_class(instance=page, context=context)
File "/opt/phaidra/env/local/lib/python2.7/site-packages/rest_framework/pagination.py" in __init__
85. self.fields[results_field] = object_serializer(source='object_list', **context_kwarg)
File "/opt/phaidra/env/local/lib/python2.7/site-packages/rest_framework/serializers.py" in __init__
162. self.fields = self.get_fields()
File "/opt/phaidra/env/local/lib/python2.7/site-packages/rest_framework/serializers.py" in get_fields
198. default_fields = self.get_default_fields()
File "/opt/phaidra/env/local/lib/python2.7/site-packages/rest_framework/serializers.py" in get_default_fields
599. while pk_field.rel and pk_field.rel.parent_link:
Exception Type: AttributeError at /users/
Exception Value: 'IdLookup' object has no attribute 'rel'
I am rather new on the Python/Django/REST service area. I hope someone could help. Thanks in advance.
Firstly I would recommend to either use Tastypie - which is out of the box supported by neo4django - instead of Django Rest Framework - or use Django Rest Framework Serializer instead of the ModelSerializer or (worst choice in my opinion) HyperlinkedModelSerializer.
As for the error you get, the problem is that neo4django does not return the record id, therefore you get the error.
One solution is to override the restore_object function, like this, to include the ID.
# User Serializer
class UserSerializer(serializers.Serializer):
id = serializers.IntegerField()
username = serializers.CharField(max_length=30)
first_name = serializers.CharField(max_length=30)
last_name = serializers.CharField(max_length=30)
email = serializers.EmailField()
password = serializers.CharField(max_length=128)
is_staff = serializers.BooleanField()
is_active = serializers.BooleanField()
is_superuser = serializers.BooleanField()
last_login = serializers.DateTimeField()
date_joined = serializers.DateTimeField()
def restore_object(self, attrs, instance=None):
"""
Given a dictionary of deserialized field values, either update
an existing model instance, or create a new model instance.
"""
if instance is not None:
instance.id = attrs.get('ID', instance.pk)
instance.username = attrs.get('Username', instance.username)
instance.first_name = attrs.get('First Name', instance.first_name)
instance.last_name = attrs.get('First Name', instance.last_name)
instance.email = attrs.get('email', instance.email)
instance.password = attrs.get('Password', instance.password)
instance.is_staff = attrs.get('Staff', instance.is_staff)
instance.is_active = attrs.get('Active', instance.is_active)
instance.is_superuser = attrs.get('Superusers', instance.is_superuser)
instance.last_login = attrs.get('Last Seen', instance.last_login)
instance.date_joined = attrs.get('Joined', instance.date_joined)
return instance
return User(**attrs)
But I still think it's better to use Tastypie with ModelResource.
Here's a gist by Matt Luongo (or Lukas Martini ?) https://gist.github.com/mhluongo/5789513
TIP. Where Serializer in Django Rest Framework, is Resource in Tastypie and always make sure you are using the github version of neo4django (pip install -e git+https://github.com/scholrly/neo4django/#egg=neo4django)
I'm new to web app and I want to check when there's a new version of dota map, I'll check links in getdota.com.
How can I do this and which language, I want it checks every time you start warcraft, and auto download new map to specific folder.
My question is : Can you give a link to a specific article about web automation or something like that.
Thanks first :)
Below is an example in Python.
It parses getdota.com page, reads parameters for POST request for downloading a map, gets the file and saves it in configured directory (by default current directory).
#!/usr/bin/env python
import urllib
import urllib2
import sgmllib
from pprint import pprint
import os.path
import sys
url = 'http://www.getdota.com/'
download_url = 'http://www.getdota.com/app/getmap/'
chunk = 10000
directory = '' #directory where file should be saved, if empty uses current dir
class DotaParser(sgmllib.SGMLParser):
def parse(self, s):
self.feed(s)
self.close()
def __init__(self, verbose=0):
sgmllib.SGMLParser.__init__(self, verbose)
self.URL = ''
self.post_args = {}
def getArgs(self):
return self.post_args
def start_input(self, attributes):
d = dict(attributes)
if d.get('id', None) == None:
return
if d['id'] in ["input_mirror2", "input_file_name2", "input_map_id2", "input_language2", "input_language_id2"]:
self.post_args[d['name']] = d['value']
if __name__ == '__main__':
dotap = DotaParser()
data = urllib2.urlopen(urllib2.Request('http://www.getdota.com/')).read()
dotap.parse(data)
data = urllib.urlencode(dotap.getArgs())
request = urllib2.Request(download_url, data)
response = urllib2.urlopen(request)
page = response.read()
#download file
fname = directory + page.split('/')[-1]
if os.path.isfile(fname):
print "No newer file available"
sys.exit(0)
f = open(fname, 'w')
print "New file available. Saving in: %s" % fname
webFile = urllib.urlopen(page)
c = webFile.read(chunk)
while(c):
f.write(c)
c = webFile.read(chunk)
f.close()
webFile.close()