├── .gitignore ├── requirements.txt ├── README.md └── app.py /.gitignore: -------------------------------------------------------------------------------- 1 | flask/ 2 | .pyc 3 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Flask 2 | BeautifulSoup4 3 | requests 4 | urllib 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Unofficial Major League Hacking API 2 | 3 | Welcome to the Unoffical MLH API. This is not the offical API used by MLH, but simply one I made at CodeDay Winter 2015. 4 | The API is a simple REST made in Flask that utilizes BeautifulSoup. It scrapes information off of [mlh.io](http://mlh.io) and returns it in a neat JSON format. 5 | 6 | The index returns all the events for the current seasons, both in Europe and the US. Appending `s2015` for the current US season, and `eu-2015` for the European, provides all the information for its location respectively. 7 | 8 | The app returns basic information about each event including the offical id, data, link, location, and name. 9 | The mapping for an event is `event/name_of_event/`. In the following example the information is pulled from `event/dragon%20hacks/`. 10 | 11 | ``` json 12 | "Dragon Hacks": { 13 | "date": "January 10th - 11th", 14 | "id": "102", 15 | "link": "http://www.hack-dragon.com", 16 | "location": "Philadelphia, PA", 17 | "name": "Dragon Hacks" 18 | }, 19 | ``` 20 | You can also select individual querys of hackathons such as the `link` or `id` using the url mapping `/search/name_of_hackathon/value/`. For example `search/dragon%20hacks/date/` would return 21 | ``` text 22 | January 10th - 11th 23 | ``` 24 | 25 | or `search/dragon%20hacks/link/` would return 26 | ``` text 27 | http://www.hack-dragon.com 28 | ``` 29 | 30 | 31 | Feel free to edit and manipulate the code as you like. I hope this code is as useful as I thought it would be. 32 | -------------------------------------------------------------------------------- /app.py: -------------------------------------------------------------------------------- 1 | #!flask/bin/python 2 | from flask import Flask, jsonify 3 | from bs4 import BeautifulSoup 4 | import requests, time 5 | import urllib 6 | import datetime 7 | 8 | app = Flask(__name__) 9 | year = str(datetime.date.today().year) 10 | 11 | def request_stuff(season, events): 12 | mlh_url = "https://mlh.io/seasons/%s/events" % (season) 13 | mlh_html = requests.get(mlh_url) 14 | soup = BeautifulSoup(mlh_html.content) 15 | event_list = soup.find_all('div', {'class':'col-lg-3'}) 16 | for event_for in event_list: 17 | event_id = str(event_for) 18 | event_id = event_id[(event_id.find("event")+12):(event_id.find("event")+15)] 19 | if event_id in events: 20 | pass 21 | else: 22 | link_tag = str(event_for.find_all('a')) 23 | index = link_tag.find('"') + 1 24 | link = link_tag[index:] 25 | index = link.find('"') 26 | link = link[:index] 27 | 28 | img_tag = (event_for.findAll('img')) 29 | backgroundImage = img_tag[0]['src'] 30 | logo = img_tag[1]['src'] 31 | 32 | event_head = str(event_for.find_all('h3')) 33 | index = event_head.find(">") + 1 34 | event_head = event_head[index:] 35 | index = event_head.find("<") 36 | event_head = event_head[:index] 37 | 38 | event_date = str(event_for.find_all('p')) 39 | index = event_date.find(">") + 1 40 | event_date = event_date[index:] 41 | index = event_date.find("<") 42 | event_date = event_date[:index] 43 | 44 | #This is for getting the city 45 | event_loc = str(event_for.find_all('span')) 46 | index = event_loc.find(">") + 1 47 | event_loc = event_loc[index:] 48 | index = event_loc.find("<") 49 | event_loc_city = event_loc[:index] 50 | 51 | #This is for getting the state, I added +9 because after it was ending - 52 | #- at ", ". +9 just moves the pointer forward. 53 | event_loc = event_loc[index+9:] 54 | index = event_loc.find(">") + 1 55 | event_loc = event_loc[index:] 56 | index = event_loc.find("<") 57 | event_loc_state = event_loc[:index] 58 | event_loc = event_loc_city+ ", " + event_loc_state 59 | 60 | event = {} 61 | event["location"] = event_loc 62 | event["date"] = event_date 63 | event["name"] = event_head 64 | event["link"] = link 65 | event["id"] = event_id 66 | events[event_head] = event 67 | event["image_bg"] = backgroundImage 68 | event["image_logo"] = logo 69 | 70 | 71 | 72 | @app.route('/') 73 | def index(): 74 | us_event = {} 75 | request_stuff("s" + year, us_event) 76 | eu_event = {} 77 | request_stuff("s"+year+"-eu", eu_event) 78 | event_all = {"us_event":us_event,"eu_event":eu_event} 79 | return jsonify(event_all) 80 | 81 | 82 | @app.route('//') 83 | def select_season(mlh_season): 84 | events_all = {} 85 | while True: 86 | request_stuff(mlh_season, events_all) 87 | return jsonify(events_all) 88 | # time to wait until refresh 89 | time.sleep(1800) 90 | 91 | @app.route('/event//') 92 | def search_event(mlh_event): 93 | us_event = {} 94 | request_stuff("s"+year, us_event) 95 | eu_event = {} 96 | request_stuff("s"+year+"-eu", eu_event) 97 | for evnt in us_event: 98 | if urllib.unquote(mlh_event.lower()) == evnt.lower(): 99 | return jsonify(us_event[evnt]) 100 | else: 101 | for i in eu_event: 102 | if urllib.unquote(mlh_event.lower()) == i.lower(): 103 | return jsonify(eu_event[i]) 104 | 105 | @app.route('/search///') 106 | 107 | def search_by_key(mlh_event, key_): 108 | us_event = {} 109 | request_stuff("s"+year, us_event) 110 | eu_event = {} 111 | request_stuff("s"+year+"-eu", eu_event) 112 | for evnt in us_event: 113 | if urllib.unquote(mlh_event.lower()) == evnt.lower(): 114 | return us_event[evnt][key_] 115 | else: 116 | for i in eu_event: 117 | if urllib.unquote(mlh_event.lower()) == i.lower(): 118 | return eu_event[i][key_] 119 | 120 | 121 | if __name__ == '__main__': 122 | app.run(debug=True, port=50981 123 | ) 124 | --------------------------------------------------------------------------------