Instantly share code, notes, and snippets.
Created
August 26, 2011 13:07
-
Star
1
(1)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
-
Save qoda/1173359 to your computer and use it in GitHub Desktop.
social_users.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #! /usr/bin/env python | |
| import pickle | |
| import re | |
| from db import Database | |
| # instanciate the database class | |
| db = Database( | |
| db_host = '*******', | |
| db_name = '*******', | |
| db_username = '****', | |
| db_password = '***********', | |
| ) | |
| # open the pickled country/city mapping and create a country set | |
| populated_city_pkl_file = open('country_populated_city.pkl', 'r') | |
| populated_city_mapping = pickle.load(populated_city_pkl_file) | |
| populated_city_pkl_file.close() | |
| all_city_pkl_file = open('country_city.pkl', 'r') | |
| all_city_mapping = pickle.load(all_city_pkl_file) | |
| country_list = [[k, v['name'].lower()] for k, v in all_city_mapping.items()] | |
| all_city_pkl_file.close() | |
| # instanciate a cache list for faster searching for already determined location strings | |
| # NB: includes a few hacks | |
| cached_locations = [ | |
| ['US', 'USA'], | |
| ['GB', 'UK'], | |
| ['US', 'US of A'], | |
| ['US', 'States'], | |
| ['US', 'Florida'], | |
| ['US', 'California'], | |
| ] | |
| cached_country_ids = [ | |
| [250, None] | |
| ] | |
| def group_by(results, key='location'): | |
| # remove bad chars and sort the results | |
| results = [r for r in results if not r.update({key: re.sub(r"[\n|\r|\t]", " ", r[key]).strip()})] | |
| sorted_results = [r for r in sorted(results, key=lambda k: k[key])] | |
| prev_location = None | |
| grouped_results = [] | |
| unique_counter = -1 | |
| for result in sorted_results: | |
| if prev_location == result[key]: | |
| grouped_results[unique_counter].append(result) | |
| else: | |
| grouped_results.append([result]) | |
| unique_counter += 1 | |
| prev_location = result[key] | |
| return grouped_results | |
| def parse_location(location): | |
| # return blank to be processed as global if no location is provided | |
| if not location: | |
| return [] | |
| # split the location by puncutuated phrases | |
| location_split = [phrase.strip().lower() for phrase in re.split(r'[,|\-|)|(|.|\||#|\:|\\|\/]', location) if phrase] | |
| possible_matches =[] | |
| city_name = None | |
| # test if the country name or code is already present in the location string | |
| for country in country_list: | |
| if country[1] in location_split: | |
| return [country[0]] | |
| elif country[0] in location_split: | |
| return [country[0]] | |
| # check if the city name is in the cache list | |
| for location in cached_locations: | |
| if location[1].lower() in location_split: | |
| return [location[0]] | |
| # iterate through the short list mapping to find a matching city name | |
| for country_code, country_dict in populated_city_mapping.items(): | |
| for city in country_dict['city_info']: | |
| if city[0].lower() in location_split: | |
| possible_matches.append([country_code, city[1]]) | |
| city_name = city[0] | |
| # iterate through the full mapping to find a matching city name | |
| if not city_name: | |
| for country_code, country_dict in all_city_mapping.items(): | |
| for city in country_dict['city_info']: | |
| if city[0].lower() in location_split: | |
| possible_matches.append([country_code, city[1]]) | |
| city_name = city[0] | |
| # sort the matched country list by cities population to increase accuracy by probability | |
| sorted_matches = [i[0] for i in sorted(possible_matches, key=lambda k: k[1], reverse=True)] | |
| # add the city to the cached list | |
| if city_name: | |
| if [sorted_matches[0], city_name] not in cached_locations: | |
| cached_locations.append([sorted_matches[0], city_name]) | |
| return sorted_matches | |
| def get_country_id(country_code): | |
| for c in cached_country_ids: | |
| if country_code == c[1]: | |
| return c[0] | |
| sql = "SELECT id FROM countries WHERE abbr2='%s'" % country_code | |
| country = db.get(sql) | |
| if country: | |
| cached_country_ids.append([country['id'], country_code]) | |
| return country['id'] | |
| return 250 | |
| def get_twitter_users(limit=None): | |
| sql = "SELECT id, username, name, location FROM twitter_users" | |
| if limit: | |
| sql += " LIMIT %s, %s" % (limit[0], limit[1]) | |
| return group_by(db.list(sql)) | |
| def twitter_user_exists(grouped_twitter_users): | |
| for twitter_user in grouped_twitter_users: | |
| sql = "SELECT id FROM social_users WHERE twitterId = %s" % twitter_user['id'] | |
| if not db.list(sql): | |
| return False | |
| return True | |
| def process_twitter_users(data): | |
| country_id = get_country_id(data['country_code']) | |
| try: | |
| db.execute( | |
| "INSERT INTO social_users (username, full_name, countryId, twitterId) VALUES (%s, %s, %s, %s)", ( | |
| data['username'], | |
| data['name'], | |
| country_id, | |
| data['id'], | |
| ) | |
| ) | |
| return True | |
| except: | |
| return False | |
| def get_facebook_users(): | |
| sql = "SELECT id, username, name, location, gender FROM facebook_users ORDER BY location" | |
| return db.list(sql) | |
| def process_facebook_users(): | |
| try: | |
| db.execute( | |
| "INSERT INTO social_users (username, full_name, gender, countryId, facebookId) VALUES (%s, %s, %s, %s, %s)", ( | |
| data['username'], | |
| data['name'], | |
| data['gender'], | |
| get_country_id(data['country_code']), | |
| data['id'], | |
| ) | |
| ) | |
| return True | |
| except: | |
| return False | |
| if __name__ == '__main__': | |
| count = 1 | |
| for grouped_twitter_users in get_twitter_users(): | |
| if not twitter_user_exists(grouped_twitter_users): | |
| try: | |
| country_code = parse_location(grouped_twitter_users[0]['location'])[0] | |
| except IndexError: | |
| country_code = None | |
| for twitter_user in grouped_twitter_users: | |
| twitter_user['country_code'] = country_code | |
| if process_twitter_users(twitter_user): | |
| print "INSERT(%s): %s" % (count, twitter_user) | |
| else: | |
| print "FAILED(%s): %s" % (count, twitter_user) | |
| count += 1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment