patternpythonMinor
Mutual friends finder written in Python
Viewed 0 times
writtenfinderpythonmutualfriends
Problem
I've written a server/client tool which can "check the Six degrees of separation theory" in Russian social network VK.com. Client sends task (which contains two VK IDs) and Server tries to find all connections between these two IDs. I've also written a simple HTTP client just to practice working with sockets.
HTTPClient.py:
VKApi.py:
```
import HTTPClient
import json
import re
import types
import md5
import time
class BaseAPIException(Exception):
def __init__(self, text=''):
Exception.__init__(self,text)
class LoginException(BaseAPIException):
pass
class MethodExecutionException(BaseAPIException):
pass
class VKApi:
def __init__(self,appId,scope=[],callbackUrl='https://oauth.vk.com/blank.html'):
self.appId = appId
if ( not isinstance(scope,types.ListType)): raise Exception("Wrong args")
scope.append('nohttps')
self.scope = ','.join(scope)
self.callbackUrl=callbackUrl
self.isLoggedIn = False
self.callsCount = 0
def getAuthorizeLink(self):
return "https://oauth.vk.com/authorize?client_id=%s&scope=%s&redirect_uri=%s&display=page&v=5.21&response_type=token" % \
(self.appId, self.scope, self.callbackUrl)
def login(self, link):
tokenRegExp = re.search('access_token=(.*?)(&|$)',link)
if tokenRegExp == None: raise LoginException('No token found')
self.token = tokenRegExp.group(1)
secretRegExp = re.search('secret=(.*?)(&|$)',link)
if secretRegExp == None: raise LoginException('No secret found')
self.secret = s
HTTPClient.py:
import socket
import re
def get(host, port, address):
s = socket.socket()
s.connect((host,port))
s.sendall("GET %s HTTP/1.0\nHost: %s\n\n" % (address, host))
answer = ""
symbol = s.recv(1024576)
while symbol != '':
answer += symbol
symbol = s.recv(1024576)
s.close()
answer = re.search("\r\n\r\n(.+)", answer, re.DOTALL).group(1)
return answerVKApi.py:
```
import HTTPClient
import json
import re
import types
import md5
import time
class BaseAPIException(Exception):
def __init__(self, text=''):
Exception.__init__(self,text)
class LoginException(BaseAPIException):
pass
class MethodExecutionException(BaseAPIException):
pass
class VKApi:
def __init__(self,appId,scope=[],callbackUrl='https://oauth.vk.com/blank.html'):
self.appId = appId
if ( not isinstance(scope,types.ListType)): raise Exception("Wrong args")
scope.append('nohttps')
self.scope = ','.join(scope)
self.callbackUrl=callbackUrl
self.isLoggedIn = False
self.callsCount = 0
def getAuthorizeLink(self):
return "https://oauth.vk.com/authorize?client_id=%s&scope=%s&redirect_uri=%s&display=page&v=5.21&response_type=token" % \
(self.appId, self.scope, self.callbackUrl)
def login(self, link):
tokenRegExp = re.search('access_token=(.*?)(&|$)',link)
if tokenRegExp == None: raise LoginException('No token found')
self.token = tokenRegExp.group(1)
secretRegExp = re.search('secret=(.*?)(&|$)',link)
if secretRegExp == None: raise LoginException('No secret found')
self.secret = s
Solution
That's quite a lot of code to review. I'll review only some parts.
HTTPClient.py
Instead of using magic number 1024576 twice,
it's better to give it a meaningful name and put it near the top of the file where it's easy to see, for example:
In this piece of code:
The name "symbol" is not great. A symbol usually suggests a single character, but here it's an entire buffer. And instead of checking for
At the end of the method you strip the header from the response like this:
In my tests, some sites don't actually return a proper header, the expression will match nothing, and so the
Exception handling
This exception class can be simplified:
This is equivalent:
Non-standard formatting
There's an official coding style guide called PEP8. You are violating it everywhere, making your code harder to read than it needs to be. For example:
This should be formatted like this to conform to the standard:
Your code is full of this kind of violations. There is a command line utility called pep8, which you can install easily with
Checking for
Instead of this:
The recommended way is this:
Or even simpler:
HTTPClient.py
Instead of using magic number 1024576 twice,
it's better to give it a meaningful name and put it near the top of the file where it's easy to see, for example:
BUFSIZE = 1024576In this piece of code:
symbol = s.recv(1024576)
while symbol != '':
answer += symbol
symbol = s.recv(1024576)The name "symbol" is not great. A symbol usually suggests a single character, but here it's an entire buffer. And instead of checking for
symbol != '', a more Pythonic way is to do not symbol. Finally, the statement symbol = s.recv(1024576) is repeated twice. A better way to write the same thing:while True:
buf = s.recv(BUFSIZE)
if not buf:
break
answer += bufAt the end of the method you strip the header from the response like this:
answer = re.search("\r\n\r\n(.+)", answer, re.DOTALL).group(1)
return answerIn my tests, some sites don't actually return a proper header, the expression will match nothing, and so the
.group(1) will raise an error. To make it more robust, I recommend to rewrite like this:return re.sub(".*\r\n\r\n", '', answer, flags=re.DOTALL)Exception handling
This exception class can be simplified:
class BaseAPIException(Exception):
def __init__(self, text=''):
Exception.__init__(self,text)This is equivalent:
class BaseAPIException(Exception):
passNon-standard formatting
There's an official coding style guide called PEP8. You are violating it everywhere, making your code harder to read than it needs to be. For example:
def __init__(self,appId,scope=[],callbackUrl='https://oauth.vk.com/blank.html'):
self.appId = appId
if ( not isinstance(scope,types.ListType)): raise Exception("Wrong args")
scope.append('nohttps')
self.scope = ','.join(scope)
self.callbackUrl=callbackUrl
self.isLoggedIn = False
self.callsCount = 0This should be formatted like this to conform to the standard:
def __init__(self, appId, scope=[], callbackUrl='https://oauth.vk.com/blank.html'):
self.appId = appId
if not isinstance(scope, types.ListType):
raise Exception("Wrong args")
scope.append('nohttps')
self.scope = ','.join(scope)
self.callbackUrl = callbackUrl
self.isLoggedIn = False
self.callsCount = 0Your code is full of this kind of violations. There is a command line utility called pep8, which you can install easily with
pip install pep8, which can tell you all the violations.Checking for
NoneInstead of this:
if tokenRegExp == None:The recommended way is this:
if tokenRegExp is None:Or even simpler:
if not tokenRegExp:Code Snippets
BUFSIZE = 1024576symbol = s.recv(1024576)
while symbol != '':
answer += symbol
symbol = s.recv(1024576)while True:
buf = s.recv(BUFSIZE)
if not buf:
break
answer += bufanswer = re.search("\r\n\r\n(.+)", answer, re.DOTALL).group(1)
return answerreturn re.sub(".*\r\n\r\n", '', answer, flags=re.DOTALL)Context
StackExchange Code Review Q#60886, answer score: 3
Revisions (0)
No revisions yet.