├── hackathon_starter ├── hackathon │ ├── __init__.py │ ├── scripts │ │ ├── __init__.py │ │ ├── twilioapi.py │ │ ├── meetup.py │ │ ├── nytimes.py │ │ ├── steam.py │ │ ├── yelp.py │ │ ├── dropbox.py │ │ ├── quandl.py │ │ ├── linkedin.py │ │ ├── scraper.py │ │ ├── googlePlus.py │ │ ├── facebook.py │ │ ├── tumblr.py │ │ ├── instagram.py │ │ ├── twitter.py │ │ ├── github.py │ │ └── .pylintrc │ ├── migrations │ │ └── __init__.py │ ├── unittests │ │ ├── __init__.py │ │ ├── testcase.py │ │ ├── testinstagram.py │ │ ├── teststeam.py │ │ ├── testtumblr.py │ │ └── testgithub.py │ ├── static │ │ ├── img │ │ │ ├── github.png │ │ │ ├── steam.png │ │ │ ├── tumblr.png │ │ │ └── linkedin.jpg │ │ └── css │ │ │ └── form.css │ ├── serializers.py │ ├── forms.py │ ├── admin.py │ ├── templates │ │ └── hackathon │ │ │ ├── instagram.html │ │ │ ├── steam.html │ │ │ ├── twilio.html │ │ │ ├── instagram_q.html │ │ │ ├── meetup.html │ │ │ ├── googlePlus.html │ │ │ ├── tumblr.html │ │ │ ├── linkedin.html │ │ │ ├── register.html │ │ │ ├── twitter_tweet.html │ │ │ ├── dropbox.html │ │ │ ├── githubTopRepositories.html │ │ │ ├── twitter.html │ │ │ ├── facebookAPIExample.html │ │ │ ├── dropboxSearchFile.html │ │ │ ├── yelp.html │ │ │ ├── nytimes.html │ │ │ ├── github.html │ │ │ ├── base.html │ │ │ ├── login.html │ │ │ ├── index.html │ │ │ ├── quandl.html │ │ │ ├── githubResume.html │ │ │ └── api_examples.html │ ├── urls.py │ ├── models.py │ └── tests.py ├── hackathon_starter │ ├── __init__.py │ ├── urls.py │ ├── wsgi.py │ └── settings.py ├── manage.py ├── index.rst ├── Makefile ├── make.bat └── conf.py ├── .bowerrc ├── .gitignore ├── bower.json ├── requirements.txt └── .pylintrc /hackathon_starter/hackathon/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/scripts/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon_starter/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/unittests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "hackathon_starter/hackathon/static/bower_components" 3 | } 4 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/static/img/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexurquhart/django-hackathon-starter/master/hackathon_starter/hackathon/static/img/github.png -------------------------------------------------------------------------------- /hackathon_starter/hackathon/static/img/steam.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexurquhart/django-hackathon-starter/master/hackathon_starter/hackathon/static/img/steam.png -------------------------------------------------------------------------------- /hackathon_starter/hackathon/static/img/tumblr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexurquhart/django-hackathon-starter/master/hackathon_starter/hackathon/static/img/tumblr.png -------------------------------------------------------------------------------- /hackathon_starter/hackathon/static/img/linkedin.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexurquhart/django-hackathon-starter/master/hackathon_starter/hackathon/static/img/linkedin.jpg -------------------------------------------------------------------------------- /hackathon_starter/hackathon/unittests/testcase.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | def fun(x): 4 | return x + 1 5 | 6 | class MyTest(unittest.TestCase): 7 | def test(self): 8 | self.assertEqual(fun(3), 4) -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | db.sqlite3 3 | *.pyc 4 | hackathon_starter/hackathon/static/bower_components/ 5 | migrations/ 6 | Thumbs.db 7 | */vendor 8 | ionic/platforms 9 | hackathon_starter/_build 10 | hackathon_starter/_static 11 | hackathon_starter/_templates 12 | .coverage -------------------------------------------------------------------------------- /hackathon_starter/hackathon/serializers.py: -------------------------------------------------------------------------------- 1 | from django.forms import widgets 2 | from rest_framework import serializers 3 | from hackathon.models import Snippet 4 | 5 | 6 | class SnippetSerializer(serializers.ModelSerializer): 7 | class Meta: 8 | model = Snippet 9 | fields = ('id', 'title', 'code', 'linenos') -------------------------------------------------------------------------------- /hackathon_starter/hackathon_starter/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import patterns, include, url 2 | from django.contrib import admin 3 | 4 | urlpatterns = patterns('', 5 | url(r'^hackathon/', include('hackathon.urls')), 6 | url(r'^admin/', include(admin.site.urls)), 7 | # url(r'^openid/(.*)', SessionConsumer()), 8 | ) 9 | -------------------------------------------------------------------------------- /hackathon_starter/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "hackathon_starter.settings") 7 | 8 | from django.core.management import execute_from_command_line 9 | 10 | execute_from_command_line(sys.argv) 11 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/forms.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth.forms import UserCreationForm 2 | from django.contrib.auth.models import User 3 | from django import forms 4 | from hackathon.models import UserProfile 5 | 6 | class UserForm(forms.ModelForm): 7 | password = forms.CharField(widget=forms.PasswordInput()) 8 | 9 | class Meta: 10 | model = User 11 | fields = ('username', 'email', 'password') 12 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon_starter/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for hackathon_starter project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.7/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "hackathon_starter.settings") 12 | 13 | from django.core.wsgi import get_wsgi_application 14 | application = get_wsgi_application() 15 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "django-hackathon-starter", 3 | "version": "0.0.0", 4 | "authors": [ 5 | "David Leonard " 6 | ], 7 | "description": "Django boilerplate project for hackathons", 8 | "keywords": [ 9 | "Django", 10 | "Python", 11 | "API", 12 | "RESTful" 13 | ], 14 | "license": "MIT", 15 | "dependencies": { 16 | "bootstrap": "~3.3.4", 17 | "jquery": "~2.1.3", 18 | "bootstrap-social": "~4", 19 | "d3": "~3.5.5" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/static/css/form.css: -------------------------------------------------------------------------------- 1 | 2 | div.well{ 3 | height: 250px; 4 | } 5 | 6 | .Absolute-Center { 7 | margin: auto; 8 | position: absolute; 9 | top: 0; left: 0; bottom: 0; right: 0; 10 | } 11 | 12 | .Absolute-Center.is-Responsive { 13 | width: 50%; 14 | height: 50%; 15 | min-width: 200px; 16 | max-width: 400px; 17 | padding: 40px; 18 | } 19 | 20 | #logo-container{ 21 | margin: auto; 22 | margin-bottom: 10px; 23 | width:200px; 24 | height:30px; 25 | background-image:url('http://placehold.it/200x30/000000/ffffff/&text=Django+Hackathon+Starter'); 26 | } -------------------------------------------------------------------------------- /hackathon_starter/hackathon/scripts/twilioapi.py: -------------------------------------------------------------------------------- 1 | # pylint: disable=invalid-name 2 | # pylint: disable=unused-variable 3 | 4 | ''' 5 | Twilioapi.py is responsible for sending 6 | a message from a registered Twilio number 7 | to a user's phone. 8 | ''' 9 | from twilio.rest import TwilioRestClient 10 | 11 | account_sid = "AC7889a1889c1833bd7181e45e60372776" 12 | auth_token = "1ad0315f3cc7a154aaaef048f1304f71" 13 | client = TwilioRestClient(account_sid, auth_token) 14 | 15 | def sendSMS(body, to, sender): 16 | 17 | '''Sends a message to a given number''' 18 | message = client.messages.create(body=body, to=to, from_=sender) 19 | return 20 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from hackathon.models import UserProfile, Profile, InstagramProfile, TwitterProfile, MeetupToken, GithubProfile, LinkedinProfile, TumblrProfile 3 | 4 | # Register your models here. 5 | class TwitterProfileAdmin(admin.ModelAdmin): 6 | list_display = ('user','twitter_user') 7 | 8 | admin.site.register(UserProfile) 9 | admin.site.register(Profile) 10 | admin.site.register(InstagramProfile) 11 | admin.site.register(TwitterProfile, TwitterProfileAdmin) 12 | admin.site.register(GithubProfile) 13 | admin.site.register(MeetupToken) 14 | admin.site.register(LinkedinProfile) 15 | admin.site.register(TumblrProfile) 16 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/scripts/meetup.py: -------------------------------------------------------------------------------- 1 | ''' 2 | meetup.py aggregates various data from meetup.com. 3 | ''' 4 | 5 | import requests 6 | import simplejson as json 7 | 8 | USERDATA = 'https://api.meetup.com/2/member/self/?access_token=' 9 | 10 | def retrieveUserData(url): 11 | '''Returns user profile info from meetup.com profile''' 12 | req = requests.get(url) 13 | content = json.loads(req.content) 14 | filteredData = [] 15 | data = {} 16 | data['name'] = content['name'] 17 | data['country'] = content['country'].upper() 18 | data['city'] = content['city'] 19 | data['state'] = content['state'] 20 | data['status'] = content['status'] 21 | filteredData.append(data) 22 | return filteredData 23 | 24 | 25 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/scripts/nytimes.py: -------------------------------------------------------------------------------- 1 | '''module containing a handful of methods for aggregating 2 | data from the NY Times.''' 3 | 4 | import requests 5 | import json 6 | 7 | def fetcharticle(apikey, url): 8 | '''returns the JSON data of the most 9 | popular articles by view from the past 24 hours.''' 10 | parameters = {'api-key' : apikey} 11 | req = requests.get(url, params=parameters) 12 | data = json.loads(req.content) 13 | parsedData = [] 14 | for datum in data['results']: 15 | newData = { 16 | "title": datum["title"], 17 | "abstract": datum["abstract"], 18 | "section": datum["section"], 19 | "byline": datum["byline"], 20 | } 21 | parsedData.append(newData) 22 | return parsedData 23 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Babel==1.3 2 | Django==1.7.6 3 | Jinja2==2.7.3 4 | MarkupSafe==0.23 5 | PyTumblr==0.0.6 6 | Pygments==2.0.2 7 | Sphinx==1.3.1 8 | alabaster==0.7.3 9 | astroid==1.3.6 10 | beautifulsoup4==4.3.2 11 | coverage==4.0a5 12 | django-bootstrap-form==3.2 13 | django-bootstrap-forms==0.1 14 | django-bower==5.0.2 15 | django-cors-headers==1.0.0 16 | django-nose==1.3 17 | djangorestframework==3.1.1 18 | docutils==0.12 19 | httplib2==0.9 20 | httpretty==0.8.8 21 | logilab-common==0.63.2 22 | mock==1.0.1 23 | nose==1.3.4 24 | oauth2==1.5.211 25 | oauthlib==0.7.2 26 | pylint==1.4.3 27 | python-openid==2.2.5 28 | pytz==2015.2 29 | requests==2.6.0 30 | requests-oauthlib==0.4.2 31 | simplejson==3.6.5 32 | six==1.9.0 33 | snowballstemmer==1.2.0 34 | sphinx-rtd-theme==0.1.7 35 | twilio==3.8.0 36 | wsgiref==0.1.2 37 | googlemaps==2.2 38 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/templates/hackathon/instagram.html: -------------------------------------------------------------------------------- 1 | {% extends "hackathon/base.html" %} 2 | 3 | {% block content %} 4 |

{{ title }}

5 |
6 | 7 |
8 |
9 |
10 | 11 |
12 | 13 |
14 |
15 |
16 | 17 | {% if tagged_media %} 18 |
19 |
20 |

#{{search_tag}}

21 | 22 | {% for i in tagged_media %} 23 | 24 | {% endfor %} 25 |
26 |
27 |
28 | {% endif %} 29 | {% endblock %} 30 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/templates/hackathon/steam.html: -------------------------------------------------------------------------------- 1 | {% extends "hackathon/base.html" %} 2 | 3 | {% block content %} 4 | 5 |

Steam API

6 |
7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | {% for game in game %} 18 | 19 | 20 | 21 | 22 | 23 | {% endfor %} 24 | 25 | 26 |
Game ID Game Name Minutes Played
{{ game.appid }}{{ game.name }}{{ game.playtime_forever }}
27 |
28 |
29 | {% endblock %} -------------------------------------------------------------------------------- /hackathon_starter/hackathon/templates/hackathon/twilio.html: -------------------------------------------------------------------------------- 1 | {% extends "hackathon/base.html" %} 2 | 3 | {% block head %} 4 | 11 | {% endblock %} 12 | 13 | {% block content %} 14 | {{ context }} 15 |

Twilio Messages

16 |
17 | 28 |
29 | {% endblock %} -------------------------------------------------------------------------------- /hackathon_starter/hackathon/scripts/steam.py: -------------------------------------------------------------------------------- 1 | '''This script contains methods belonging to the Steam web API 2 | that can collect information based on an user's gaming library.''' 3 | import requests 4 | import json 5 | 6 | def gamespulling(steamid, apikey): 7 | '''Returns the JSON data from the Steam API based of one's 8 | Steam ID number and returns a dictionary of 9 | gameids and minutes played.''' 10 | steaminfo = { 11 | 'key': apikey, 12 | 'steamid': steamid, 13 | 'format':'JSON', 14 | 'include_appinfo':'1' 15 | } 16 | apiurl = 'http://api.steampowered.com/IPlayerService/GetOwnedGames/v0001/' 17 | req = requests.get(apiurl, params=steaminfo) 18 | data = json.loads(req.content) 19 | return data['response']['games'] 20 | 21 | def steamidpulling(steamun, apikey): 22 | '''Pulls out and returns the steam id number for use in steam queries.''' 23 | steaminfo = {'key': apikey, 'vanityurl': steamun} 24 | apiurl = 'http://api.steampowered.com/ISteamUser/ResolveVanityURL/v0001/' 25 | req = requests.get(apiurl, params=steaminfo) 26 | data = json.loads(req.content) 27 | steamid = data['response']['steamid'] 28 | return steamid 29 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/templates/hackathon/instagram_q.html: -------------------------------------------------------------------------------- 1 | {% extends "hackathon/base.html" %} 2 | 3 | {% block content %} 4 |

{{ title }}

5 |
6 |
7 |
8 |
9 | 10 |
11 | 12 |
13 |
14 |
15 |
16 |

{{err_msg}}

17 |
18 | 19 | {% if geocode_result %} 20 |
21 |
22 |

Latitude: {{geocode_result.lat}}

23 |

Longitude: {{geocode_result.lng}}

24 | 25 |

{{list_id}}

26 | 27 | {% for list in media %} 28 | {% for user in list %} 29 | 30 | {% endfor %} 31 | {% endfor %} 32 | 33 |
34 |
35 |
36 | {% endif %} 37 | {% endblock %} -------------------------------------------------------------------------------- /hackathon_starter/index.rst: -------------------------------------------------------------------------------- 1 | .. Django Hackathon Starter documentation master file, created by 2 | sphinx-quickstart on Sun Apr 12 22:33:44 2015. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to Django Hackathon Starter's documentation! 7 | ==================================================== 8 | 9 | Contents: 10 | 11 | .. toctree:: 12 | :maxdepth: 2 13 | 14 | Github 15 | ====== 16 | .. automodule:: github 17 | :members: 18 | 19 | Instagram 20 | ========= 21 | .. automodule:: instagram 22 | :members: 23 | 24 | Steam 25 | ===== 26 | .. automodule:: steam 27 | :members: 28 | 29 | Tumblr 30 | ====== 31 | .. automodule:: tumblr 32 | :members: 33 | 34 | Twilio 35 | ====== 36 | .. automodule:: twilioapi 37 | :members: 38 | 39 | Twitter 40 | ======= 41 | .. automodule:: twitter 42 | :members: 43 | 44 | Scraper 45 | ======= 46 | .. automodule:: scraper 47 | :members: 48 | 49 | New York Times 50 | ============== 51 | .. automodule:: nytimes 52 | :members: 53 | 54 | Instagram 55 | ========= 56 | .. automodule:: instagram 57 | :members: 58 | 59 | 60 | 61 | 62 | Indices and tables 63 | ================== 64 | 65 | * :ref:`genindex` 66 | * :ref:`modindex` 67 | * :ref:`search` 68 | 69 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/templates/hackathon/meetup.html: -------------------------------------------------------------------------------- 1 | {% extends "hackathon/base.html" %} 2 | 3 | {% block content %} 4 | 5 |

Meetup Profile

6 |
7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | {% for key in data.userData %} 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | {% endfor %} 29 | 30 | 31 |
Name State City Country Status
{{ key.name }}{{ key.state }}{{ key.city }}{{ key.country }}{{ key.status }}
32 |
33 |
34 | {{% endblock %}} 35 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/templates/hackathon/googlePlus.html: -------------------------------------------------------------------------------- 1 | {% extends "hackathon/base.html" %} 2 | 3 | {% block content %} 4 |
5 |

Google Plus API Example

6 |

Basic User Info

7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 23 | 24 | 25 | 26 | 27 | 30 | 31 | 32 | 33 | 34 | 37 | 38 | 39 | 40 | 41 | 44 | 45 | 46 |
User ID 14 | {{userInfo.id}} 15 |
First Name 21 | {{userInfo.given_name}} 22 |
Last Name 28 | {{userInfo.family_name}} 29 |
Gender 35 | {{userInfo.gender}} 36 |
Profile 42 | {{userInfo.link}} 43 |
47 | 48 |
49 | {% endblock %} -------------------------------------------------------------------------------- /hackathon_starter/hackathon/templates/hackathon/tumblr.html: -------------------------------------------------------------------------------- 1 | {% extends "hackathon/base.html" %} 2 | 3 | {% block content %} 4 |

{{ title }}

5 |
6 |
7 |
8 |

BLOGGER

9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 |
Name{{blogData.name}}
Posts{{blogData.posts}}
Blog title{{blogData.title}}
Last updated{{blogData.updated}}
Description{{blogData.description}}
31 |
32 |
33 | 34 |
35 |
36 |

#starbucks

37 | 38 | {% for i in blogTag %} 39 | 40 | 41 | 42 | {% endfor %} 43 |
{{i}}
44 |
45 |
46 | 47 |
48 |
49 |

Comments

50 | 51 | {% for i in blogontag %} 52 | 53 | 54 | 55 | {% endfor %} 56 |
{{i}}
57 |
58 |
59 | {% endblock %} 60 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/scripts/yelp.py: -------------------------------------------------------------------------------- 1 | # pylint: disable=invalid-name 2 | 3 | ''' 4 | Yelp.py contains methods for 5 | authenticating the user and 6 | retrieving data from Yelp's API. 7 | ''' 8 | 9 | import simplejson as json 10 | import oauth2 11 | import requests 12 | 13 | # OAuth credential placeholders that must be filled in by users. 14 | CONSUMER_KEY = 'EXMisJNWez_PuR5pr06hyQ' 15 | CONSUMER_SECRET = 'VCK-4cDjtQ9Ra4HC5ltClNiJFXs' 16 | TOKEN = 'AWYVs7Vim7mwYyT1BLJA2xhNTs_vXLYS' 17 | TOKEN_SECRET = 'Rv4GrlYxYGhxUs14s0VBfk7JLJY' 18 | 19 | def requestData(location): 20 | ''' 21 | Authenticates a request and returns 22 | data from Yelp API. 23 | ''' 24 | data = [] 25 | url = 'http://api.yelp.com/v2/business/' + location + '?' 26 | 27 | consumer = oauth2.Consumer(CONSUMER_KEY, CONSUMER_SECRET) 28 | oauth_request = oauth2.Request(method="GET", url=url) 29 | 30 | oauth_request.update( 31 | { 32 | 'oauth_nonce': oauth2.generate_nonce(), 33 | 'oauth_timestamp': oauth2.generate_timestamp(), 34 | 'oauth_token': TOKEN, 35 | 'oauth_consumer_key': CONSUMER_KEY 36 | } 37 | ) 38 | token = oauth2.Token(TOKEN, TOKEN_SECRET) 39 | oauth_request.sign_request(oauth2.SignatureMethod_HMAC_SHA1(), consumer, token) 40 | signed_url = oauth_request.to_url() 41 | req = requests.get(signed_url) 42 | content = json.loads(req.content) 43 | data.append(content) 44 | return data 45 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/unittests/testinstagram.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from mock import Mock, patch, MagicMock 3 | from hackathon.scripts.instagram import InstagramOauthClient, searchForLocation 4 | 5 | 6 | class TwitterTests(unittest.TestCase): 7 | 8 | def setUp(self): 9 | self.authorization_url = 'https://api.instagram.com/oauth/authorize/?client_id=' 10 | self.access_token_url = 'https://api.instagram.com/oauth/access_token' 11 | self.client_id = '77dc10b9e3624e908ce437c0a82da92e' 12 | self.client_secret = '8bcf3139857149aaba7acaa61288427f' 13 | self.googlemap_api_key = 'AIzaSyA7tttML91EGZ32S_FOOoxu-mbxN9Ojds8' 14 | 15 | 16 | def test_TwitterOauthClient(self): 17 | with patch('hackathon.scripts.instagram.requests') as mock_requests: 18 | mock_requests.get.return_value = mock_response = Mock() 19 | mock_response.status_code = 200 20 | mock_response.json.return_value = jsonlist = {'access_token': '32833691.77dc10b.fe8fefd1dbf44cdea759714e9fcb44f3', 'user': {'username': 'mk200789', 'bio': '', 'website': '', 'profile_picture': 'https://instagramimages-a.akamaihd.net/profiles/profile_32833691_75sq_1333679391.jpg', 'full_name': '', 'id': '32833691'}} 21 | 22 | def test_searchForLocation(self): 23 | with patch('hackathon.scripts.instagram.searchForLocation') as mock_searchForLocation: 24 | mock_searchForLocation.return_value = {'lat': 40.621372, 'lng': -74.00232690000001} 25 | result = searchForLocation('7011 14th avenue, brooklyn, ny') 26 | self.assertEqual(mock_searchForLocation.return_value, result) 27 | 28 | 29 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/unittests/teststeam.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from mock import Mock, patch, MagicMock 3 | from django.conf import settings 4 | from hackathon.scripts.steam import * 5 | 6 | 7 | class SteamTests(unittest.TestCase): 8 | 9 | def setup(self): 10 | self.API_URL = 'http://api.steampowered.com/IPlayerService/GetOwnedGames/v0001/' 11 | self.APIKEY = '231E98D442E52B87110816C3D5114A1D' 12 | self.userID = 'Marorin' 13 | self.steamnum = '76561197997115778' 14 | 15 | def testGetUserIDNum(self): 16 | '''Test for steam.py method''' 17 | 18 | # Pulling from setUp 19 | userID = self.userID 20 | API_URL = self.API_URL 21 | APIKEY = self.APIKEY 22 | 23 | # constructing the URL 24 | self.url = API_URL + '?' + APIKEY + '&' + userID 25 | 26 | with patch('hackathon.scripts.steam.steamIDpulling') as mock_steamIDPulling: 27 | # Mocking the return value of this method. 28 | mock_steamIDpulling = 76561197997115778 29 | self.assertEqual(steamIDPulling(userID,APIKEY),mock_steamIDpulling) 30 | 31 | def testgamespulling(self): 32 | '''Test gamesPulling method''' 33 | # Using test account due to huge JSON from normal one. 34 | steamnum = self.steamnum 35 | with patch("requests.get") as mock_gamespulling: 36 | mock_gamespulling.returnvalue = [{"response": {"game_count": 0}}] 37 | self.assertEqual(gamesPulling(steamnum,APIKEY), mock_gamespulling.returnvalue) 38 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/templates/hackathon/linkedin.html: -------------------------------------------------------------------------------- 1 | {% extends "hackathon/base.html" %} 2 | 3 | {% block content %} 4 |

{{ title }}

5 |
6 |
7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 28 | 37 | 38 | 39 |
First Name Skills Education
{{ content.firstName }} 20 | {% if content.skills %} 21 | {% for i in content.skills.values %} 22 | {{i.skill.name}} 23 | {% endfor %} 24 | {% else %} 25 | None 26 | {% endif %} 27 | 29 | {% if content.educations %} 30 | {% for i in content.educations.values %} 31 | {{i.schoolName }} [{{i.degree}}, {{i.fieldOfStudy}}] ({{i.startDate.year}} - {{i.endDate.year}}) 32 | {% endfor %} 33 | {% else %} 34 | None 35 | {% endif %} 36 |
40 |
41 |
42 | {% endblock %} 43 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/templates/hackathon/register.html: -------------------------------------------------------------------------------- 1 | {% extends "hackathon/base.html" %} 2 | 3 | {% block head %} 4 | {% load static %} 5 | 6 | {% endblock %} 7 | 8 | {% block content %} 9 | 10 | 11 | {% if registered %} 12 | Thank you for registering! 13 | Return to the homepage.
14 | 15 | {% else %} 16 |
17 | 18 |
19 |
20 | {% csrf_token %} 21 | {% load bootstrap %} 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 |
{{ user_form.username | bootstrap_horizontal}}
{{ user_form.email | bootstrap_horizontal}}
{{ user_form.password | bootstrap_horizontal}}
39 | 40 | 41 |
42 |
43 | {% endif %} 44 | 45 | 46 | {% endblock %} 47 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/templates/hackathon/twitter_tweet.html: -------------------------------------------------------------------------------- 1 | {% extends "hackathon/base.html" %} 2 | 3 | {% block content %} 4 |

{{ title }}

5 |
6 | 7 |
8 |
9 |
10 | 11 |
12 | 13 |
14 |
15 |
16 | 17 | {% if content %} 18 |
19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | {% for item in content %} 32 | 33 | 34 | 35 | 36 | 37 | {% endfor %} 38 | 39 |
Who Tweet Retweets Created
{{ item.user.screen_name }}{{ item.text }}{{ item.retweet_count}}{{ item.created_at}}
40 |
41 |
42 | {% endif %} 43 | {% endblock %} 44 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/unittests/testtumblr.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from mock import Mock, patch, MagicMock 3 | from hackathon.scripts.tumblr import * 4 | import oauth2 5 | import urlparse 6 | from django.conf import settings 7 | 8 | class TestTumblr(unittest.TestCase): 9 | 10 | def setUp(self): 11 | self.consumer_key = 'KrSbAc9cYLmIgVAn1D21FjRR97QWsutNMxkPDFBxo8CMWtMk4M' 12 | self.consumer_secret = 'lKWMtL2Lj8zr5pY51PVqT8ugeoG0DjrdgoFewM0QTSyJ12jP8d' 13 | self.consumer = oauth2.Consumer(key=self.consumer_key, secret=self.consumer_secret) 14 | self.tumblrclient = TumblrOauthClient(self.consumer_key, self.consumer_secret)#, 'QBXdeeMKAnLzDbIG7dDNewTzRYyQoHZLbcn3bAFTCEFF5EXurl') 15 | self.authorize = self.tumblrclient.authorize_url() 16 | 17 | 18 | def test_init(self): 19 | self.assertEqual(self.consumer.key, self.consumer_key) 20 | self.assertEqual(self.consumer.secret, self.consumer_secret) 21 | 22 | #def test_get_authorize_url(self): 23 | # self.client = oauth2.Client(self.consumer) 24 | # self.assertEqual(self.client.consumer, self.consumer) 25 | # with patch('hackathon.scripts.tumblr.TumblrOauthClient.authorize_url') as mock_get_authorize_url: 26 | # mock_get_authorize_url.return_value = "oauth_token=QBXdeeMKAnLzDbIG7dDNewTzRYyQoHZLbcn3bAFTCEFF5EXurl&oauth_token_secret=u10SuRl2nzS8vFK4K7UPQexAvbIFBFrZBjA79XDlgoXFxv9ZhO&oauth_callback_confirmed=true" 27 | # self.request_token = dict(urlparse.parse_qsl(mock_get_authorize_url.return_value)) 28 | # self.oauth_token = self.request_token['oauth_token'] 29 | # self.oauth_token_secret = self.request_token['oauth_token_secret'] 30 | # link = "http://www.tumblr.com/oauth/authorize?oauth_token="+self.oauth_token+"&redirect_uri=http%3A%2F%2Flocalhost%3A8000/hackathon/tumblr" 31 | # self.assertEqual(self.authorize,link ) -------------------------------------------------------------------------------- /hackathon_starter/hackathon/templates/hackathon/dropbox.html: -------------------------------------------------------------------------------- 1 | {% extends "hackathon/base.html" %} 2 | 3 | {% block head %} 4 | 14 | {% endblock %} 15 | 16 | {% block content %} 17 |
18 |

Dropbox API Usage Example

19 |
20 |

Basic User Info

21 | 22 | 23 | 24 | 27 | 28 | 29 | 30 | 31 | 34 | 35 | 36 | 37 | 38 | 41 | 42 | 43 | 44 | 45 | 48 | 49 |
User ID 25 | {{userInfo.uid}} 26 |
Name 32 | {{userInfo.display_name}} 33 |
Email 39 | {{userInfo.email}} 40 |
Country 46 | {{userInfo.country}} 47 |
50 | 51 |
52 | 53 |

Search Files Example

54 | 55 |
56 | {% csrf_token %} 57 | {% load bootstrap %} 58 | 59 |
60 | 61 | 62 |
63 |
64 | {% endblock %} -------------------------------------------------------------------------------- /hackathon_starter/hackathon/templates/hackathon/githubTopRepositories.html: -------------------------------------------------------------------------------- 1 | {% extends "hackathon/base.html" %} 2 | 3 | {% block head %} 4 | 11 | {% endblock %} 12 | 13 | {% block content %} 14 |

Github Top Repositories

15 | 16 |
17 | 26 |
27 | 28 |
29 |
30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | {% for key in data.committed %} 40 | 41 | 42 | 43 | 44 | {% endfor %} 45 | 46 | 47 |
Repository Total
{{ key.repo_name }}{{ key.total }}
48 |
49 |
50 | {% endblock %} 51 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/templates/hackathon/twitter.html: -------------------------------------------------------------------------------- 1 | {% extends "hackathon/base.html" %} 2 | 3 | {% block content %} 4 |

{{ title }}

5 | 6 |
7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | {% for item in value %} 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | {% if item.neighbor %} 30 | 35 | {% else %} 36 | 37 | {% endif %} 38 | {% endfor %} 39 | 40 |
Name Woeid Place type Country Country Code ParentID Neighbor
{{ item.name }}{{ item.woeid }}{{ item.placeType.name}}{{ item.country}}{{ item.countryCode}}{{ item.parentid}} 31 | {% for v in item.neighbor.places.place %} 32 | {{ v.name }}, 33 | {% endfor %} 34 | No available Data.
41 |
42 |
43 | {% endblock %} -------------------------------------------------------------------------------- /hackathon_starter/hackathon/templates/hackathon/facebookAPIExample.html: -------------------------------------------------------------------------------- 1 | {% extends "hackathon/base.html" %} 2 | 3 | {% block content %} 4 |
5 |

Facebook API Usage Example

6 |
7 |

Basic User Info

8 | 9 | 10 | 11 | 14 | 15 | 16 | 17 | 20 | 21 | 22 | 23 | 26 | 27 | 28 | 29 | 32 | 33 | 34 | 35 | 38 | 39 | 40 | 41 | 44 | 45 |
User ID 12 | {{userInfo.id}} 13 |
First Name 18 | {{userInfo.first_name}} 19 |
Last Name 24 | {{userInfo.last_name}} 25 |
Gender 30 | {{userInfo.gender}} 31 |
Time Zone 36 | GMT{{userInfo.timezone}} 37 |
Profile 42 | {{userInfo.link}} 43 |
46 |
47 | Every Facebook account basic information is available for all apps by default. In order to get more information about a user 48 | (such as likes, photos, status updates, etc.) you must submit a request to facebook which you will find in the Facebook app page. 49 | After gaining the desired permissions, you can call check_permissions(self, perm) to check if you gained permission from the user and request_permissions to request the permission from the user. 50 |
51 | 52 | {% endblock %} -------------------------------------------------------------------------------- /hackathon_starter/hackathon/templates/hackathon/dropboxSearchFile.html: -------------------------------------------------------------------------------- 1 | {% extends "hackathon/base.html" %} 2 | 3 | {% block content %} 4 |
5 |

Back to Search

6 |

Search Results:

7 |
8 | 9 | {% if data %} 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | {% for element in data %} 21 | 22 | 29 | 30 | 31 | 32 | 33 | {% endfor %} 34 | 35 |
Type Path Size Modified
23 | {% if element.is_dir %} 24 | Folder 25 | {% else %} 26 | File 27 | {% endif %} 28 | {{ element.path }} {{ element.size }} {{ element.modified }}
36 | 37 | {% else %} 38 |

No files were found

39 | {% endif %} 40 |
41 | {% endblock %} 42 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/scripts/dropbox.py: -------------------------------------------------------------------------------- 1 | import simplejson as json 2 | import urllib 3 | import requests 4 | import string 5 | import pdb 6 | import random 7 | 8 | 9 | AUTHORIZE_URL = 'https://www.dropbox.com/1/oauth2/authorize' 10 | ACCESS_TOKEN_URL = 'https://api.dropbox.com/1/oauth2/token' 11 | 12 | 13 | class DropboxOauthClient(object): 14 | 15 | access_token = None 16 | session_id = None 17 | def __init__(self, client_id, client_secret): 18 | self.client_id = client_id 19 | self.client_secret = client_secret 20 | 21 | 22 | def get_authorize_url(self): 23 | self.get_session_id() 24 | authSettings = {'response_type': 'code', 25 | 'client_id': self.client_id, 26 | 'redirect_uri': 'http://localhost:8000/hackathon', 27 | 'state': self.session_id} 28 | 29 | params = urllib.urlencode(authSettings) 30 | 31 | return AUTHORIZE_URL + '?' + params 32 | 33 | def get_session_id(self, length=50): 34 | chars = string.uppercase + string.digits + string.lowercase 35 | self.session_id = ''.join(random.choice(chars) for _ in range(length)) 36 | 37 | def get_access_token(self, code, state): 38 | if state != self.session_id: 39 | raise(Exception('Danger! Someone is messing up with you connection!')) 40 | 41 | authSettings = {'code': code, 42 | 'grant_type': 'authorization_code', 43 | 'client_id': self.client_id, 44 | 'client_secret': self.client_secret, 45 | 'redirect_uri': 'http://localhost:8000/hackathon'} 46 | 47 | response = requests.post(ACCESS_TOKEN_URL, data=authSettings) 48 | 49 | if response.status_code!=200: 50 | raise(Exception('Invalid response, response code {c}'.format(c=response.status_code))) 51 | self.access_token = response.json()['access_token'] 52 | 53 | 54 | def get_user_info(self): 55 | USER_INFO_API = 'https://api.dropbox.com/1/account/info' 56 | params = urllib.urlencode({'access_token': self.access_token}) 57 | response = requests.get(USER_INFO_API + '?' + params) 58 | if response.status_code!=200: 59 | raise(Exception('Invalid response, response code {c}'.format(c=response.status_code))) 60 | return response.json() 61 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/templates/hackathon/yelp.html: -------------------------------------------------------------------------------- 1 | {% extends "hackathon/base.html" %} 2 | 3 | {% block head %} 4 | 11 | {% endblock %} 12 | 13 | {% block content %} 14 |

Yelp API

15 |
16 | 25 |
26 | 27 | {% if data %} 28 |
29 |
30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | {% for key in data %} 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | {% endfor %} 51 | 52 | 53 |
Name Snippet Text Open? Review Count URL
{{ key.name }}{{ key.snippet_text }}{{ key.is_closed }}{{ key.review_count }}{{ key.url |urlize }}
54 |
55 |
56 | {% endif %} 57 | {% endblock %} -------------------------------------------------------------------------------- /hackathon_starter/hackathon/scripts/quandl.py: -------------------------------------------------------------------------------- 1 | '''Module containing a handful of methods for 2 | aggregating data from markets throughout the world''' 3 | 4 | import requests 5 | import json 6 | 7 | def fetchData(apikey, url): 8 | '''Returns JSON data of the Dow Jones Average.''' 9 | parameters = {'rows' : 1, 'column' : 1, 'auth_token' : apikey} 10 | req = requests.get(url, params=parameters) 11 | data = json.loads(req.content) 12 | parsedData = [] 13 | stockData = {} 14 | if data['code'] == 'COMP': 15 | stockData['name'] = data['name'] 16 | stockData['description'] = '''The NASDAQ Composite Index measures all 17 | NASDAQ domestic and international based common type stocks listed \ 18 | on The NASDAQ Stock Market.''' 19 | stockData['data'] = data['data'][0][1] 20 | stockData['code'] = data['code'] 21 | else: 22 | stockData['name'] = data['name'] 23 | stockData['description'] = data['description'] 24 | stockData['data'] = data['data'][0][1] 25 | stockData['code'] = data['code'] 26 | parsedData.append(stockData) 27 | return parsedData 28 | 29 | def fetchstockData(apikey, url): 30 | '''Returns Stock related JSON data of the stock url placed there.''' 31 | parameters = {'rows' : 1, 'auth_token' : apikey} 32 | req = requests.get(url, params=parameters) 33 | data = json.loads(req.content) 34 | parsedData = [] 35 | stockData = {} 36 | stockData['name'] = data['name'] 37 | stockData['open'] = data['data'][0][1] 38 | stockData['high'] = data['data'][0][2] 39 | stockData['low'] = data['data'][0][3] 40 | stockData['close'] = data['data'][0][4] 41 | stockData['code'] = data['code'] 42 | parsedData.append(stockData) 43 | return parsedData 44 | 45 | def rdiffData(apikey, url): 46 | '''Returns data of the difference of the stock URL placed there.''' 47 | parameters = {'rows' : 1, 'column' : 1, 'transformation': 'rdiff', 'auth_token' : apikey} 48 | req = requests.get(url, params=parameters) 49 | data = json.loads(req.content) 50 | parsedData = [] 51 | stockData = {} 52 | stockData['rdiff'] = data['data'][0][1] 53 | parsedData.append(stockData) 54 | return parsedData 55 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/templates/hackathon/nytimes.html: -------------------------------------------------------------------------------- 1 | {% extends "hackathon/base.html" %} 2 | 3 | {% block content %} 4 | 5 |

New York Times Collection

6 |

Popular Stories Data

7 |
8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | {% for data in everyData.pop %} 21 | 22 | 23 | 24 | 25 | 26 | 27 | {% endfor %} 28 | 29 |
Title Abstract Section Located Author
{{ data.title }}{{ data.abstract }}{{ data.section }}{{ data.byline }}
30 |
31 |
32 |

Top Stories Data

33 |
34 |
35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | {% for data in everyData.top %} 47 | 48 | 49 | 50 | 51 | 52 | 53 | {% endfor %} 54 | 55 |
Title Abstract Section Located Author
{{ data.title }}{{ data.abstract }}{{ data.section }}{{ data.byline }}
56 |
57 |
58 | {% endblock %} -------------------------------------------------------------------------------- /hackathon_starter/hackathon/templates/hackathon/github.html: -------------------------------------------------------------------------------- 1 | {% extends "hackathon/base.html" %} 2 | 3 | {% block head %} 4 | 11 | {% endblock %} 12 | 13 | {% block content %} 14 |

Github User Data

15 | 16 |
17 | 26 |
27 | 28 | {% if data %} 29 |
30 |
31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | {% for key in data.userData %} 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | {% endfor %} 56 | 57 | 58 |
Username Blog Public Repos Public Gists Email Followers Following
{{ key.name }}{{ key.blog }}{{ key.public_repos }}{{ key.public_gists }}{{ key.email }}{{ key.followers }}{{ key.following }}
59 |
60 |
61 | {% endif %} 62 | {% endblock %} 63 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/scripts/linkedin.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | import simplejson as json 4 | import requests 5 | import urlparse, urllib 6 | 7 | AUTHORIZATION_URL = 'https://www.linkedin.com/uas/oauth2/authorization' 8 | ACCESS_TOKEN_URL = 'https://www.linkedin.com/uas/oauth2/accessToken' 9 | 10 | class LinkedinOauthClient(object): 11 | 12 | is_authorized = False 13 | 14 | def __init__(self, client_id, client_secret): 15 | self.client_id = client_id 16 | self.client_secret = client_secret 17 | 18 | def get_authorize_url(self): 19 | auth_setting = {'response_type' : 'code', 20 | 'client_id' : self.client_id, 21 | 'client_secret' : self.client_secret, 22 | 'redirect_uri' : 'http://127.0.0.1:8000/hackathon/', 23 | 'state' : 'DCEeFWf45A53sdfKef424', 24 | 'scope': 'r_basicprofile'} 25 | 26 | params = urllib.urlencode(auth_setting) 27 | authURL = AUTHORIZATION_URL + '?' + params 28 | return authURL 29 | 30 | def get_access_token(self, code): 31 | settings = {'grant_type' : 'authorization_code', 32 | 'code' : code, 33 | 'redirect_uri' : 'http://127.0.0.1:8000/hackathon/', 34 | 'client_id' : self.client_id, 35 | 'client_secret': self.client_secret} 36 | 37 | header = {'content-type' : 'application/x-www-form-urlencoded'} 38 | params = urllib.urlencode(settings) 39 | link = ACCESS_TOKEN_URL + '?' + params 40 | req = requests.post(link)#, headers=header) 41 | 42 | if req.status_code != 200: 43 | raise Exception('Invalid response %s' %req.status_code) 44 | 45 | content = json.loads(req.content) 46 | self.access_token = content['access_token'] 47 | self.is_authorized = True 48 | 49 | def getUserInfo(self): 50 | #link = 'https://api.linkedin.com/v1/people/~?format=json&oauth2_access_token=' + self.access_token 51 | link = 'https://api.linkedin.com/v1/people/~:(id,first-name,skills,educations,languages,twitter-accounts)?oauth2_access_token='+self.access_token 52 | headers = {'x-li-format' : 'json', 53 | 'content-type' : 'application/json'} 54 | req = requests.get(link, headers=headers) 55 | content = json.loads(req.content) 56 | 57 | if req.status_code != 200: 58 | raise Exception('Invalid response %s' %req.status_code) 59 | 60 | self.user_id = content['id'] 61 | print content 62 | return content 63 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/templates/hackathon/base.html: -------------------------------------------------------------------------------- 1 | {% load static %} 2 | 3 | 4 | 5 | Django Hackathon Starter 6 | 7 | 8 | 9 | 10 | {% block head %} 11 | {% endblock %} 12 | 13 | 14 | 50 | {% block content %} 51 | {% endblock %} 52 | 53 | 54 | 55 | {% block js %} 56 | {% endblock %} 57 | 58 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/templates/hackathon/login.html: -------------------------------------------------------------------------------- 1 | {% extends "hackathon/base.html" %} 2 | 3 | {% block head %} 4 | 11 | {% endblock %} 12 | 13 | {% block content %} 14 |
15 | 27 |
28 | 29 |
30 | 31 | 32 | Sign in with Twitter 33 | 34 | 35 | 36 | Sign in with Instagram 37 | 38 | 39 | 40 | Sign in with Tumblr 41 | 42 | 43 | 44 | Sign in with Github 45 | 46 | 47 | 48 | Sign in with LinkedIn 49 | 50 | 51 | 52 | Sign in with Facebook 53 | 54 | 55 | 56 | Sign in with Google+ 57 | 58 | 59 | 60 | Sign in with Dropbox 61 | 62 |
63 | {% endblock %} -------------------------------------------------------------------------------- /hackathon_starter/hackathon/templates/hackathon/index.html: -------------------------------------------------------------------------------- 1 | {% extends "hackathon/base.html" %} 2 | 3 | {% block content %} 4 |
5 | {% if user.is_authenticated %} 6 |

Api Example

7 | {{ boldmessage }}
8 | {% else %} 9 |

Please register/login!

10 | {% endif %} 11 |
12 |
13 |
14 | Vestibulum sed metus sed tortor rutrum pharetra vel non erat. Aliquam vitae lectus sapien. Fusce volutpat pharetra enim, at mattis mauris porttitor pharetra. Morbi et dolor dapibus, consequat sem non, mollis risus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Phasellus auctor eros id elit consectetur, ut sollicitudin felis condimentum. Mauris porta, nulla quis malesuada sagittis, orci lectus luctus tellus, sit amet mollis arcu lectus id sapien. Pellentesque a dignissim ligula. Vestibulum eu semper nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Morbi nisl justo, fermentum eget dignissim at, fermentum ut nisl. 15 |
16 |
17 | Vestibulum sed metus sed tortor rutrum pharetra vel non erat. Aliquam vitae lectus sapien. Fusce volutpat pharetra enim, at mattis mauris porttitor pharetra. Morbi et dolor dapibus, consequat sem non, mollis risus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Phasellus auctor eros id elit consectetur, ut sollicitudin felis condimentum. Mauris porta, nulla quis malesuada sagittis, orci lectus luctus tellus, sit amet mollis arcu lectus id sapien. Pellentesque a dignissim ligula. Vestibulum eu semper nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Morbi nisl justo, fermentum eget dignissim at, fermentum ut nisl. 18 |
19 |
20 |
21 |
22 |
23 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam felis nunc, finibus eu condimentum porttitor, vehicula vitae dui. Cras lacinia augue vel sem ultricies, vel tempor orci sagittis. Suspendisse mattis purus a auctor semper. In tincidunt tincidunt enim, vel aliquet est congue sed. Vestibulum eget lacus in ligula fringilla faucibus quis eu enim. Cras lacinia blandit est, vitae sollicitudin enim venenatis malesuada. Cras egestas eget nibh at volutpat. Ut at consequat urna. Ut pretium felis vitae molestie vestibulum. 24 |
25 |
26 | Vestibulum sed metus sed tortor rutrum pharetra vel non erat. Aliquam vitae lectus sapien. Fusce volutpat pharetra enim, at mattis mauris porttitor pharetra. Morbi et dolor dapibus, consequat sem non, mollis risus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Phasellus auctor eros id elit consectetur, ut sollicitudin felis condimentum. Mauris porta, nulla quis malesuada sagittis, orci lectus luctus tellus, sit amet mollis arcu lectus id sapien. Pellentesque a dignissim ligula. Vestibulum eu semper nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Morbi nisl justo, fermentum eget dignissim at, fermentum ut nisl. 27 |
28 |
29 |
30 | {% endblock %} 31 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import patterns, url 2 | 3 | from hackathon import views 4 | 5 | urlpatterns = patterns('', 6 | url(r'^$', views.index, name='index'), 7 | url(r'^register/$', views.register, name='register'), 8 | url(r'^login/$', views.user_login, name='login'), 9 | url(r'^logout/$', views.user_logout, name='logout'), 10 | url(r'^api/$', views.api_examples, name='api'), 11 | url(r'^steam/$', views.steam, name='steam'), 12 | url(r'^steamDiscountedGames/$', views.steamDiscountedGames, name='steamDiscountedGames'), 13 | url(r'^githubResume/$', views.githubResume, name='githubResume'), 14 | url(r'^githubUser/$', views.githubUser, name='githubUser'), 15 | url(r'^githubTopRepositories/$', views.githubTopRepositories, name='githubTopRepositories'), 16 | url(r'^tumblr/$', views.tumblr, name='tumblr'), 17 | url(r'^linkedin/$', views.linkedin, name='linkedin'), 18 | url(r'^snippets/$', views.snippet_list, name='snippets'), 19 | url(r'^twilio/$', views.twilio, name='twilio'), 20 | url(r'^instagram/$', views.instagram, name='instagram'), 21 | url(r'^instagram_login/$', views.instagram_login, name='instagram_login'), 22 | url(r'^instagramUser/$', views.instagramUser, name='instagramUser'), 23 | url(r'^instagramMediaByLocation/$', views.instagramMediaByLocation, name='instagramMediaByLocation'),# 24 | url(r'^instagramUserMedia/$', views.instagramUserMedia, name='instagramUserMedia'), 25 | url(r'^twitter/$', views.twitter, name='twitter'), 26 | url(r'^twitterTweets/$', views.twitterTweets, name='twitterTweets'), 27 | url(r'^tumblr_login/$', views.tumblr_login, name='tumblr_login'), 28 | url(r'^twitter_login/$', views.twitter_login, name='twitter_login'), 29 | url(r'^github_login/$', views.github_login, name='github_login'), 30 | url(r'^linkedin_login/$', views.linkedin_login, name='linkedin_login'), 31 | url(r'^facebook_login/$', views.facebook_login, name='facebook_login'), 32 | url(r'^facebook/$', views.facebook, name='facebook'), 33 | url(r'^google_login/$', views.google_login, name='google_login'), 34 | url(r'^google/$', views.googlePlus, name='googlePlus'), 35 | url(r'^dropbox_login/$', views.dropbox_login, name='dropbox_login'), 36 | url(r'^dropbox/$', views.dropbox, name='dropbox'), 37 | url(r'^dropboxSearchFile/$', views.dropboxSearchFile, name='dropboxSearchFile'), 38 | url(r'^quandlSnp500/$', views.quandlSnp500, name='quandlsnp500'), 39 | url(r'^quandlNasdaq/$', views.quandlNasdaq, name='quandlnasdaq'), 40 | url(r'^quandlNasdaqdiff/$', views.quandlNasdaqdiff, name='quandlnasdaqdiff'), 41 | url(r'^quandlDowJones/$', views.quandlDowJones, name='quandldowjones'), 42 | url(r'^quandlstocks/$', views.quandlstocks, name='quandlstocks'), 43 | url(r'^quandlapple/$', views.quandlapple, name='quandlapple'), 44 | url(r'^quandlapplediff/$', views.quandlapplediff, name='quandlapplediff'), 45 | url(r'^quandlDowJonesdiff/$', views.quandlDowJonesdiff, name='quandldowjonesdiff'), 46 | url(r'^quandlSnp500diff/$', views.quandlSnp500diff, name='quandlsnp500diff'), 47 | url(r'^nytimespop/$', views.nytimespop, name='nytimespop'), 48 | url(r'^nytimestop/$', views.nytimestop, name='nytimestop'), 49 | url(r'^nytimesarticles/$', views.nytimesarticles, name='nytimesarticles'), 50 | url(r'^meetup/$', views.meetup, name='meetup'), 51 | url(r'^meetupToken/$', views.meetupToken, name='meetupToken'), 52 | url(r'^meetupUser/$', views.meetupUser, name='meetupUser'), 53 | url(r'^yelp/$', views.yelp, name='yelp'), 54 | ) -------------------------------------------------------------------------------- /hackathon_starter/hackathon/scripts/scraper.py: -------------------------------------------------------------------------------- 1 | # pylint: disable=line-too-long 2 | 3 | ''' 4 | scraper.py contains various methods for scraping 5 | HTML content and packaging into dictionaries. 6 | ''' 7 | 8 | import requests 9 | from bs4 import BeautifulSoup 10 | 11 | def fetchHTML(url): 12 | ''' 13 | Returns HTML retrived from a url. 14 | 15 | Parameters: 16 | url: String 17 | - The URL to fetch HTML from 18 | 19 | Returns: 20 | html: String 21 | - The HTML from a given URL 22 | ''' 23 | req = requests.get(url) 24 | html = req.text 25 | return html 26 | 27 | def extractTag(content, tag, className=None): 28 | ''' 29 | Returns data embed within a tag, along 30 | with an optional class for filtering. 31 | 32 | Parameters: 33 | content: String 34 | - The HTML to parse 35 | tag: String 36 | - The HTML tag to scan for 37 | class: String 38 | - Optional filter for tag 39 | 40 | Returns: 41 | filteredData: List 42 | - Content embed within searched tags 43 | ''' 44 | soup = BeautifulSoup(content) 45 | data = soup.findAll(tag, {'class': className}) 46 | filteredData = [] 47 | for datum in data: 48 | filteredData.append(datum.text) 49 | return filteredData 50 | 51 | 52 | def steamDiscounts(): 53 | '''Returns discounts from steam.com''' 54 | req = requests.get('http://store.steampowered.com/search/?specials=1#sort_by=_ASC&sort_order=ASC&specials=1&page=1') 55 | content = req.text 56 | soup = BeautifulSoup(content) 57 | allData = {id: {} for id in range(0, 25)} 58 | 59 | # Get all divs of a specific class 60 | releaseDate = soup.findAll('div', {'class': 'col search_released'}) 61 | 62 | # Get all release dates 63 | releaseDates = [] 64 | id = 0 65 | for date in releaseDate: 66 | allData[id]['releaseDates'] = date.text 67 | releaseDates.append(date.text) 68 | id += 1 69 | 70 | #print releaseDates 71 | 72 | id = 0 73 | gameName = soup.findAll('div', {'class': 'col search_name ellipsis'}) 74 | 75 | # Get all game names 76 | gameNames = [] 77 | for name in gameName: 78 | span = name.findAll('span', {'class': 'title'}) 79 | for tag in span: 80 | allData[id]['name'] = tag.text 81 | gameNames.append(tag.text) 82 | id += 1 83 | 84 | # print gameNames 85 | 86 | discount = soup.findAll('div', {'class': 'col search_discount'}) 87 | 88 | id = 0 89 | # Get all game discounts 90 | gameDiscounts = [] 91 | for discountedGame in discount: 92 | span = discountedGame.findAll('span') 93 | for tag in span: 94 | allData[id]['discount'] = tag.text 95 | gameDiscounts.append(tag.text) 96 | id += 1 97 | 98 | # print gameDiscounts 99 | 100 | price = soup.findAll('div', {'class': 'col search_price discounted'}) 101 | 102 | id = 0 103 | prices = [] 104 | # Get all discounted prices 105 | for value in price: 106 | br = value.findAll('br') 107 | for tag in br: 108 | allData[id]['price'] = tag.text.strip('\t') 109 | prices.append(tag.text.strip('\t')) 110 | id += 1 111 | 112 | # Cleanup data 113 | newData = [] 114 | for datum in allData: 115 | newData.append(allData[datum]) 116 | # print prices 117 | return newData 118 | 119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/scripts/googlePlus.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import urllib 3 | import simplejson as json 4 | import random 5 | import string 6 | 7 | 8 | AUTHORISE_URL = 'https://accounts.google.com/o/oauth2/auth' 9 | ACCESS_TOKEN_URL = 'https://accounts.google.com/o/oauth2/token' 10 | REDIRECT_URL = 'http://localhost:8000/hackathon/' 11 | PROFILE_API = 'https://www.googleapis.com/auth/plus.login' 12 | 13 | class GooglePlus: 14 | 15 | access_token = None 16 | session_id = None 17 | 18 | def __init__(self, client_id, client_secret): 19 | ''' 20 | Parameters: 21 | client_id: string 22 | - The client ID from the registering app on Google. 23 | 24 | client_secret: string 25 | -The client secret from the registering app on Google. 26 | ''' 27 | self.client_id = client_id 28 | self.client_secret = client_secret 29 | 30 | 31 | def get_session_id(self, length=50): 32 | ''' 33 | Generates a random session ID. As a part from the authentication process 34 | we need to verify that the response we get from the server contains the 35 | same session ID as we sent. 36 | 37 | Parameters: 38 | length: integer 39 | - The length of the session ID. 40 | ''' 41 | chars = string.uppercase + string.digits + string.lowercase 42 | self.session_id = ''.join(random.choice(chars) for _ in range(length)) 43 | 44 | 45 | def get_authorize_url(self): 46 | ''' 47 | Obtains authorize url link with the given client_id. 48 | 49 | Returns: 50 | authURL: string 51 | - The authorization URL. 52 | ''' 53 | 54 | self.get_session_id() 55 | authSettings = {'state': self.session_id, 56 | 'redirect_uri':REDIRECT_URL, 57 | 'response_type':'code', 58 | 'client_id':self.client_id, 59 | 'scope': PROFILE_API} 60 | 61 | params = urllib.urlencode(authSettings) 62 | return AUTHORISE_URL + '?' + params 63 | 64 | 65 | def get_access_token(self, code, state): 66 | ''' 67 | Obtains access token. 68 | 69 | Parameters: 70 | code: string 71 | - The code is retrived from the authorization URL parameter 72 | to obtain access token. 73 | state: string 74 | - The unique session ID. 75 | ''' 76 | 77 | #Checking that the sessino ID from the response match the session ID we sent 78 | if state != self.session_id: 79 | raise(Exception('Danger! Someone is messing up with you connection!')) 80 | 81 | authSettings = {'client_secret': self.client_secret, 82 | 'code':code, 83 | 'grant_type':'authorization_code', 84 | 'client_id': self.client_id, 85 | 'redirect_uri': 'http://localhost:8000/hackathon/'} 86 | 87 | response = requests.post(ACCESS_TOKEN_URL, data=authSettings) 88 | if response.status_code != 200: 89 | raise(Exception('Invalid response, response code {c}'.format(c=response.status_code))) 90 | 91 | self.access_token = response.json()['access_token'] 92 | 93 | 94 | 95 | def get_user_info(self): 96 | ''' 97 | Obtain user information. 98 | 99 | Returns: 100 | content: dictionary 101 | - A dictionary contains user information. 102 | ''' 103 | USER_INFO_API = 'https://www.googleapis.com/oauth2/v2/userinfo' 104 | params = urllib.urlencode({'access_token' : self.access_token}) 105 | response = requests.get(USER_INFO_API + '?' + params) 106 | if response.status_code != 200: 107 | raise(Exception('Invalid response, response code {c}'.format(c=response.status_code))) 108 | 109 | return response.json() -------------------------------------------------------------------------------- /hackathon_starter/hackathon/templates/hackathon/quandl.html: -------------------------------------------------------------------------------- 1 | {% extends "hackathon/base.html" %} 2 | 3 | {% block content %} 4 | 5 |

Quandl Collection

6 |

Index Data

7 |
8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | {% for data in everyData.dow %} 21 | 22 | 23 | 24 | {% endfor %} 25 | {% for data in everyData.dowdiff %} 26 | 27 | {% endfor %} 28 | 29 | 30 | {% for data in everyData.snp %} 31 | 32 | 33 | 34 | {% endfor %} 35 | {% for data in everyData.snpdiff %} 36 | 37 | {% endfor %} 38 | 39 | 40 | {% for data in everyData.nasdaq %} 41 | 42 | 43 | 44 | {% endfor %} 45 | {% for data in everyData.nasdaqdiff %} 46 | 47 | {% endfor %} 48 | 49 | 50 |
Name Code Data Change
{{ data.name }}{{ data.code }}{{ data.data }}{{ data.rdiff }}
{{ data.name }}{{ data.code }}{{ data.data }}{{ data.rdiff }}
{{ data.name }}{{ data.code }}{{ data.data }}{{ data.rdiff }}
51 |
52 |
53 | 54 |

Stock Data

55 |
56 |
57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | {% for data in everyData.apple %} 72 | 73 | 74 | 75 | 76 | 77 | 78 | {% endfor %} 79 | {% for data in everyData.applediff %} 80 | 81 | {% endfor %} 82 | 83 | 84 |
Name Code Open High Low Close Change
{{ data.name }}{{ data.code }}{{ data.open }}{{ data.high }}{{ data.low }}{{ data.close }}{{ data.rdiff }}
85 |
86 |
87 | {{% endblock %}} -------------------------------------------------------------------------------- /hackathon_starter/hackathon/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from django.contrib.auth.models import User 3 | 4 | # Create your models here. 5 | class UserProfile(models.Model): 6 | # This line is required. Links UserProfile to a User model instance. 7 | user = models.OneToOneField(User) 8 | 9 | # Override the __unicode__() method to return out something meaningful! 10 | def __unicode__(self): 11 | return self.user.username 12 | 13 | class Profile(models.Model): 14 | user = models.ForeignKey(User) 15 | oauth_token = models.CharField(max_length=200) 16 | oauth_secret = models.CharField(max_length=200) 17 | 18 | def __unicode__(self): 19 | return unicode(self.user) 20 | 21 | class GithubProfile(models.Model): 22 | user = models.ForeignKey(User) 23 | github_user = models.CharField(max_length=200) 24 | access_token = models.CharField(max_length=200) 25 | scopes = models.CharField(max_length=200) 26 | 27 | def __unicode__(self): 28 | return unicode(self.user) 29 | 30 | class TumblrProfile(models.Model): 31 | user = models.ForeignKey(User) 32 | tumblr_user = models.CharField(max_length=200) 33 | access_token = models.CharField(max_length=200) 34 | access_token_secret = models.CharField(max_length=200) 35 | 36 | def __unicode__(self): 37 | return unicode(self.user) 38 | 39 | class InstagramProfile(models.Model): 40 | user = models.ForeignKey(User) 41 | instagram_user = models.CharField(max_length=200) 42 | access_token = models.CharField(max_length=200) 43 | 44 | def __unicode__(self): 45 | return unicode(self.user) 46 | 47 | class TwitterProfile(models.Model): 48 | user = models.ForeignKey(User) 49 | twitter_user = models.CharField(max_length=200) 50 | oauth_token = models.CharField(max_length=200) 51 | oauth_token_secret = models.CharField(max_length=200) 52 | 53 | def __unicode__(self): 54 | return unicode(self.user) 55 | 56 | class LinkedinProfile(models.Model): 57 | user = models.ForeignKey(User) 58 | linkedin_user = models.CharField(max_length=200) 59 | access_token = models.CharField(max_length=200) 60 | 61 | def __unicode__(self): 62 | return unicode(self.user) 63 | 64 | class Snippet(models.Model): 65 | created = models.DateTimeField(auto_now_add=True) 66 | title = models.CharField(max_length=100, blank=True, default='') 67 | code = models.TextField() 68 | linenos = models.BooleanField(default=False) 69 | 70 | class Meta: 71 | ordering = ('created',) 72 | 73 | class MeetupToken(models.Model): 74 | # user = models.ForeignKey(User) 75 | access_token = models.CharField(max_length=200) 76 | 77 | def __unicode__(self): 78 | return unicode(self.access_token) 79 | 80 | class FacebookProfile(models.Model): 81 | user = models.ForeignKey(User) 82 | fb_user_id = models.CharField(max_length=100) 83 | time_created = models.DateTimeField(auto_now_add=True) 84 | profile_url = models.CharField(max_length=50) 85 | access_token = models.CharField(max_length=100) 86 | 87 | class GoogleProfile(models.Model): 88 | user = models.ForeignKey(User) 89 | google_user_id = models.CharField(max_length=100) 90 | time_created = models.DateTimeField(auto_now_add=True) 91 | access_token = models.CharField(max_length=100) 92 | profile_url = models.CharField(max_length=100) 93 | 94 | class DropboxProfile(models.Model): 95 | user = models.ForeignKey(User) 96 | dropbox_user_id = models.CharField(max_length=100) 97 | time_created = models.DateTimeField(auto_now_add=True) 98 | access_token = models.CharField(max_length=100) -------------------------------------------------------------------------------- /hackathon_starter/hackathon/templates/hackathon/githubResume.html: -------------------------------------------------------------------------------- 1 | {% extends "hackathon/base.html" %} 2 | 3 | {% block content %} 4 | 5 |

Github Resume

6 |
7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | {% for key in data.userData %} 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | {% endfor %} 33 | 34 | 35 |
Username Blog Public Repos Public Gists Email Followers Following
{{ key.name }}{{ key.blog }}{{ key.public_repos }}{{ key.public_gists }}{{ key.email }}{{ key.followers }}{{ key.following }}
36 |
37 |
38 | 39 |
40 |

Top Contributed Repositories

41 |
42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | {% for key in data.filteredData %} 52 | 53 | 54 | 55 | 56 | {% endfor %} 57 | 58 | 59 |
Repository Total
{{ key.repo_name }}{{ key.total }}
60 |
61 |
62 |
63 |

Top Starred Repositories

64 |
65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | {% for key in data.filteredStargazers %} 75 | 76 | 77 | 78 | 79 | {% endfor %} 80 | 81 | 82 |
Repository Count
{{ key.name }}{{ key.stargazers_count }}
83 |
84 |
85 | 86 |
87 |

Contributions

88 |
89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | {% for key in data.forkedRepos %} 98 | 99 | 100 | 101 | {% endfor %} 102 | 103 | 104 |
Repository
{{ key.name }}
105 |
106 |
107 | {% endblock %} -------------------------------------------------------------------------------- /hackathon_starter/hackathon/templates/hackathon/api_examples.html: -------------------------------------------------------------------------------- 1 | {% extends "hackathon/base.html" %} 2 | 3 | {% block content %} 4 |
5 | 22 |
23 | {% endblock %} -------------------------------------------------------------------------------- /hackathon_starter/hackathon/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | from django.test import Client 3 | 4 | class SteamViewTestCase(TestCase): 5 | def testSteam(self): 6 | resp = self.client.get('/hackathon/steam/') 7 | self.assertEqual(resp.status_code, 200) 8 | 9 | def testSteamDiscountedGames(self): 10 | resp = self.client.get('/hackathon/steamDiscountedGames/') 11 | self.assertEqual(resp.status_code, 200) 12 | 13 | def testSteamPlaytimeForever(self): 14 | resp = self.client.get('/hackathon/steam/') 15 | for dict in resp.context: 16 | if 'playtime_forever' in dict: 17 | self.assertTrue('playtime_forever' in dict) 18 | 19 | def testSteamName(self): 20 | resp = self.client.get('/hackathon/steam/') 21 | for dict in resp.context: 22 | if 'name' in dict: 23 | self.assertTrue('name' in dict) 24 | 25 | def testSteamImg(self): 26 | resp = self.client.get('/hackathon/steam/') 27 | for dict in resp.context: 28 | if 'img_logo_url' in dict: 29 | self.assertTrue('img_logo_url' in dict) 30 | 31 | def testSteamAppID(self): 32 | resp = self.client.get('/hackathon/steam/') 33 | for dict in resp.context: 34 | if 'appid' in dict: 35 | self.assertTrue('appid' in dict) 36 | 37 | def testSteamDiscountedGamesDiscount(self): 38 | resp = self.client.get('/hackathon/steamDiscountedGames/') 39 | self.assertEqual(resp.context, None) 40 | 41 | 42 | class HackathonViewsTestCase(TestCase): 43 | def testIndex(self): 44 | resp = self.client.get('/hackathon/api/') 45 | self.assertEqual(resp.status_code, 200) 46 | 47 | def testQuandlDowJones(self): 48 | resp = self.client.get('/hackathon/quandlDowJones/') 49 | self.assertEqual(resp.status_code, 200) 50 | 51 | def testQuandlSnp500(self): 52 | resp = self.client.get('/hackathon/quandlSnp500/') 53 | self.assertEqual(resp.status_code, 200) 54 | 55 | def testQuandlNasdaq(self): 56 | resp = self.client.get('/hackathon/quandlNasdaq/') 57 | self.assertEqual(resp.status_code, 200) 58 | 59 | def testGithubUser(self): 60 | resp = self.client.get('/hackathon/githubUser/') 61 | self.assertEqual(resp.status_code, 200) 62 | 63 | def testGithubTopRepositories(self): 64 | resp = self.client.get('/hackathon/githubTopRepositories/') 65 | self.assertEqual(resp.status_code, 200) 66 | 67 | def testGithubResume(self): 68 | resp = self.client.get('/hackathon/githubResume/') 69 | self.assertEqual(resp.status_code, 200) 70 | 71 | def testNytimespop(self): 72 | resp = self.client.get('/hackathon/nytimespop/') 73 | self.assertEqual(resp.status_code, 200) 74 | 75 | class YelpTestCase(TestCase): 76 | def testYelpPost(self): 77 | resp = self.client.post('/hackathon/yelp/', {'location': 'yelp-san-francisco'}) 78 | self.assertEqual(resp.status_code, 200) 79 | 80 | def testYelpContent(self): 81 | resp = self.client.post('/hackathon/yelp/', {'location': 'yelp-san-francisco'}) 82 | self.assertNotEqual(resp.content, '') 83 | 84 | def testYelpContentNotNone(self): 85 | resp = self.client.post('/hackathon/yelp/', {'location': 'yelp-san-francisco'}) 86 | self.assertIsNotNone(resp.content) 87 | 88 | def testGetYelpPage(self): 89 | resp = self.client.get('/hackathon/yelp') 90 | self.assertEqual(resp.status_code, 301) 91 | 92 | class ScraperTestCase(TestCase): 93 | def testScraperPage(self): 94 | resp = self.client.get('/hackathon/steamDiscountedGames/') 95 | self.assertEqual(resp.status_code, 200) 96 | 97 | def testScraperContent(self): 98 | resp = self.client.get('/hackathon/steamDiscountedGames/') 99 | self.assertNotEqual(resp.content, '') 100 | 101 | class TwilioTestCase(TestCase): 102 | def testTwilio(self): 103 | resp = self.client.get('/hackathon/twilio/') 104 | self.assertEqual(resp.status_code, 200) 105 | 106 | #def testMessage(self): 107 | # resp = self.client.post('/hackathon/twilio/', {'number': '+13473282978', 'message': 'hello world'}) 108 | # self.assertEqual(resp.status_code, 302) 109 | 110 | class NewYorkTimesTestCase(TestCase): 111 | def testPopularArticles(self): 112 | resp = self.client.get('/hackathon/nytimespop/') 113 | self.assertEqual(resp.status_code, 200) 114 | 115 | def testPopularArticlesContent(self): 116 | resp = self.client.get('/hackathon/nytimespop/') 117 | self.assertNotEqual(resp.content, '') 118 | 119 | def testTopArticles(self): 120 | resp = self.client.get('/hackathon/nytimestop/') 121 | self.assertEqual(resp.status_code, 200) 122 | 123 | def testTopArticlesContent(self): 124 | resp = self.client.get('/hackathon/nytimestop/') 125 | self.assertNotEqual(resp.content, '') 126 | 127 | def testNewYorkTimesArticles(self): 128 | resp = self.client.get('/hackathon/nytimesarticles/') 129 | self.assertEqual(resp.status_code, 200) 130 | 131 | def testNewYorkTimesArticlesContent(self): 132 | resp = self.client.get('/hackathon/nytimesarticles/') 133 | self.assertNotEqual(resp.content, '') 134 | 135 | 136 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/scripts/facebook.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import urllib 3 | import simplejson as json 4 | 5 | ########################## 6 | # FACEBOOK API CONSTANTS # 7 | ########################## 8 | 9 | AUTHORIZE_URL = 'https://graph.facebook.com/oauth/authorize' 10 | ACCESS_TOKEN_URL = 'https://graph.facebook.com/oauth/access_token' 11 | API_URL = 'https://graph.facebook.com/v2.3/' 12 | REQUEST_PERMISSIONS_URL = "https://www.facebook.com/dialog/oauth?" 13 | 14 | class FacebookOauthClient(object): 15 | ''' 16 | Python client for Facebook API 17 | ''' 18 | 19 | access_token = None 20 | permission_request_url = None 21 | 22 | def __init__(self, client_id, client_secret): 23 | ''' 24 | Parameters: 25 | client_id: String 26 | - The client id from the registering app on Facebook 27 | client_secret: String 28 | - The client secret from the registering app on Facebook 29 | ''' 30 | self.client_id = client_id 31 | self.client_secret = client_secret 32 | 33 | 34 | 35 | def get_authorize_url(self): 36 | ''' 37 | Obtains authorize url link with given client_id. 38 | 39 | Returns: 40 | authURL: String 41 | - The authorization url. 42 | 43 | ''' 44 | authSettings = {'redirect_uri': "http://localhost:8000/hackathon/", 45 | 'client_id': self.client_id} 46 | params = urllib.urlencode(authSettings) 47 | return AUTHORIZE_URL + '?' + params 48 | 49 | 50 | 51 | def get_access_token(self, code): 52 | ''' 53 | Obtains access token. 54 | 55 | Parameters: 56 | code: String 57 | - The code is retrieved from the authorization url parameter 58 | to obtain access_token. 59 | ''' 60 | authSettings = {'code': code, 61 | 'redirect_uri': "http://localhost:8000/hackathon/", 62 | 'client_secret': self.client_secret, 63 | 'client_id': self.client_id} 64 | params = urllib.urlencode(authSettings) 65 | response = requests.get(ACCESS_TOKEN_URL + '?' + params) 66 | 67 | if response.status_code != 200: 68 | raise(Exception('Invalid response,response code: {c}'.format(c=response.status_code))) 69 | 70 | response_array = str(response.text).split('&') 71 | self.access_token = str(response_array[0][13:]) 72 | 73 | 74 | 75 | def get_user_info(self): 76 | ''' 77 | Obtains user information. 78 | 79 | Returns: 80 | content: Dictionary 81 | - A dictionary containing user information. 82 | ''' 83 | response = requests.get("https://graph.facebook.com/me?access_token={at}".format(at=self.access_token)) 84 | if response.status_code != 200: 85 | raise(Exception('Invalid response,response code: {c}'.format(c=response.status_code))) 86 | 87 | return response.json() 88 | 89 | 90 | 91 | 92 | def get_user_likes(self): 93 | ''' 94 | Obtains a list of all the user likes. Require a special permission 95 | via Facebook. 96 | 97 | Returns: 98 | content: dictionary 99 | -A dictionary containing user likes. 100 | ''' 101 | #Check if permission exists or ask for it 102 | if not self.check_permissions('user_likes'): 103 | requestedPermissionUrl = self.request_permissions('user_likes') 104 | 105 | #Get likes 106 | response = requests.get(API_URL + 'me/likes?access_token={at}'.format(at=self.access_token)) 107 | return response.json()['data'] 108 | 109 | 110 | 111 | def check_permissions(self, perm): 112 | ''' 113 | Checks if the app has the specified permission. 114 | 115 | Parameters: 116 | perm: String 117 | - The desired permission (such as user_likes) 118 | 119 | Returns: 120 | bool 121 | - True if the permission granted or false otherwise. 122 | ''' 123 | 124 | permDict = {'status': 'granted', 'permission':perm} 125 | response = requests.get(API_URL + 'me/permissions?access_token={at}'.format(at=self.access_token)) 126 | if response.status_code != 200: 127 | raise(Exception('Invalid response,response code: {c}'.format(c=response.status_code))) 128 | 129 | currentPermissions = response.json()['data'] 130 | if permDict in currentPermissions: 131 | return True 132 | return False 133 | 134 | 135 | def request_permissions(self, perm): 136 | ''' 137 | Requests a permission from the user. 138 | 139 | Parameters: 140 | perm: String 141 | - The permission we would like to get. 142 | 143 | Returns: String 144 | - The URL to redirect the user in order to get the permission. 145 | ''' 146 | authSettings = {'client_id' : self.client_id, 147 | 'redirect_uri' : 'http://localhost:8000/hackathon/', 148 | 'auth_type' : 'rerequest', 149 | 'scope' : perm, 150 | 'access_token' : access_token} 151 | params = urllib.urlencode(authSettings) 152 | self.permission_request_url = REQUEST_PERMISSIONS_URL + '?' + params 153 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon_starter/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for hackathon_starter project. 3 | 4 | For more information on this file, see 5 | https://docs.djangoproject.com/en/1.7/topics/settings/ 6 | 7 | For the full list of settings and their values, see 8 | https://docs.djangoproject.com/en/1.7/ref/settings/ 9 | """ 10 | 11 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 12 | import os 13 | BASE_DIR = os.path.dirname(os.path.dirname(__file__)) 14 | 15 | 16 | # Quick-start development settings - unsuitable for production 17 | # See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/ 18 | 19 | # SECURITY WARNING: keep the secret key used in production secret! 20 | SECRET_KEY = 'keuhh=0*%do-ayvy*m2k=vss*$7)j8q!@u0+d^na7mi2(^!l!d' 21 | 22 | # SECURITY WARNING: don't run with debug turned on in production! 23 | DEBUG = True 24 | 25 | TEMPLATE_DEBUG = True 26 | 27 | ALLOWED_HOSTS = [] 28 | 29 | 30 | # Application definition 31 | 32 | INSTALLED_APPS = ( 33 | 'django.contrib.admin', 34 | 'django.contrib.auth', 35 | 'django.contrib.contenttypes', 36 | 'django.contrib.sessions', 37 | 'django.contrib.messages', 38 | 'django.contrib.staticfiles', 39 | 'hackathon', 40 | 'bootstrapform', 41 | # 'django_openid', 42 | 'django_nose', 43 | 'rest_framework', 44 | 'corsheaders', 45 | ) 46 | 47 | MIDDLEWARE_CLASSES = ( 48 | 'django.contrib.sessions.middleware.SessionMiddleware', 49 | 'corsheaders.middleware.CorsMiddleware', 50 | 'django.middleware.common.CommonMiddleware', 51 | 'django.middleware.csrf.CsrfViewMiddleware', 52 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 53 | 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 54 | 'django.contrib.messages.middleware.MessageMiddleware', 55 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 56 | #'django_openid_consumer.SessionConsumer', 57 | ) 58 | 59 | ROOT_URLCONF = 'hackathon_starter.urls' 60 | 61 | WSGI_APPLICATION = 'hackathon_starter.wsgi.application' 62 | 63 | 64 | # Database 65 | # https://docs.djangoproject.com/en/1.7/ref/settings/#databases 66 | 67 | DATABASES = { 68 | 'default': { 69 | 'ENGINE': 'django.db.backends.sqlite3', 70 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 71 | } 72 | } 73 | 74 | # Internationalization 75 | # https://docs.djangoproject.com/en/1.7/topics/i18n/ 76 | 77 | LANGUAGE_CODE = 'en-us' 78 | 79 | TIME_ZONE = 'UTC' 80 | 81 | USE_I18N = True 82 | 83 | USE_L10N = True 84 | 85 | USE_TZ = True 86 | 87 | 88 | # Static files (CSS, JavaScript, Images) 89 | # https://docs.djangoproject.com/en/1.7/howto/static-files/ 90 | 91 | STATIC_URL = '/static/' 92 | 93 | TEMPLATE_DIRS = [os.path.join(BASE_DIR, 'templates')] 94 | 95 | # Use nose to run all tests 96 | TEST_RUNNER = 'django_nose.NoseTestSuiteRunner' 97 | 98 | # Tell nose to measure coverage on the 'foo' and 'bar' apps 99 | NOSE_ARGS = [ 100 | '--with-coverage', 101 | '--cover-package=hackathon/scripts', 102 | ] 103 | 104 | CORS_ORIGIN_ALLOW_ALL = True 105 | 106 | ############ 107 | # KEYS # 108 | ############ 109 | 110 | GITHUB_CLIENT_ID = 'client_id=2404a1e21aebd902f6db' 111 | GITHUB_CLIENT_SECRET = 'client_secret=3da44769d4b7c9465fa4c812669148a163607c23' 112 | 113 | TUMBLR_CONSUMER_KEY = 'KrSbAc9cYLmIgVAn1D21FjRR97QWsutNMxkPDFBxo8CMWtMk4M' 114 | TUMBLR_CONSUMER_SECRET ='lKWMtL2Lj8zr5pY51PVqT8ugeoG0DjrdgoFewM0QTSyJ12jP8d' 115 | 116 | INSTAGRAM_CLIENT_ID = '77dc10b9e3624e908ce437c0a82da92e' 117 | INSTAGRAM_CLIENT_SECRET = '8bcf3139857149aaba7acaa61288427f' 118 | 119 | GOOGLEMAP_API_KEY = 'AIzaSyA7tttML91EGZ32S_FOOoxu-mbxN9Ojds8' 120 | YAHOO_CONSUMER_KEY = 'dj0yJmk9bUtPVmVpZEczZWp5JmQ9WVdrOWQxbDJkMjFhTmpRbWNHbzlNQS0tJnM9Y29uc3VtZXJzZWNyZXQmeD1iOQ--' 121 | YAHOO_CONSUMER_SECRET = '630e59649caf71255679853ca3f6b0580c571e98' 122 | YAHOO_APP_ID = 'wYvwmZ64' 123 | 124 | TWITTER_CONSUMER_KEY = 'MS8DNyi5HX9HhJgigL24VEkqA' 125 | TWITTER_CONSUMER_SECRET = '1QdaLTNyrGIoZUniToou5bqax8mo7yuzIm7o4XjxzMhBE4UPY1' 126 | TWITTER_ACCESS_TOKEN = '43035062-zulNy9FQtEb2i9DeRGQen62HEDf21hpwWcRVAEOOy' 127 | TWITTER_ACCESS_TOKEN_SECRET = 'EEssSDgD4JbXzksmWHW1stBVxNtwfj1nq5Pd2Plkm17wj' 128 | 129 | MEETUP_CONSUMER_KEY = 'p50vftdqq72tgotpaeqk5660un' 130 | MEETUP_CONSUMER_SECRET = 'i5l00ln2r4mcf161n6451hjoj8' 131 | 132 | BITBUCKET_CONSUMER_KEY = 'nQcSHrjPzaXRq7HjtJ' 133 | BITBUCKET_CONSUMER_SECRET = 'd8XzR8EzgADW9GnyQGb3pZE7rWBtc2RA' 134 | 135 | LINKEDIN_CLIENT_ID = '77p43ettu67h56' 136 | LINKEDIN_CLIENT_SECRET = '0NG9XjmS2IWL5pMl' 137 | 138 | YELP_CONSUMER_KEY = 'EXMisJNWez_PuR5pr06hyQ' 139 | YELP_CONSUMER_SECRET = 'VCK-4cDjtQ9Ra4HC5ltClNiJFXs' 140 | YELP_TOKEN = 'AWYVs7Vim7mwYyT1BLJA2xhNTs_vXLYS' 141 | YELP_TOKEN_SECRET = 'Rv4GrlYxYGhxUs14s0VBfk7JLJY' 142 | 143 | POPAPIKEY = 'be4cd251d8a4f1a3362689088bdb0255:0:71947444' 144 | TOPAPIKEY = 'c9655598e1fd4ff591f6d46f2321260e:17:71947444' 145 | 146 | QUANDLAPIKEY = 'fANs6ykrCdAxas7zpMz7' 147 | 148 | FACEBOOK_APP_ID = '885847011479129' 149 | FACEBOOK_APP_SECRET = '9a81d5797b87885ef608463086a5c4ac' 150 | 151 | GOOGLE_PLUS_APP_ID = '52433353167-5hvsos5pvd2i2dt62trivbqvfk4qc2pv.apps.googleusercontent.com' 152 | GOOGLE_PLUS_APP_SECRET = 'mv1ZcpHqMF6uX7NRTLDC2jXR' 153 | 154 | DROPBOX_APP_ID = '8et85bx2ur6b1fb' 155 | DROPBOX_APP_SECRET = 'xx0virsvtghxlui' 156 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/scripts/tumblr.py: -------------------------------------------------------------------------------- 1 | # pylint: disable=invalid-name 2 | # pylint: disable=too-many-instance-attributes 3 | 4 | ''' 5 | tumblr.py contains methods for authenticating 6 | the user via tumblr OAuth as well as methods 7 | for getting data from Tumblr API. 8 | ''' 9 | 10 | 11 | import requests 12 | import simplejson as json 13 | import time 14 | import re 15 | from bs4 import BeautifulSoup 16 | import urlparse 17 | import oauth2 18 | 19 | request_token_url = 'http://www.tumblr.com/oauth/request_token' 20 | authorize_url = 'http://www.tumblr.com/oauth/authorize' 21 | access_token_url = 'http://www.tumblr.com/oauth/access_token' 22 | 23 | user_uri = "http://api.tumblr.com/v2/user/info" 24 | blog_uri = "http://api.tumblr.com/v2/blog/" 25 | 26 | class TumblrOauthClient(object): 27 | ''' 28 | Class responsible for authenticating the user 29 | via Tumblr OAuth2. 30 | ''' 31 | token = None 32 | oauth_verifier = None 33 | oauth_token = None 34 | oauth_token_secret = None 35 | is_authorized = False 36 | access_token = None 37 | 38 | def __init__(self, consumer_key, consumer_secret): 39 | self.consumer_key = consumer_key 40 | self.consumer_secret = consumer_secret 41 | self.consumer = oauth2.Consumer(consumer_key, consumer_secret) 42 | 43 | def authorize_url(self): 44 | ''' 45 | Redirects user to authorize use. 46 | ''' 47 | client = oauth2.Client(self.consumer) 48 | resp, content = client.request(request_token_url, "GET") 49 | #parse content 50 | if not self.oauth_token: 51 | request_token = dict(urlparse.parse_qsl(content)) 52 | self.oauth_token = request_token['oauth_token'] 53 | self.oauth_token_secret = request_token['oauth_token_secret'] 54 | link = authorize_url + "?oauth_token=" + self.oauth_token + \ 55 | "&redirect_uri=http://127.0.0.1:8000/hackathon/" 56 | return link 57 | 58 | 59 | def access_token_url(self, oauth_verifier=''): 60 | ''' 61 | Returns an access token to the user. 62 | ''' 63 | self.is_authorized = True 64 | token = oauth2.Token(self.oauth_token, self.oauth_token_secret) 65 | self.oauth_verifier = oauth_verifier 66 | print self.oauth_verifier 67 | token.set_verifier(self.oauth_verifier) 68 | client = oauth2.Client(self.consumer, token) 69 | resp, content = client.request(access_token_url, "POST") 70 | self.access_token = dict(urlparse.parse_qsl(content)) 71 | #set verified token 72 | self.token = oauth2.Token(self.access_token['oauth_token'], self.access_token['oauth_token_secret']) 73 | 74 | def getUserInfo(self): 75 | ''' Returns users information. ''' 76 | client = oauth2.Client(self.consumer, self.token) 77 | #print client 78 | resp, content = client.request(user_uri, "POST") 79 | if int(resp['status']) != 200: 80 | raise Exception("Invalid response %s." % resp['status']) 81 | 82 | #return content in json format 83 | jsonlist = json.loads(content) 84 | response = jsonlist['response'] 85 | self.username = str(response['user']['name']) 86 | user_info = response['user'] 87 | total_blogs = len(user_info['blogs']) 88 | #print user_info 89 | return user_info, total_blogs 90 | 91 | 92 | def getBlogInfo(self, user): 93 | ''' Returns blogger's blog information ''' 94 | blog_info = blog_uri + user + ".tumblr.com/info?api_key="+self.consumer_key 95 | req = requests.get(blog_info) 96 | jsonlist = json.loads(req.content) 97 | response = jsonlist['response'] 98 | blog = response['blog'] 99 | blog['updated'] = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(blog['updated'])) 100 | return blog 101 | 102 | 103 | def getTaggedInfo(self, tag): 104 | ''' Return tags related to blog with certain tag. ''' 105 | 106 | tagged_uri = "http://api.tumblr.com/v2/tagged?tag=" + tag + "&api_key=" + \ 107 | self.consumer_key + "&limit=20" 108 | req = requests.get(tagged_uri) 109 | jsonlist = json.loads(req.content) 110 | tags = [] 111 | body = jsonlist['response'] 112 | for blog in body: 113 | for data in blog: 114 | if data == "tags": 115 | #print blog[data] 116 | for i in blog[data]: 117 | m = re.match("(.*)(s*)s(t*)t(a*)a(r*)r(b*)b(u*)u(c*)c(k*)k(.*)", i.lower()) 118 | if not m: 119 | tags.append(i) 120 | 121 | return tags 122 | 123 | 124 | def getTaggedBlog(self, tag): 125 | ''' Return the tagged blogs's captions or post.''' 126 | 127 | tagged_uri = "http://api.tumblr.com/v2/tagged?tag=" + tag + "&api_key=" + \ 128 | self.consumer_key + "&limit=20" 129 | req = requests.get(tagged_uri) 130 | jsonlist = json.loads(req.content) 131 | body = jsonlist['response'] 132 | 133 | tagtext = [] 134 | 135 | for blog in body: 136 | #print "####" 137 | for data in blog: 138 | #post 139 | if data == "body": 140 | if blog[data]: 141 | #print blog[data] 142 | soup = BeautifulSoup(blog[data]) 143 | text = soup.get_text() 144 | tagtext.append(text) 145 | #an image 146 | if data == "caption": 147 | if blog[data]: 148 | #print blog[data] 149 | soup = BeautifulSoup(blog[data]) 150 | text = soup.get_text() 151 | tagtext.append(text) 152 | 153 | return tagtext 154 | -------------------------------------------------------------------------------- /hackathon_starter/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = _build 9 | 10 | # User-friendly check for sphinx-build 11 | ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) 12 | $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) 13 | endif 14 | 15 | # Internal variables. 16 | PAPEROPT_a4 = -D latex_paper_size=a4 17 | PAPEROPT_letter = -D latex_paper_size=letter 18 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 19 | # the i18n builder cannot share the environment and doctrees with the others 20 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 21 | 22 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext 23 | 24 | help: 25 | @echo "Please use \`make ' where is one of" 26 | @echo " html to make standalone HTML files" 27 | @echo " dirhtml to make HTML files named index.html in directories" 28 | @echo " singlehtml to make a single large HTML file" 29 | @echo " pickle to make pickle files" 30 | @echo " json to make JSON files" 31 | @echo " htmlhelp to make HTML files and a HTML help project" 32 | @echo " qthelp to make HTML files and a qthelp project" 33 | @echo " applehelp to make an Apple Help Book" 34 | @echo " devhelp to make HTML files and a Devhelp project" 35 | @echo " epub to make an epub" 36 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 37 | @echo " latexpdf to make LaTeX files and run them through pdflatex" 38 | @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" 39 | @echo " text to make text files" 40 | @echo " man to make manual pages" 41 | @echo " texinfo to make Texinfo files" 42 | @echo " info to make Texinfo files and run them through makeinfo" 43 | @echo " gettext to make PO message catalogs" 44 | @echo " changes to make an overview of all changed/added/deprecated items" 45 | @echo " xml to make Docutils-native XML files" 46 | @echo " pseudoxml to make pseudoxml-XML files for display purposes" 47 | @echo " linkcheck to check all external links for integrity" 48 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 49 | @echo " coverage to run coverage check of the documentation (if enabled)" 50 | 51 | clean: 52 | rm -rf $(BUILDDIR)/* 53 | 54 | html: 55 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 56 | @echo 57 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 58 | 59 | dirhtml: 60 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 61 | @echo 62 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 63 | 64 | singlehtml: 65 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml 66 | @echo 67 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." 68 | 69 | pickle: 70 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 71 | @echo 72 | @echo "Build finished; now you can process the pickle files." 73 | 74 | json: 75 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 76 | @echo 77 | @echo "Build finished; now you can process the JSON files." 78 | 79 | htmlhelp: 80 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 81 | @echo 82 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 83 | ".hhp project file in $(BUILDDIR)/htmlhelp." 84 | 85 | qthelp: 86 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 87 | @echo 88 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 89 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 90 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/DjangoHackathonStarter.qhcp" 91 | @echo "To view the help file:" 92 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/DjangoHackathonStarter.qhc" 93 | 94 | applehelp: 95 | $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp 96 | @echo 97 | @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." 98 | @echo "N.B. You won't be able to view it unless you put it in" \ 99 | "~/Library/Documentation/Help or install it in your application" \ 100 | "bundle." 101 | 102 | devhelp: 103 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp 104 | @echo 105 | @echo "Build finished." 106 | @echo "To view the help file:" 107 | @echo "# mkdir -p $$HOME/.local/share/devhelp/DjangoHackathonStarter" 108 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/DjangoHackathonStarter" 109 | @echo "# devhelp" 110 | 111 | epub: 112 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub 113 | @echo 114 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." 115 | 116 | latex: 117 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 118 | @echo 119 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 120 | @echo "Run \`make' in that directory to run these through (pdf)latex" \ 121 | "(use \`make latexpdf' here to do that automatically)." 122 | 123 | latexpdf: 124 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 125 | @echo "Running LaTeX files through pdflatex..." 126 | $(MAKE) -C $(BUILDDIR)/latex all-pdf 127 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 128 | 129 | latexpdfja: 130 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 131 | @echo "Running LaTeX files through platex and dvipdfmx..." 132 | $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja 133 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 134 | 135 | text: 136 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text 137 | @echo 138 | @echo "Build finished. The text files are in $(BUILDDIR)/text." 139 | 140 | man: 141 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man 142 | @echo 143 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man." 144 | 145 | texinfo: 146 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 147 | @echo 148 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." 149 | @echo "Run \`make' in that directory to run these through makeinfo" \ 150 | "(use \`make info' here to do that automatically)." 151 | 152 | info: 153 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 154 | @echo "Running Texinfo files through makeinfo..." 155 | make -C $(BUILDDIR)/texinfo info 156 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." 157 | 158 | gettext: 159 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale 160 | @echo 161 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." 162 | 163 | changes: 164 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 165 | @echo 166 | @echo "The overview file is in $(BUILDDIR)/changes." 167 | 168 | linkcheck: 169 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 170 | @echo 171 | @echo "Link check complete; look for any errors in the above output " \ 172 | "or in $(BUILDDIR)/linkcheck/output.txt." 173 | 174 | doctest: 175 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 176 | @echo "Testing of doctests in the sources finished, look at the " \ 177 | "results in $(BUILDDIR)/doctest/output.txt." 178 | 179 | coverage: 180 | $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage 181 | @echo "Testing of coverage in the sources finished, look at the " \ 182 | "results in $(BUILDDIR)/coverage/python.txt." 183 | 184 | xml: 185 | $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml 186 | @echo 187 | @echo "Build finished. The XML files are in $(BUILDDIR)/xml." 188 | 189 | pseudoxml: 190 | $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml 191 | @echo 192 | @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." 193 | -------------------------------------------------------------------------------- /hackathon_starter/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | REM Command file for Sphinx documentation 4 | 5 | if "%SPHINXBUILD%" == "" ( 6 | set SPHINXBUILD=sphinx-build 7 | ) 8 | set BUILDDIR=_build 9 | set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . 10 | set I18NSPHINXOPTS=%SPHINXOPTS% . 11 | if NOT "%PAPER%" == "" ( 12 | set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% 13 | set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% 14 | ) 15 | 16 | if "%1" == "" goto help 17 | 18 | if "%1" == "help" ( 19 | :help 20 | echo.Please use `make ^` where ^ is one of 21 | echo. html to make standalone HTML files 22 | echo. dirhtml to make HTML files named index.html in directories 23 | echo. singlehtml to make a single large HTML file 24 | echo. pickle to make pickle files 25 | echo. json to make JSON files 26 | echo. htmlhelp to make HTML files and a HTML help project 27 | echo. qthelp to make HTML files and a qthelp project 28 | echo. devhelp to make HTML files and a Devhelp project 29 | echo. epub to make an epub 30 | echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter 31 | echo. text to make text files 32 | echo. man to make manual pages 33 | echo. texinfo to make Texinfo files 34 | echo. gettext to make PO message catalogs 35 | echo. changes to make an overview over all changed/added/deprecated items 36 | echo. xml to make Docutils-native XML files 37 | echo. pseudoxml to make pseudoxml-XML files for display purposes 38 | echo. linkcheck to check all external links for integrity 39 | echo. doctest to run all doctests embedded in the documentation if enabled 40 | echo. coverage to run coverage check of the documentation if enabled 41 | goto end 42 | ) 43 | 44 | if "%1" == "clean" ( 45 | for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i 46 | del /q /s %BUILDDIR%\* 47 | goto end 48 | ) 49 | 50 | 51 | REM Check if sphinx-build is available and fallback to Python version if any 52 | %SPHINXBUILD% 2> nul 53 | if errorlevel 9009 goto sphinx_python 54 | goto sphinx_ok 55 | 56 | :sphinx_python 57 | 58 | set SPHINXBUILD=python -m sphinx.__init__ 59 | %SPHINXBUILD% 2> nul 60 | if errorlevel 9009 ( 61 | echo. 62 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 63 | echo.installed, then set the SPHINXBUILD environment variable to point 64 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 65 | echo.may add the Sphinx directory to PATH. 66 | echo. 67 | echo.If you don't have Sphinx installed, grab it from 68 | echo.http://sphinx-doc.org/ 69 | exit /b 1 70 | ) 71 | 72 | :sphinx_ok 73 | 74 | 75 | if "%1" == "html" ( 76 | %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html 77 | if errorlevel 1 exit /b 1 78 | echo. 79 | echo.Build finished. The HTML pages are in %BUILDDIR%/html. 80 | goto end 81 | ) 82 | 83 | if "%1" == "dirhtml" ( 84 | %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml 85 | if errorlevel 1 exit /b 1 86 | echo. 87 | echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. 88 | goto end 89 | ) 90 | 91 | if "%1" == "singlehtml" ( 92 | %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml 93 | if errorlevel 1 exit /b 1 94 | echo. 95 | echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. 96 | goto end 97 | ) 98 | 99 | if "%1" == "pickle" ( 100 | %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle 101 | if errorlevel 1 exit /b 1 102 | echo. 103 | echo.Build finished; now you can process the pickle files. 104 | goto end 105 | ) 106 | 107 | if "%1" == "json" ( 108 | %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json 109 | if errorlevel 1 exit /b 1 110 | echo. 111 | echo.Build finished; now you can process the JSON files. 112 | goto end 113 | ) 114 | 115 | if "%1" == "htmlhelp" ( 116 | %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp 117 | if errorlevel 1 exit /b 1 118 | echo. 119 | echo.Build finished; now you can run HTML Help Workshop with the ^ 120 | .hhp project file in %BUILDDIR%/htmlhelp. 121 | goto end 122 | ) 123 | 124 | if "%1" == "qthelp" ( 125 | %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp 126 | if errorlevel 1 exit /b 1 127 | echo. 128 | echo.Build finished; now you can run "qcollectiongenerator" with the ^ 129 | .qhcp project file in %BUILDDIR%/qthelp, like this: 130 | echo.^> qcollectiongenerator %BUILDDIR%\qthelp\DjangoHackathonStarter.qhcp 131 | echo.To view the help file: 132 | echo.^> assistant -collectionFile %BUILDDIR%\qthelp\DjangoHackathonStarter.ghc 133 | goto end 134 | ) 135 | 136 | if "%1" == "devhelp" ( 137 | %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp 138 | if errorlevel 1 exit /b 1 139 | echo. 140 | echo.Build finished. 141 | goto end 142 | ) 143 | 144 | if "%1" == "epub" ( 145 | %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub 146 | if errorlevel 1 exit /b 1 147 | echo. 148 | echo.Build finished. The epub file is in %BUILDDIR%/epub. 149 | goto end 150 | ) 151 | 152 | if "%1" == "latex" ( 153 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 154 | if errorlevel 1 exit /b 1 155 | echo. 156 | echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. 157 | goto end 158 | ) 159 | 160 | if "%1" == "latexpdf" ( 161 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 162 | cd %BUILDDIR%/latex 163 | make all-pdf 164 | cd %~dp0 165 | echo. 166 | echo.Build finished; the PDF files are in %BUILDDIR%/latex. 167 | goto end 168 | ) 169 | 170 | if "%1" == "latexpdfja" ( 171 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 172 | cd %BUILDDIR%/latex 173 | make all-pdf-ja 174 | cd %~dp0 175 | echo. 176 | echo.Build finished; the PDF files are in %BUILDDIR%/latex. 177 | goto end 178 | ) 179 | 180 | if "%1" == "text" ( 181 | %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text 182 | if errorlevel 1 exit /b 1 183 | echo. 184 | echo.Build finished. The text files are in %BUILDDIR%/text. 185 | goto end 186 | ) 187 | 188 | if "%1" == "man" ( 189 | %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man 190 | if errorlevel 1 exit /b 1 191 | echo. 192 | echo.Build finished. The manual pages are in %BUILDDIR%/man. 193 | goto end 194 | ) 195 | 196 | if "%1" == "texinfo" ( 197 | %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo 198 | if errorlevel 1 exit /b 1 199 | echo. 200 | echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. 201 | goto end 202 | ) 203 | 204 | if "%1" == "gettext" ( 205 | %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale 206 | if errorlevel 1 exit /b 1 207 | echo. 208 | echo.Build finished. The message catalogs are in %BUILDDIR%/locale. 209 | goto end 210 | ) 211 | 212 | if "%1" == "changes" ( 213 | %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes 214 | if errorlevel 1 exit /b 1 215 | echo. 216 | echo.The overview file is in %BUILDDIR%/changes. 217 | goto end 218 | ) 219 | 220 | if "%1" == "linkcheck" ( 221 | %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck 222 | if errorlevel 1 exit /b 1 223 | echo. 224 | echo.Link check complete; look for any errors in the above output ^ 225 | or in %BUILDDIR%/linkcheck/output.txt. 226 | goto end 227 | ) 228 | 229 | if "%1" == "doctest" ( 230 | %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest 231 | if errorlevel 1 exit /b 1 232 | echo. 233 | echo.Testing of doctests in the sources finished, look at the ^ 234 | results in %BUILDDIR%/doctest/output.txt. 235 | goto end 236 | ) 237 | 238 | if "%1" == "coverage" ( 239 | %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage 240 | if errorlevel 1 exit /b 1 241 | echo. 242 | echo.Testing of coverage in the sources finished, look at the ^ 243 | results in %BUILDDIR%/coverage/python.txt. 244 | goto end 245 | ) 246 | 247 | if "%1" == "xml" ( 248 | %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml 249 | if errorlevel 1 exit /b 1 250 | echo. 251 | echo.Build finished. The XML files are in %BUILDDIR%/xml. 252 | goto end 253 | ) 254 | 255 | if "%1" == "pseudoxml" ( 256 | %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml 257 | if errorlevel 1 exit /b 1 258 | echo. 259 | echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. 260 | goto end 261 | ) 262 | 263 | :end 264 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/scripts/instagram.py: -------------------------------------------------------------------------------- 1 | ''' 2 | instagram.py contains a handful of methods for interacting 3 | with Instagram data and returning the responses as JSON. 4 | ''' 5 | 6 | import requests 7 | import urllib 8 | import urllib2 9 | import json 10 | import simplejson as json2 11 | import googlemaps 12 | from django.conf import settings 13 | from datetime import datetime 14 | 15 | AUTHORIZATION_URL = 'https://api.instagram.com/oauth/authorize/?client_id=' 16 | ACCESS_TOKEN_URL = 'https://api.instagram.com/oauth/access_token' 17 | 18 | class InstagramOauthClient(object): 19 | ''' 20 | Python Client for Instagram API. 21 | ''' 22 | 23 | access_token = None 24 | user_data = None 25 | is_authorized = False 26 | 27 | def __init__(self, client_id, client_secret): 28 | ''' 29 | Parameters: 30 | client_id: String 31 | - The client_id from registering application 32 | on Instagram. 33 | client_secret: String 34 | - The client_secret from registering application 35 | on Instagram. 36 | ''' 37 | self.client_id = client_id 38 | self.client_secret = client_secret 39 | 40 | 41 | def get_authorize_url(self): 42 | ''' 43 | Obtains authorize url link with given client_id. 44 | 45 | Returns: 46 | authURL: String 47 | - The authorization url. 48 | ''' 49 | 50 | redirectUri = '&redirect_uri=http://127.0.0.1:8000/hackathon/&response_type=code' 51 | authURL = AUTHORIZATION_URL + self.client_id + redirectUri 52 | #print authURL 53 | return authURL 54 | 55 | def get_access_token(self, code): 56 | ''' 57 | Obtains access token. 58 | 59 | Parameters: 60 | code: String 61 | - The code is retrieved from the authorization url parameter 62 | to obtain access_token. 63 | ''' 64 | 65 | authSetting = { 66 | 'client_id' : self.client_id, 67 | 'client_secret' : self.client_secret, 68 | 'grant_type' : 'authorization_code', 69 | 'redirect_uri' : 'http://127.0.0.1:8000/hackathon/', 70 | 'code' : code} 71 | 72 | authSettingUrl = urllib.urlencode(authSetting) 73 | req = urllib2.Request(ACCESS_TOKEN_URL, authSettingUrl) 74 | content = urllib2.urlopen(req) 75 | jsonlist = json.load(content) 76 | self.access_token = jsonlist['access_token'] 77 | self.user_data = jsonlist['user'] 78 | self.is_authorized = True 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | def searchForLocation(address): 87 | ''' 88 | Parameters: 89 | address: String 90 | - The address is a user input. 91 | 92 | Returns: 93 | location: Dictionary 94 | - A dictionary returning the latitude, and longitude 95 | of an address. 96 | ''' 97 | 98 | gmaps = googlemaps.Client(key=settings.GOOGLEMAP_API_KEY) 99 | #geocoding and address 100 | geocodeResult = gmaps.geocode(address) 101 | 102 | if geocodeResult: 103 | location = geocodeResult[0]['geometry']['location'] 104 | return location 105 | 106 | 107 | def getTaggedMedia(tag, accessToken): 108 | ''' 109 | Get recent tagged media. 110 | 111 | Parameters: 112 | tag: String 113 | - The tag used to search the most recent media that's tagged with it. 114 | 115 | Returns: 116 | data: Dictionary 117 | - A dictionary containing recent tagged 120 media 118 | counts data pertaining to each media. 119 | ''' 120 | 121 | tagUri = 'https://api.instagram.com/v1/tags/' 122 | taggedMediaUrl = tagUri + tag + '/media/recent?access_token=' + accessToken 123 | req = requests.get(taggedMediaUrl) 124 | content = json2.loads(req.content) 125 | data = content['data'] 126 | 127 | while len(data) <= 100: 128 | nextUrl = content['pagination']['next_url'] 129 | req = requests.get(nextUrl) 130 | content = json2.loads(req.content) 131 | for i in content['data']: 132 | data.append(i) 133 | #print len(data) 134 | return data 135 | 136 | 137 | def getUserInfo(accessToken): 138 | ''' 139 | Get user information. 140 | 141 | Parameters: 142 | access_token: String 143 | - The access_token given after granting permission 144 | application access to Instagram data. 145 | 146 | Returns: 147 | data: Dictionary 148 | - A dictionary containing user information. 149 | ''' 150 | 151 | userInfo = 'https://api.instagram.com/v1/users/32833691/?access_token='+accessToken 152 | req = requests.get(userInfo) 153 | content = json2.loads(req.content) 154 | data = content['data'] 155 | return data 156 | 157 | 158 | def getUserMedia(userId, accessToken): 159 | ''' 160 | Parameters: 161 | accessToken: String 162 | - The access_token given after granting permission 163 | application access to Instagram data. 164 | userId: Integer 165 | - User's instagram ID number. 166 | 167 | Returns: 168 | data: Dictionary 169 | - A dictionary containing user media information. 170 | ''' 171 | 172 | userMediaUri = 'https://api.instagram.com/v1/users/' + str(userId) 173 | userMedia = userMediaUri + '/media/recent/?access_token=' + accessToken 174 | req = requests.get(userMedia) 175 | content = json2.loads(req.content) 176 | data = content['data'] 177 | return data 178 | 179 | 180 | def searchLocationIds(lat, lng, accessToken): 181 | ''' 182 | Parameters: 183 | lat: Float 184 | - The latitude of the input address 185 | lng: Float 186 | - The longitude of the input address 187 | 188 | Returns: 189 | listOfIds: Dictionary 190 | - A dictionary returning the list of location ids 191 | of the given address coordinates. 192 | ''' 193 | 194 | locIdUri = 'https://api.instagram.com/v1/locations/search?lat=' + str(lat) 195 | location = locIdUri+'&lng='+str(lng)+'&access_token='+ accessToken+'&distance=5000' 196 | req = requests.get(location) 197 | data = json2.loads(req.content) 198 | listOfIds = [] 199 | if data['meta']['code'] != 200: 200 | raise Exception("Invalid response %s." % data['meta']['code']) 201 | searchIds = data['data'] 202 | for data in searchIds: 203 | for i in data: 204 | if i == 'id': 205 | listOfIds.append(data[i]) 206 | return listOfIds 207 | 208 | 209 | def searchLocationMedia(listOfLocationIds, accessToken): 210 | ''' 211 | Parameters: 212 | listOfLocationIds: Float 213 | - list of location ids retrieve from coordinate of 214 | of searched address. 215 | access_token: String 216 | - The access_token given after granting permission 217 | application access to Instagram data. 218 | 219 | Returns: 220 | media: Dictionary 221 | - A dictionary returning the list of recent media 222 | of the list of location ids. 223 | ''' 224 | 225 | media = [] 226 | locationUri = 'https://api.instagram.com/v1/locations/' 227 | for location in listOfLocationIds: 228 | mediaByLocation = locationUri+location+'/media/recent?access_token='+ accessToken 229 | req = requests.get(mediaByLocation) 230 | contentAll = json2.loads(req.content) 231 | if contentAll['pagination']: 232 | tempMedia = [] 233 | nextUrl = contentAll['pagination']['next_url'] 234 | req = requests.get(nextUrl) 235 | content = json2.loads(req.content) 236 | for i in content['data']: 237 | i['created_time'] = datetime.fromtimestamp(int(i['created_time'])) 238 | i['created_time'] = i['created_time'].strftime('%Y-%m-%d %H:%M:%S') 239 | tempMedia.append(i) 240 | media += [tempMedia] 241 | else: 242 | for i in contentAll['data']: 243 | for data in i: 244 | if data == 'created_time': 245 | i[data] = datetime.fromtimestamp(int(i[data])) 246 | i[data] = i[data].strftime('%Y-%m-%d %H:%M:%S') 247 | media.append(contentAll['data']) 248 | return media 249 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/scripts/twitter.py: -------------------------------------------------------------------------------- 1 | # pylint: disable=too-many-instance-attributes 2 | # pylint: disable=unused-variable 3 | # pylint: disable=too-many-arguments 4 | 5 | ''' 6 | twitter.py contains a handful of methods for interacting 7 | with Twitter data and returning the responses as JSON. 8 | ''' 9 | 10 | 11 | import urlparse 12 | import oauth2 as oauth 13 | import requests 14 | import base64, random 15 | import urllib 16 | import binascii 17 | import time, collections, hmac, hashlib 18 | import simplejson as json2 19 | import codecs 20 | import json 21 | 22 | REQUEST_TOKEN_URL = 'https://api.twitter.com/oauth/request_token' 23 | ACCESS_TOKEN_URL = 'https://api.twitter.com/oauth/access_token' 24 | AUTHORIZE_URL = 'https://api.twitter.com/oauth/authorize' 25 | 26 | class TwitterOauthClient(object): 27 | ''' 28 | Python Client for Twitter API. 29 | ''' 30 | 31 | oauth_token = None 32 | oauth_token_secret = None 33 | username = None 34 | is_authorized = False 35 | 36 | 37 | def __init__(self, consumer_key, consumer_secret, access_token, access_token_secret): 38 | ''' 39 | Parameters: 40 | consumer_key: String 41 | - The consumer_key from registering application 42 | on Instagram. 43 | consumer_secret: String 44 | - The consumer_secret from registering application 45 | on Instagram. 46 | ''' 47 | 48 | self.consumer_key = consumer_key 49 | self.consumer_secret = consumer_secret 50 | self.access_token = access_token 51 | self.access_token_secret = access_token_secret 52 | self.consumer = oauth.Consumer(key=self.consumer_key, secret=self.consumer_secret) 53 | 54 | 55 | def get_authorize_url(self): 56 | ''' 57 | Obtained oauth_token and oauth_token_secret from request_token_url, 58 | returns an authorize url. 59 | 60 | From the redirect url, we obtain the oauth verifier. 61 | 62 | Returns: 63 | authURL: String 64 | - The authorization url. 65 | ''' 66 | 67 | client = oauth.Client(self.consumer) 68 | resp, content = client.request(REQUEST_TOKEN_URL, 'GET') 69 | 70 | #if int(resp['status']) != 200: 71 | # raise Exception('Invalid response %s' %resp['status']) 72 | 73 | requestToken = dict(urlparse.parse_qsl(content)) 74 | 75 | #temporary 76 | self.oauth_token = requestToken['oauth_token'] 77 | self.oauth_token_secret = requestToken['oauth_token_secret'] 78 | #print self.oauth_token 79 | 80 | #link to authorize app access twitter data and return to twitter api example page 81 | redirectUri = '&redirect_uri=http%3A%2F%2Flocalhost%3A8000/hackathon/twitter/' 82 | authURL = AUTHORIZE_URL+"?oauth_token="+self.oauth_token+redirectUri 83 | return authURL 84 | 85 | 86 | def get_access_token_url(self, oauthVerifier): 87 | ''' 88 | Get access token from redirect url. 89 | 90 | Parameters: 91 | oauthVerifier: String 92 | - A paramater retrieved from scraping the redirect url. 93 | 94 | Returns: 95 | data: Dictionary 96 | - A dictionary containing recent tagged 120 media 97 | counts data pertaining to each media. 98 | ''' 99 | 100 | token = oauth.Token(self.oauth_token, self.oauth_token_secret) 101 | token.set_verifier(oauthVerifier) 102 | 103 | client = oauth.Client(self.consumer, token) 104 | resp, content = client.request(ACCESS_TOKEN_URL, 'POST') 105 | 106 | if int(resp['status']) != 200: 107 | raise Exception('Invalid response %s' %resp['status']) 108 | 109 | #print content 110 | accessToken = dict(urlparse.parse_qsl(content)) 111 | 112 | #permanent 113 | self.oauth_token = accessToken['oauth_token'] 114 | self.oauth_token_secret = accessToken['oauth_token_secret'] 115 | self.username = accessToken['screen_name'] 116 | self.is_authorized = True 117 | 118 | 119 | def get_tweets(self, tweet): 120 | ''' 121 | Get tweets of relevant search query. 122 | ''' 123 | method = 'get' 124 | link = 'https://api.twitter.com/1.1/search/tweets.json' 125 | linkParameters = {'q': tweet, 'count': '100', 'result_type': 'popular'} 126 | 127 | oauthParameters = getOauthParameters( 128 | self.consumer_key, 129 | self.access_token 130 | ) 131 | 132 | oauthParameters['oauth_signature'] = generateSignature( 133 | method, 134 | link, 135 | linkParameters, 136 | oauthParameters, 137 | self.consumer_secret, 138 | self.access_token_secret 139 | ) 140 | 141 | headers = {'Authorization': createAuthHeader(oauthParameters)} 142 | 143 | link += '?' + urllib.urlencode(linkParameters) 144 | 145 | req = requests.get(link, headers=headers) 146 | 147 | if int(req.status_code) != 200: 148 | raise Exception('Invalid response %s' %req.status_code) 149 | 150 | content = json2.loads(req.content) 151 | 152 | jsonlist = {} 153 | for contrib in content['statuses']: 154 | for e in contrib: 155 | if e == 'retweet_count': 156 | if contrib['user']['screen_name'] in jsonlist: 157 | jsonlist[contrib['user']['screen_name']][contrib[e]] = str(contrib['text'].encode('ascii', 'ignore')) 158 | else: 159 | jsonlist[contrib['user']['screen_name']] = { contrib[e]:str(contrib['text'].encode('ascii', 'ignore'))} 160 | 161 | 162 | return content['statuses'], json.dumps(jsonlist) 163 | 164 | 165 | def get_trends_available(self, yahooConsumerKey): 166 | ''' 167 | Get the locations that Twitter has trending topic information for. 168 | 169 | ''' 170 | 171 | method = 'get' 172 | link = 'https://api.twitter.com/1.1/trends/available.json' 173 | linkParameters = {} 174 | 175 | oauthParameters = getOauthParameters( 176 | self.consumer_key, 177 | self.access_token 178 | ) 179 | 180 | oauthParameters['oauth_signature'] = generateSignature( 181 | method, 182 | link, 183 | linkParameters, 184 | oauthParameters, 185 | self.consumer_secret, 186 | self.access_token_secret 187 | ) 188 | 189 | headers = {'Authorization': createAuthHeader(oauthParameters)} 190 | 191 | if linkParameters: 192 | link += '?'+urllib.urlencode(linkParameters) 193 | 194 | req = requests.get(link, headers=headers) 195 | #print req.status_code 196 | 197 | if int(req.status_code) != 200: 198 | raise Exception('Invalid response %s' %req.status_code) 199 | 200 | content = json2.loads(req.content) 201 | #print len(content) 202 | 203 | for place in content: 204 | for item in place: 205 | if item == 'url': 206 | url = place[item]+'/neighbors?appid='+yahooConsumerKey+'&format=json' 207 | requestNeighborData = requests.get(url) 208 | #print request_neighbor_data.status_code 209 | if requestNeighborData.status_code == 200: 210 | neighbor = json2.loads(requestNeighborData.content) 211 | else: 212 | neighbor = {} 213 | 214 | place['neighbor'] = neighbor 215 | #print place 216 | 217 | 218 | return content 219 | 220 | 221 | 222 | def percentEncode(string): 223 | ''' 224 | Percent encode strings. 225 | ''' 226 | return urllib.quote(string, safe='~') 227 | 228 | 229 | def getNonce(): 230 | ''' 231 | Generate unique token per request. 232 | ''' 233 | 234 | nonce = base64.b64encode(''.join([str(random.randint(0, 9)) for i in range(24)])) 235 | return nonce 236 | 237 | def generateSignature(method, link, linkParameters, oauthParameters, 238 | oauthConsumerSecret, oauthTokenSecret=None): 239 | ''' 240 | Generate signature. 241 | ''' 242 | 243 | if linkParameters: 244 | newDict = dict(oauthParameters, **linkParameters) 245 | params = urllib.urlencode(collections.OrderedDict(sorted(newDict.items()))) 246 | else: 247 | params = urllib.urlencode(collections.OrderedDict(sorted(oauthParameters.items()))) 248 | 249 | #Create your Signature Base String 250 | signatureBaseString = (method.upper()+'&'+percentEncode(str(link))+'&'+percentEncode(params)) 251 | 252 | #Get the signing key 253 | signingKey = createSigningKey(oauthConsumerSecret, oauthTokenSecret) 254 | 255 | return calculateSignature(signingKey, signatureBaseString) 256 | 257 | 258 | 259 | def calculateSignature(signingKey, signatureBaseString): 260 | ''' 261 | Calculate signature using HMAC-SHA1 hashing algorithm. 262 | ''' 263 | hashed = hmac.new(signingKey, signatureBaseString, hashlib.sha1) 264 | 265 | sig = binascii.b2a_base64(hashed.digest())[:-1] 266 | 267 | return percentEncode(sig) 268 | 269 | 270 | def createSigningKey(oauthConsumerSecret, oauthTokenSecret): 271 | ''' 272 | Creates a key to sign the request with. 273 | ''' 274 | 275 | signingKey = percentEncode(oauthConsumerSecret) + '&' + percentEncode(oauthTokenSecret) 276 | 277 | return signingKey 278 | 279 | 280 | def createAuthHeader(parameters): 281 | ''' 282 | Format authorization header with oath parameters. 283 | ''' 284 | 285 | orderedParameters = collections.OrderedDict(sorted(parameters.items())) 286 | authHeader = ('%s="%s"' % (k, v) for k, v in orderedParameters.iteritems()) 287 | 288 | return "OAuth " + ', '.join(authHeader) 289 | 290 | 291 | def getOauthParameters(consumerKey, accessToken): 292 | ''' 293 | Returns parameters for making requests. 294 | ''' 295 | oauthParameters = { 296 | 'oauth_timestamp': str(int(time.time())), 297 | 'oauth_signature_method': "HMAC-SHA1", 298 | 'oauth_version': "1.0", 299 | 'oauth_token': accessToken, 300 | 'oauth_nonce': getNonce(), 301 | 'oauth_consumer_key': consumerKey 302 | } 303 | 304 | return oauthParameters 305 | -------------------------------------------------------------------------------- /hackathon_starter/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Django Hackathon Starter documentation build configuration file, created by 4 | # sphinx-quickstart on Sun Apr 12 22:33:44 2015. 5 | # 6 | # This file is execfile()d with the current directory set to its 7 | # containing dir. 8 | # 9 | # Note that not all possible configuration values are present in this 10 | # autogenerated file. 11 | # 12 | # All configuration values have a default; values that are commented out 13 | # serve to show the default. 14 | 15 | import sys 16 | import os 17 | import shlex 18 | 19 | # If extensions (or modules to document with autodoc) are in another directory, 20 | # add these directories to sys.path here. If the directory is relative to the 21 | # documentation root, use os.path.abspath to make it absolute, like shown here. 22 | #sys.path.insert(0, os.path.abspath('.')) 23 | sys.path.insert(0, os.path.abspath("hackathon/scripts/")) 24 | 25 | # -- General configuration ------------------------------------------------ 26 | 27 | # If your documentation needs a minimal Sphinx version, state it here. 28 | #needs_sphinx = '1.0' 29 | 30 | # Add any Sphinx extension module names here, as strings. They can be 31 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 32 | # ones. 33 | extensions = [ 34 | 'sphinx.ext.autodoc', 35 | 'sphinx.ext.doctest', 36 | 'sphinx.ext.todo', 37 | 'sphinx.ext.coverage', 38 | 'sphinx.ext.mathjax', 39 | 'sphinx.ext.ifconfig', 40 | 'sphinx.ext.viewcode', 41 | ] 42 | 43 | # Add any paths that contain templates here, relative to this directory. 44 | templates_path = ['_templates'] 45 | 46 | # The suffix(es) of source filenames. 47 | # You can specify multiple suffix as a list of string: 48 | # source_suffix = ['.rst', '.md'] 49 | source_suffix = '.rst' 50 | 51 | # The encoding of source files. 52 | #source_encoding = 'utf-8-sig' 53 | 54 | # The master toctree document. 55 | master_doc = 'index' 56 | 57 | # General information about the project. 58 | project = u'Django Hackathon Starter' 59 | copyright = u'2015, David Leonard, Wan Kim Mok, Marco Quezada, Eswari Pravallika Swarna' 60 | author = u'David Leonard, Wan Kim Mok, Marco Quezada, Eswari Pravallika Swarna' 61 | 62 | # The version info for the project you're documenting, acts as replacement for 63 | # |version| and |release|, also used in various other places throughout the 64 | # built documents. 65 | # 66 | # The short X.Y version. 67 | version = '0.0.1' 68 | # The full version, including alpha/beta/rc tags. 69 | release = '0.0.1' 70 | 71 | # The language for content autogenerated by Sphinx. Refer to documentation 72 | # for a list of supported languages. 73 | # 74 | # This is also used if you do content translation via gettext catalogs. 75 | # Usually you set "language" from the command line for these cases. 76 | language = None 77 | 78 | # There are two options for replacing |today|: either, you set today to some 79 | # non-false value, then it is used: 80 | #today = '' 81 | # Else, today_fmt is used as the format for a strftime call. 82 | #today_fmt = '%B %d, %Y' 83 | 84 | # List of patterns, relative to source directory, that match files and 85 | # directories to ignore when looking for source files. 86 | exclude_patterns = ['_build'] 87 | 88 | # The reST default role (used for this markup: `text`) to use for all 89 | # documents. 90 | #default_role = None 91 | 92 | # If true, '()' will be appended to :func: etc. cross-reference text. 93 | #add_function_parentheses = True 94 | 95 | # If true, the current module name will be prepended to all description 96 | # unit titles (such as .. function::). 97 | #add_module_names = True 98 | 99 | # If true, sectionauthor and moduleauthor directives will be shown in the 100 | # output. They are ignored by default. 101 | #show_authors = False 102 | 103 | # The name of the Pygments (syntax highlighting) style to use. 104 | pygments_style = 'sphinx' 105 | 106 | # A list of ignored prefixes for module index sorting. 107 | #modindex_common_prefix = [] 108 | 109 | # If true, keep warnings as "system message" paragraphs in the built documents. 110 | #keep_warnings = False 111 | 112 | # If true, `todo` and `todoList` produce output, else they produce nothing. 113 | todo_include_todos = True 114 | 115 | 116 | # -- Options for HTML output ---------------------------------------------- 117 | 118 | # The theme to use for HTML and HTML Help pages. See the documentation for 119 | # a list of builtin themes. 120 | html_theme = 'alabaster' 121 | 122 | # Theme options are theme-specific and customize the look and feel of a theme 123 | # further. For a list of options available for each theme, see the 124 | # documentation. 125 | #html_theme_options = {} 126 | 127 | # Add any paths that contain custom themes here, relative to this directory. 128 | #html_theme_path = [] 129 | 130 | # The name for this set of Sphinx documents. If None, it defaults to 131 | # " v documentation". 132 | #html_title = None 133 | 134 | # A shorter title for the navigation bar. Default is the same as html_title. 135 | #html_short_title = None 136 | 137 | # The name of an image file (relative to this directory) to place at the top 138 | # of the sidebar. 139 | #html_logo = None 140 | 141 | # The name of an image file (within the static path) to use as favicon of the 142 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 143 | # pixels large. 144 | #html_favicon = None 145 | 146 | # Add any paths that contain custom static files (such as style sheets) here, 147 | # relative to this directory. They are copied after the builtin static files, 148 | # so a file named "default.css" will overwrite the builtin "default.css". 149 | html_static_path = ['_static'] 150 | 151 | # Add any extra paths that contain custom files (such as robots.txt or 152 | # .htaccess) here, relative to this directory. These files are copied 153 | # directly to the root of the documentation. 154 | #html_extra_path = [] 155 | 156 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, 157 | # using the given strftime format. 158 | #html_last_updated_fmt = '%b %d, %Y' 159 | 160 | # If true, SmartyPants will be used to convert quotes and dashes to 161 | # typographically correct entities. 162 | #html_use_smartypants = True 163 | 164 | # Custom sidebar templates, maps document names to template names. 165 | #html_sidebars = {} 166 | 167 | # Additional templates that should be rendered to pages, maps page names to 168 | # template names. 169 | #html_additional_pages = {} 170 | 171 | # If false, no module index is generated. 172 | #html_domain_indices = True 173 | 174 | # If false, no index is generated. 175 | #html_use_index = True 176 | 177 | # If true, the index is split into individual pages for each letter. 178 | #html_split_index = False 179 | 180 | # If true, links to the reST sources are added to the pages. 181 | #html_show_sourcelink = True 182 | 183 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. 184 | #html_show_sphinx = True 185 | 186 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. 187 | #html_show_copyright = True 188 | 189 | # If true, an OpenSearch description file will be output, and all pages will 190 | # contain a tag referring to it. The value of this option must be the 191 | # base URL from which the finished HTML is served. 192 | #html_use_opensearch = '' 193 | 194 | # This is the file name suffix for HTML files (e.g. ".xhtml"). 195 | #html_file_suffix = None 196 | 197 | # Language to be used for generating the HTML full-text search index. 198 | # Sphinx supports the following languages: 199 | # 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' 200 | # 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr' 201 | #html_search_language = 'en' 202 | 203 | # A dictionary with options for the search language support, empty by default. 204 | # Now only 'ja' uses this config value 205 | #html_search_options = {'type': 'default'} 206 | 207 | # The name of a javascript file (relative to the configuration directory) that 208 | # implements a search results scorer. If empty, the default will be used. 209 | #html_search_scorer = 'scorer.js' 210 | 211 | # Output file base name for HTML help builder. 212 | htmlhelp_basename = 'DjangoHackathonStarterdoc' 213 | 214 | # -- Options for LaTeX output --------------------------------------------- 215 | 216 | latex_elements = { 217 | # The paper size ('letterpaper' or 'a4paper'). 218 | #'papersize': 'letterpaper', 219 | 220 | # The font size ('10pt', '11pt' or '12pt'). 221 | #'pointsize': '10pt', 222 | 223 | # Additional stuff for the LaTeX preamble. 224 | #'preamble': '', 225 | 226 | # Latex figure (float) alignment 227 | #'figure_align': 'htbp', 228 | } 229 | 230 | # Grouping the document tree into LaTeX files. List of tuples 231 | # (source start file, target name, title, 232 | # author, documentclass [howto, manual, or own class]). 233 | latex_documents = [ 234 | (master_doc, 'DjangoHackathonStarter.tex', u'Django Hackathon Starter Documentation', 235 | u'David Leonard, Wan Kim Mok, Marco Quezada, Eswari Pravallika Swarna', 'manual'), 236 | ] 237 | 238 | # The name of an image file (relative to this directory) to place at the top of 239 | # the title page. 240 | #latex_logo = None 241 | 242 | # For "manual" documents, if this is true, then toplevel headings are parts, 243 | # not chapters. 244 | #latex_use_parts = False 245 | 246 | # If true, show page references after internal links. 247 | #latex_show_pagerefs = False 248 | 249 | # If true, show URL addresses after external links. 250 | #latex_show_urls = False 251 | 252 | # Documents to append as an appendix to all manuals. 253 | #latex_appendices = [] 254 | 255 | # If false, no module index is generated. 256 | #latex_domain_indices = True 257 | 258 | 259 | # -- Options for manual page output --------------------------------------- 260 | 261 | # One entry per manual page. List of tuples 262 | # (source start file, name, description, authors, manual section). 263 | man_pages = [ 264 | (master_doc, 'djangohackathonstarter', u'Django Hackathon Starter Documentation', 265 | [author], 1) 266 | ] 267 | 268 | # If true, show URL addresses after external links. 269 | #man_show_urls = False 270 | 271 | 272 | # -- Options for Texinfo output ------------------------------------------- 273 | 274 | # Grouping the document tree into Texinfo files. List of tuples 275 | # (source start file, target name, title, author, 276 | # dir menu entry, description, category) 277 | texinfo_documents = [ 278 | (master_doc, 'DjangoHackathonStarter', u'Django Hackathon Starter Documentation', 279 | author, 'DjangoHackathonStarter', 'One line description of project.', 280 | 'Miscellaneous'), 281 | ] 282 | 283 | # Documents to append as an appendix to all manuals. 284 | #texinfo_appendices = [] 285 | 286 | # If false, no module index is generated. 287 | #texinfo_domain_indices = True 288 | 289 | # How to display URL addresses: 'footnote', 'no', or 'inline'. 290 | #texinfo_show_urls = 'footnote' 291 | 292 | # If true, do not generate a @detailmenu in the "Top" node's menu. 293 | #texinfo_no_detailmenu = False 294 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/scripts/github.py: -------------------------------------------------------------------------------- 1 | ''' 2 | github.py contains a handful of methods for interacting 3 | with Github data and returning the responses as JSON. 4 | ''' 5 | 6 | import requests 7 | import simplejson as json 8 | import urllib, urlparse 9 | 10 | ######################## 11 | # GITHUB API CONSTANTS # 12 | ######################## 13 | 14 | API_BASE_URL = 'https://api.github.com/users/' 15 | 16 | AUTHORIZE_URL = 'https://github.com/login/oauth/authorize' 17 | ACCESS_TOKEN_URL = 'https://github.com/login/oauth/access_token' 18 | 19 | class GithubOauthClient(object): 20 | ''' 21 | Python Client for Github API. 22 | ''' 23 | access_token = None 24 | token_type = None 25 | 26 | def __init__(self, client_id, client_secret): 27 | ''' 28 | Parameters: 29 | client_id: String 30 | - The client_id from registering application 31 | on Github. 32 | client_secret: String 33 | - The client_secret from registering application 34 | on Github. 35 | ''' 36 | self.client_id = client_id 37 | self.client_secret = client_secret 38 | 39 | def get_authorize_url(self): 40 | ''' 41 | Obtains authorize url link with given client_id. 42 | 43 | Returns: 44 | authURL: String 45 | - The authorization url. 46 | ''' 47 | 48 | authSetting = {'client_id': self.client_id, 49 | 'redirect_uri': 'http://127.0.0.1:8000/hackathon/', 50 | 'scope': 'user, public_repo, repo, repo_deployment, notifications, gist'} 51 | params = urllib.urlencode(authSetting) 52 | authURL = AUTHORIZE_URL + '?' + params 53 | 54 | return authURL 55 | 56 | def get_access_token(self, code): 57 | ''' 58 | Obtains access token. 59 | 60 | Parameters: 61 | code: String 62 | - The code is retrieved from the authorization url parameter 63 | to obtain access_token. 64 | ''' 65 | 66 | settings = {'client_id': self.client_id, 67 | 'client_secret': self.client_secret, 68 | 'code': code, 69 | 'redirect_uri': 'http://127.0.0.1:8000/hackathon/', 70 | 'accept': 'json'} 71 | params = urllib.urlencode(settings) 72 | accessLink = ACCESS_TOKEN_URL + '?' + params 73 | req = requests.get(accessLink) 74 | 75 | if int(req.status_code) != 200: 76 | raise Exception('Invalid response %s' %req.status_code) 77 | 78 | content = urlparse.parse_qs(req.content) 79 | self.access_token = content['access_token'][0] 80 | self.token_type = content['token_type'][0] 81 | self.scopes = content['scope'][0] 82 | 83 | def getUserInfo(self): 84 | ''' 85 | Obtains user information. 86 | 87 | Returns: 88 | content: Dictionary 89 | - A dictionary containing user information. 90 | ''' 91 | 92 | link = 'https://api.github.com/user?access_token=' + self.access_token 93 | req = requests.get(link) 94 | 95 | if int(req.status_code) != 200: 96 | raise Exception('Invalid response %s' %req.status_code) 97 | 98 | content = json.loads(req.content) 99 | self.username = content['login'] 100 | return content 101 | 102 | def getUserData(user, clientID, clientSecret): 103 | ''' 104 | Returns data found on a Github User's public profile. 105 | This includes information such as number of followers, 106 | e-mail, number of repositories and more. 107 | 108 | Parameters: 109 | clientID: String 110 | - The clientID from registering this application 111 | on Github. 112 | clientSecret: String 113 | - The clientSecret from registering this application 114 | on Github. 115 | 116 | Returns: 117 | parsedData: Dictionary 118 | - A dictionary containing the following data: 119 | - userData['name'] 120 | - The user's public name on Github 121 | - userData['blog'] 122 | - Link to the user's blog on Github 123 | - userData['email'] 124 | - The user's public e-mail on Github 125 | - userData['public_gists'] 126 | - The number of the user's public gists 127 | - userData['public_repos'] 128 | - The number of public repositories owned 129 | - userData['avatar_url'] 130 | - Link to user's public avatar 131 | - userData['followers'] 132 | - Number of followers 133 | - userData['following'] 134 | - Number of users being followed 135 | ''' 136 | url = API_BASE_URL + user + '?' + clientID + '&' + clientSecret 137 | print url 138 | req = requests.get(url) 139 | jsonList = [] 140 | jsonList.append(json.loads(req.content)) 141 | parsedData = [] 142 | userData = {} 143 | for data in jsonList: 144 | userData['name'] = data['name'] 145 | userData['blog'] = data['blog'] 146 | userData['email'] = data['email'] 147 | userData['public_gists'] = data['public_gists'] 148 | userData['public_repos'] = data['public_repos'] 149 | userData['avatar_url'] = data['avatar_url'] 150 | userData['followers'] = data['followers'] 151 | userData['following'] = data['following'] 152 | parsedData.append(userData) 153 | 154 | return parsedData 155 | 156 | def getUserRepositories(user, clientID, clientSecret): 157 | ''' 158 | Returns a list of all the public repositories 159 | owned by a User. 160 | 161 | Parameters: 162 | clientID: String 163 | - The clientID from registering this application 164 | on Github. 165 | clientSecret: String. 166 | - The clientSecret from registering this application 167 | on Github. 168 | 169 | Returns: 170 | repositories: List 171 | - A list containing all public repository names 172 | belonging to a user. 173 | ''' 174 | pageNumber = 1 175 | jsonList = [] 176 | repositories = [] 177 | 178 | while True: 179 | req = requests.get('https://api.github.com/users/' + user + '/repos?page=' \ 180 | + str(pageNumber) + '&' + clientID + '&' + clientSecret) 181 | jsonList.append(json.loads(req.content)) 182 | if len(json.loads(req.content)) < 30: 183 | break 184 | elif len(json.loads(req.content)) >= 30: 185 | pageNumber += 1 186 | for data in jsonList: 187 | for datum in data: 188 | repositories.append(datum['name']) 189 | return repositories 190 | 191 | def getForkedRepositories(user, clientID, clientSecret): 192 | ''' 193 | Returns a list of all the public forked repositories 194 | owned by a User. 195 | 196 | Parameters: 197 | clientID: String 198 | - The clientID from registering this application 199 | on Github. 200 | clientSecret: String. 201 | - The clientSecret from registering this application 202 | on Github. 203 | 204 | Returns: 205 | forkedRepositories: List 206 | - A list containing all forked repository names 207 | belonging to a user. 208 | ''' 209 | 210 | pageNumber = 1 211 | jsonList = [] 212 | forkedRepositories = [] 213 | while True: 214 | req = requests.get('https://api.github.com/users/' + user + '/repos?page=' \ 215 | + str(pageNumber) + '&' + clientID + '&' + clientSecret) 216 | jsonList.append(json.loads(req.content)) 217 | if len(json.loads(req.content)) < 30: 218 | break 219 | elif len(json.loads(req.content)) >= 30: 220 | pageNumber += 1 221 | 222 | 223 | forkedRepos = {} 224 | for data in jsonList: 225 | for datum in data: 226 | if datum['fork'] == True: 227 | forkedRepos['name'] = datum['name'] 228 | forkedRepositories.append(forkedRepos) 229 | forkedRepos = {} 230 | 231 | return forkedRepositories 232 | 233 | def getTopContributedRepositories(user, repos, clientID, clientSecret): 234 | ''' 235 | Returns a list containing the commit totals for all 236 | repositories owned by a user. 237 | 238 | Parameters: 239 | clientID: String 240 | - The clientID from registering this application 241 | on Github. 242 | clientSecret: String 243 | - The clientSecret from registering this application 244 | on Github. 245 | 246 | Returns: 247 | parsedData: Dictionary 248 | - A dictionary containing the following data: 249 | - commits['author'] 250 | - The name of the committer 251 | - commits['total'] 252 | - Total commit count for a user in a repository 253 | - commits['repo_name'] 254 | - The name of the repository being tallied 255 | ''' 256 | jsonList = [] 257 | for repo in repos: 258 | req = requests.get('https://api.github.com/repos/' + user + '/' + repo \ 259 | + '/stats/contributors' + '?' + clientID + '&' + clientSecret) 260 | jsonList.append(json.loads(req.content)) 261 | 262 | parsedData = [] 263 | 264 | indexNumber = -1 265 | for item in jsonList: 266 | indexNumber += 1 267 | commits = {} 268 | for data in item: 269 | if data['author']['login'] == user: 270 | commits['author'] = data['author']['login'] 271 | commits['total'] = data['total'] 272 | commits['repo_name'] = repos[indexNumber] 273 | parsedData.append(commits) 274 | 275 | return parsedData 276 | 277 | def filterCommits(data): 278 | ''' 279 | Returns the top 10 committed repositories. 280 | 281 | Parameters: 282 | data: List 283 | - A list containing commit counts for all 284 | of a user's public repositories 285 | 286 | Returns: 287 | maxCommits: List 288 | - A list containing the top ten repositories 289 | with the maximum number of commits by a user 290 | ''' 291 | 292 | maxCommits = [] 293 | i = 0 294 | while i < 10: 295 | maxCommitedRepo = max(data, key=lambda x: x['total']) 296 | maxCommits.append(maxCommitedRepo) 297 | index = data.index(maxCommitedRepo) 298 | data.pop(index) 299 | i += 1 300 | return maxCommits 301 | 302 | def getStarGazerCount(user, clientID, clientSecret): 303 | ''' 304 | Returns a list number of stargazers for each 305 | of a user's public repositories. 306 | 307 | Parameters: 308 | clientID: String 309 | - The clientID from registering this application 310 | on Github. 311 | clientSecret: String 312 | - The clientSecret from registering this application 313 | on Github. 314 | 315 | Returns: 316 | stargazers: Dictionary 317 | - A dictionary containing the following data: 318 | - starData['stargazers_count'] 319 | - The number of stargazers for a given repository 320 | - starData['name'] 321 | - The name of the repository being observed 322 | ''' 323 | pageNumber = 1 324 | jsonList = [] 325 | stargazers = [] 326 | while True: 327 | req = requests.get('https://api.github.com/users/' + user + '/repos?page=' \ 328 | + str(pageNumber) + '&' + clientID + '&' + clientSecret) 329 | jsonList.append(json.loads(req.content)) 330 | if len(json.loads(req.content)) < 30: 331 | break 332 | elif len(json.loads(req.content)) >= 30: 333 | pageNumber += 1 334 | 335 | 336 | for data in jsonList: 337 | for datum in data: 338 | starData = {} 339 | starData['stargazers_count'] = datum['stargazers_count'] 340 | starData['name'] = datum['name'] 341 | stargazers.append(starData) 342 | 343 | return stargazers 344 | 345 | def filterStarGazerCount(data): 346 | ''' 347 | Returns the top 10 stargazed repositories. 348 | 349 | Parameters: 350 | data: List 351 | - A list containing stargazer counts for all 352 | of a user's public repositories 353 | 354 | Returns: 355 | maxStars: List 356 | - A list containing the top ten repositories 357 | with the maximum number of stargazers 358 | ''' 359 | maxStars = [] 360 | i = 0 361 | while i < 10: 362 | maxStarGazers = max(data, key=lambda x: x['stargazers_count']) 363 | maxStars.append(maxStarGazers) 364 | index = data.index(maxStarGazers) 365 | data.pop(index) 366 | i += 1 367 | return maxStars 368 | 369 | 370 | 371 | 372 | -------------------------------------------------------------------------------- /.pylintrc: -------------------------------------------------------------------------------- 1 | [MASTER] 2 | 3 | # Specify a configuration file. 4 | #rcfile= 5 | 6 | # Python code to execute, usually for sys.path manipulation such as 7 | # pygtk.require(). 8 | #init-hook= 9 | 10 | # Profiled execution. 11 | profile=no 12 | 13 | # Add files or directories to the blacklist. They should be base names, not 14 | # paths. 15 | ignore=CVS 16 | 17 | # Pickle collected data for later comparisons. 18 | persistent=yes 19 | 20 | # List of plugins (as comma separated values of python modules names) to load, 21 | # usually to register additional checkers. 22 | load-plugins= 23 | 24 | # Deprecated. It was used to include message's id in output. Use --msg-template 25 | # instead. 26 | include-ids=no 27 | 28 | # Deprecated. It was used to include symbolic ids of messages in output. Use 29 | # --msg-template instead. 30 | symbols=no 31 | 32 | # Use multiple processes to speed up Pylint. 33 | jobs=1 34 | 35 | # Allow loading of arbitrary C extensions. Extensions are imported into the 36 | # active Python interpreter and may run arbitrary code. 37 | unsafe-load-any-extension=no 38 | 39 | # A comma-separated list of package or module names from where C extensions may 40 | # be loaded. Extensions are loading into the active Python interpreter and may 41 | # run arbitrary code 42 | extension-pkg-whitelist= 43 | 44 | # Allow optimization of some AST trees. This will activate a peephole AST 45 | # optimizer, which will apply various small optimizations. For instance, it can 46 | # be used to obtain the result of joining multiple strings with the addition 47 | # operator. Joining a lot of strings can lead to a maximum recursion error in 48 | # Pylint and this flag can prevent that. It has one side effect, the resulting 49 | # AST will be different than the one from reality. 50 | optimize-ast=no 51 | 52 | 53 | [MESSAGES CONTROL] 54 | 55 | # Only show warnings with the listed confidence levels. Leave empty to show 56 | # all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED 57 | confidence= 58 | 59 | # Enable the message, report, category or checker with the given id(s). You can 60 | # either give multiple identifier separated by comma (,) or put this option 61 | # multiple time. See also the "--disable" option for examples. 62 | #enable= 63 | 64 | # Disable the message, report, category or checker with the given id(s). You 65 | # can either give multiple identifiers separated by comma (,) or put this 66 | # option multiple times (only on the command line, not in the configuration 67 | # file where it should appear only once).You can also use "--disable=all" to 68 | # disable everything first and then reenable specific checks. For example, if 69 | # you want to run only the similarities checker, you can use "--disable=all 70 | # --enable=similarities". If you want to run only the classes checker, but have 71 | # no Warning level messages displayed, use"--disable=all --enable=classes 72 | # --disable=W" 73 | disable=E1608,W1627,E1601,E1603,E1602,E1605,E1604,E1607,E1606,W1621,W1620,W1623,W1622,W1625,W1624,W1609,W1608,W1607,W1606,W1605,W1604,W1603,W1602,W1601,W1639,W1640,I0021,W1638,I0020,W1618,W1619,W1630,W1626,W1637,W1634,W1635,W1610,W1611,W1612,W1613,W1614,W1615,W1616,W1617,W1632,W1633,W0704,W1628,W1629,W1636 74 | 75 | 76 | [REPORTS] 77 | 78 | # Set the output format. Available formats are text, parseable, colorized, msvs 79 | # (visual studio) and html. You can also give a reporter class, eg 80 | # mypackage.mymodule.MyReporterClass. 81 | output-format=text 82 | 83 | # Put messages in a separate file for each module / package specified on the 84 | # command line instead of printing them on stdout. Reports (if any) will be 85 | # written in a file name "pylint_global.[txt|html]". 86 | files-output=no 87 | 88 | # Tells whether to display a full report or only the messages 89 | reports=yes 90 | 91 | # Python expression which should return a note less than 10 (10 is the highest 92 | # note). You have access to the variables errors warning, statement which 93 | # respectively contain the number of errors / warnings messages and the total 94 | # number of statements analyzed. This is used by the global evaluation report 95 | # (RP0004). 96 | evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) 97 | 98 | # Add a comment according to your evaluation note. This is used by the global 99 | # evaluation report (RP0004). 100 | comment=no 101 | 102 | # Template used to display messages. This is a python new-style format string 103 | # used to format the message information. See doc for all details 104 | #msg-template= 105 | 106 | 107 | [BASIC] 108 | 109 | # Required attributes for module, separated by a comma 110 | required-attributes= 111 | 112 | # List of builtins function names that should not be used, separated by a comma 113 | bad-functions=map,filter,input 114 | 115 | # Good variable names which should always be accepted, separated by a comma 116 | good-names=i,j,k,ex,Run,_ 117 | 118 | # Bad variable names which should always be refused, separated by a comma 119 | bad-names=foo,bar,baz,toto,tutu,tata 120 | 121 | # Colon-delimited sets of names that determine each other's naming style when 122 | # the name regexes allow several styles. 123 | name-group= 124 | 125 | # Include a hint for the correct naming format with invalid-name 126 | include-naming-hint=no 127 | 128 | # Regular expression matching correct function names 129 | function-rgx=[a-z][A-Za-z0-9]{1,30}$ 130 | 131 | # Naming hint for function names 132 | function-name-hint=[a-z_][a-z0-9_]{2,30}$ 133 | 134 | # Regular expression matching correct variable names 135 | variable-rgx=[a-z][A-Za-z0-9]{1,30}$ 136 | 137 | # Naming hint for variable names 138 | variable-name-hint=[a-z_][a-z0-9_]{2,30}$ 139 | 140 | # Regular expression matching correct constant names 141 | const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$ 142 | 143 | # Naming hint for constant names 144 | const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$ 145 | 146 | # Regular expression matching correct attribute names 147 | attr-rgx=[a-z_][a-z0-9_]{2,30}$ 148 | 149 | # Naming hint for attribute names 150 | attr-name-hint=[a-z_][a-z0-9_]{2,30}$ 151 | 152 | # Regular expression matching correct argument names 153 | argument-rgx=[a-z][A-Za-z0-9]{1,30}$ 154 | 155 | # Naming hint for argument names 156 | argument-name-hint=[a-z_][a-z0-9_]{2,30}$ 157 | 158 | # Regular expression matching correct class attribute names 159 | class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ 160 | 161 | # Naming hint for class attribute names 162 | class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ 163 | 164 | # Regular expression matching correct inline iteration names 165 | inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ 166 | 167 | # Naming hint for inline iteration names 168 | inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$ 169 | 170 | # Regular expression matching correct class names 171 | class-rgx=[A-Z_][a-zA-Z0-9]+$ 172 | 173 | # Naming hint for class names 174 | class-name-hint=[A-Z_][a-zA-Z0-9]+$ 175 | 176 | # Regular expression matching correct module names 177 | module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ 178 | 179 | # Naming hint for module names 180 | module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ 181 | 182 | # Regular expression matching correct method names 183 | method-rgx=[a-z_][a-z0-9_]{2,30}$ 184 | 185 | # Naming hint for method names 186 | method-name-hint=[a-z_][a-z0-9_]{2,30}$ 187 | 188 | # Regular expression which should only match function or class names that do 189 | # not require a docstring. 190 | no-docstring-rgx=__.*__ 191 | 192 | # Minimum line length for functions/classes that require docstrings, shorter 193 | # ones are exempt. 194 | docstring-min-length=-1 195 | 196 | 197 | [FORMAT] 198 | 199 | # Maximum number of characters on a single line. 200 | max-line-length=100 201 | 202 | # Regexp for a line that is allowed to be longer than the limit. 203 | ignore-long-lines=^\s*(# )??$ 204 | 205 | # Allow the body of an if to be on the same line as the test if there is no 206 | # else. 207 | single-line-if-stmt=no 208 | 209 | # List of optional constructs for which whitespace checking is disabled 210 | no-space-check=trailing-comma,dict-separator 211 | 212 | # Maximum number of lines in a module 213 | max-module-lines=1000 214 | 215 | # String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 216 | # tab). 217 | indent-string=' ' 218 | 219 | # Number of spaces of indent required inside a hanging or continued line. 220 | indent-after-paren=4 221 | 222 | # Expected format of line ending, e.g. empty (any line ending), LF or CRLF. 223 | expected-line-ending-format= 224 | 225 | 226 | [LOGGING] 227 | 228 | # Logging modules to check that the string format arguments are in logging 229 | # function parameter format 230 | logging-modules=logging 231 | 232 | 233 | [MISCELLANEOUS] 234 | 235 | # List of note tags to take in consideration, separated by a comma. 236 | notes=FIXME,XXX,TODO 237 | 238 | 239 | [SIMILARITIES] 240 | 241 | # Minimum lines number of a similarity. 242 | min-similarity-lines=4 243 | 244 | # Ignore comments when computing similarities. 245 | ignore-comments=yes 246 | 247 | # Ignore docstrings when computing similarities. 248 | ignore-docstrings=yes 249 | 250 | # Ignore imports when computing similarities. 251 | ignore-imports=no 252 | 253 | 254 | [SPELLING] 255 | 256 | # Spelling dictionary name. Available dictionaries: none. To make it working 257 | # install python-enchant package. 258 | spelling-dict= 259 | 260 | # List of comma separated words that should not be checked. 261 | spelling-ignore-words= 262 | 263 | # A path to a file that contains private dictionary; one word per line. 264 | spelling-private-dict-file= 265 | 266 | # Tells whether to store unknown words to indicated private dictionary in 267 | # --spelling-private-dict-file option instead of raising a message. 268 | spelling-store-unknown-words=no 269 | 270 | 271 | [TYPECHECK] 272 | 273 | # Tells whether missing members accessed in mixin class should be ignored. A 274 | # mixin class is detected if its name ends with "mixin" (case insensitive). 275 | ignore-mixin-members=yes 276 | 277 | # List of module names for which member attributes should not be checked 278 | # (useful for modules/projects where namespaces are manipulated during runtime 279 | # and thus existing member attributes cannot be deduced by static analysis 280 | ignored-modules= 281 | 282 | # List of classes names for which member attributes should not be checked 283 | # (useful for classes with attributes dynamically set). 284 | ignored-classes=SQLObject 285 | 286 | # When zope mode is activated, add a predefined set of Zope acquired attributes 287 | # to generated-members. 288 | zope=no 289 | 290 | # List of members which are set dynamically and missed by pylint inference 291 | # system, and so shouldn't trigger E0201 when accessed. Python regular 292 | # expressions are accepted. 293 | generated-members=REQUEST,acl_users,aq_parent 294 | 295 | 296 | [VARIABLES] 297 | 298 | # Tells whether we should check for unused import in __init__ files. 299 | init-import=no 300 | 301 | # A regular expression matching the name of dummy variables (i.e. expectedly 302 | # not used). 303 | dummy-variables-rgx=_$|dummy 304 | 305 | # List of additional names supposed to be defined in builtins. Remember that 306 | # you should avoid to define new builtins when possible. 307 | additional-builtins= 308 | 309 | # List of strings which can identify a callback function by name. A callback 310 | # name must start or end with one of those strings. 311 | callbacks=cb_,_cb 312 | 313 | 314 | [CLASSES] 315 | 316 | # List of interface methods to ignore, separated by a comma. This is used for 317 | # instance to not check methods defines in Zope's Interface base class. 318 | ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by 319 | 320 | # List of method names used to declare (i.e. assign) instance attributes. 321 | defining-attr-methods=__init__,__new__,setUp 322 | 323 | # List of valid names for the first argument in a class method. 324 | valid-classmethod-first-arg=cls 325 | 326 | # List of valid names for the first argument in a metaclass class method. 327 | valid-metaclass-classmethod-first-arg=mcs 328 | 329 | # List of member names, which should be excluded from the protected access 330 | # warning. 331 | exclude-protected=_asdict,_fields,_replace,_source,_make 332 | 333 | 334 | [DESIGN] 335 | 336 | # Maximum number of arguments for function / method 337 | max-args=5 338 | 339 | # Argument names that match this expression will be ignored. Default to name 340 | # with leading underscore 341 | ignored-argument-names=_.* 342 | 343 | # Maximum number of locals for function / method body 344 | max-locals=15 345 | 346 | # Maximum number of return / yield for function / method body 347 | max-returns=6 348 | 349 | # Maximum number of branch for function / method body 350 | max-branches=12 351 | 352 | # Maximum number of statements in function / method body 353 | max-statements=50 354 | 355 | # Maximum number of parents for a class (see R0901). 356 | max-parents=7 357 | 358 | # Maximum number of attributes for a class (see R0902). 359 | max-attributes=7 360 | 361 | # Minimum number of public methods for a class (see R0903). 362 | min-public-methods=2 363 | 364 | # Maximum number of public methods for a class (see R0904). 365 | max-public-methods=20 366 | 367 | 368 | [IMPORTS] 369 | 370 | # Deprecated modules which should not be used, separated by a comma 371 | deprecated-modules=regsub,TERMIOS,Bastion,rexec 372 | 373 | # Create a graph of every (i.e. internal and external) dependencies in the 374 | # given file (report RP0402 must not be disabled) 375 | import-graph= 376 | 377 | # Create a graph of external dependencies in the given file (report RP0402 must 378 | # not be disabled) 379 | ext-import-graph= 380 | 381 | # Create a graph of internal dependencies in the given file (report RP0402 must 382 | # not be disabled) 383 | int-import-graph= 384 | 385 | 386 | [EXCEPTIONS] 387 | 388 | # Exceptions that will emit a warning when being caught. Defaults to 389 | # "Exception" 390 | overgeneral-exceptions=Exception 391 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/scripts/.pylintrc: -------------------------------------------------------------------------------- 1 | [MASTER] 2 | 3 | # Specify a configuration file. 4 | #rcfile= 5 | 6 | # Python code to execute, usually for sys.path manipulation such as 7 | # pygtk.require(). 8 | #init-hook= 9 | 10 | # Profiled execution. 11 | profile=no 12 | 13 | # Add files or directories to the blacklist. They should be base names, not 14 | # paths. 15 | ignore=CVS 16 | 17 | # Pickle collected data for later comparisons. 18 | persistent=yes 19 | 20 | # List of plugins (as comma separated values of python modules names) to load, 21 | # usually to register additional checkers. 22 | load-plugins= 23 | 24 | # Deprecated. It was used to include message's id in output. Use --msg-template 25 | # instead. 26 | include-ids=no 27 | 28 | # Deprecated. It was used to include symbolic ids of messages in output. Use 29 | # --msg-template instead. 30 | symbols=no 31 | 32 | # Use multiple processes to speed up Pylint. 33 | jobs=1 34 | 35 | # Allow loading of arbitrary C extensions. Extensions are imported into the 36 | # active Python interpreter and may run arbitrary code. 37 | unsafe-load-any-extension=no 38 | 39 | # A comma-separated list of package or module names from where C extensions may 40 | # be loaded. Extensions are loading into the active Python interpreter and may 41 | # run arbitrary code 42 | extension-pkg-whitelist= 43 | 44 | # Allow optimization of some AST trees. This will activate a peephole AST 45 | # optimizer, which will apply various small optimizations. For instance, it can 46 | # be used to obtain the result of joining multiple strings with the addition 47 | # operator. Joining a lot of strings can lead to a maximum recursion error in 48 | # Pylint and this flag can prevent that. It has one side effect, the resulting 49 | # AST will be different than the one from reality. 50 | optimize-ast=no 51 | 52 | 53 | [MESSAGES CONTROL] 54 | 55 | # Only show warnings with the listed confidence levels. Leave empty to show 56 | # all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED 57 | confidence= 58 | 59 | # Enable the message, report, category or checker with the given id(s). You can 60 | # either give multiple identifier separated by comma (,) or put this option 61 | # multiple time. See also the "--disable" option for examples. 62 | #enable= 63 | 64 | # Disable the message, report, category or checker with the given id(s). You 65 | # can either give multiple identifiers separated by comma (,) or put this 66 | # option multiple times (only on the command line, not in the configuration 67 | # file where it should appear only once).You can also use "--disable=all" to 68 | # disable everything first and then reenable specific checks. For example, if 69 | # you want to run only the similarities checker, you can use "--disable=all 70 | # --enable=similarities". If you want to run only the classes checker, but have 71 | # no Warning level messages displayed, use"--disable=all --enable=classes 72 | # --disable=W" 73 | disable=E1608,W1627,E1601,E1603,E1602,E1605,E1604,E1607,E1606,W1621,W1620,W1623,W1622,W1625,W1624,W1609,W1608,W1607,W1606,W1605,W1604,W1603,W1602,W1601,W1639,W1640,I0021,W1638,I0020,W1618,W1619,W1630,W1626,W1637,W1634,W1635,W1610,W1611,W1612,W1613,W1614,W1615,W1616,W1617,W1632,W1633,W0704,W1628,W1629,W1636 74 | 75 | 76 | [REPORTS] 77 | 78 | # Set the output format. Available formats are text, parseable, colorized, msvs 79 | # (visual studio) and html. You can also give a reporter class, eg 80 | # mypackage.mymodule.MyReporterClass. 81 | output-format=text 82 | 83 | # Put messages in a separate file for each module / package specified on the 84 | # command line instead of printing them on stdout. Reports (if any) will be 85 | # written in a file name "pylint_global.[txt|html]". 86 | files-output=no 87 | 88 | # Tells whether to display a full report or only the messages 89 | reports=yes 90 | 91 | # Python expression which should return a note less than 10 (10 is the highest 92 | # note). You have access to the variables errors warning, statement which 93 | # respectively contain the number of errors / warnings messages and the total 94 | # number of statements analyzed. This is used by the global evaluation report 95 | # (RP0004). 96 | evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) 97 | 98 | # Add a comment according to your evaluation note. This is used by the global 99 | # evaluation report (RP0004). 100 | comment=no 101 | 102 | # Template used to display messages. This is a python new-style format string 103 | # used to format the message information. See doc for all details 104 | #msg-template= 105 | 106 | 107 | [BASIC] 108 | 109 | # Required attributes for module, separated by a comma 110 | required-attributes= 111 | 112 | # List of builtins function names that should not be used, separated by a comma 113 | bad-functions=map,filter,input 114 | 115 | # Good variable names which should always be accepted, separated by a comma 116 | good-names=i,j,k,ex,Run,_ 117 | 118 | # Bad variable names which should always be refused, separated by a comma 119 | bad-names=foo,bar,baz,toto,tutu,tata 120 | 121 | # Colon-delimited sets of names that determine each other's naming style when 122 | # the name regexes allow several styles. 123 | name-group= 124 | 125 | # Include a hint for the correct naming format with invalid-name 126 | include-naming-hint=no 127 | 128 | # Regular expression matching correct function names 129 | function-rgx=[a-z][A-Za-z0-9]{1,30}$ 130 | 131 | # Naming hint for function names 132 | function-name-hint=[a-z_][a-z0-9_]{2,30}$ 133 | 134 | # Regular expression matching correct variable names 135 | variable-rgx=[a-z][A-Za-z0-9]{1,30}$ 136 | 137 | # Naming hint for variable names 138 | variable-name-hint=[a-z_][a-z0-9_]{2,30}$ 139 | 140 | # Regular expression matching correct constant names 141 | const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$ 142 | 143 | # Naming hint for constant names 144 | const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$ 145 | 146 | # Regular expression matching correct attribute names 147 | attr-rgx=[a-z_][a-z0-9_]{2,30}$ 148 | 149 | # Naming hint for attribute names 150 | attr-name-hint=[a-z_][a-z0-9_]{2,30}$ 151 | 152 | # Regular expression matching correct argument names 153 | argument-rgx=[a-z][A-Za-z0-9]{1,30}$ 154 | 155 | # Naming hint for argument names 156 | argument-name-hint=[a-z_][a-z0-9_]{2,30}$ 157 | 158 | # Regular expression matching correct class attribute names 159 | class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ 160 | 161 | # Naming hint for class attribute names 162 | class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ 163 | 164 | # Regular expression matching correct inline iteration names 165 | inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ 166 | 167 | # Naming hint for inline iteration names 168 | inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$ 169 | 170 | # Regular expression matching correct class names 171 | class-rgx=[A-Z_][a-zA-Z0-9]+$ 172 | 173 | # Naming hint for class names 174 | class-name-hint=[A-Z_][a-zA-Z0-9]+$ 175 | 176 | # Regular expression matching correct module names 177 | module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ 178 | 179 | # Naming hint for module names 180 | module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ 181 | 182 | # Regular expression matching correct method names 183 | method-rgx=[a-z_][a-z0-9_]{2,30}$ 184 | 185 | # Naming hint for method names 186 | method-name-hint=[a-z_][a-z0-9_]{2,30}$ 187 | 188 | # Regular expression which should only match function or class names that do 189 | # not require a docstring. 190 | no-docstring-rgx=__.*__ 191 | 192 | # Minimum line length for functions/classes that require docstrings, shorter 193 | # ones are exempt. 194 | docstring-min-length=-1 195 | 196 | 197 | [FORMAT] 198 | 199 | # Maximum number of characters on a single line. 200 | max-line-length=100 201 | 202 | # Regexp for a line that is allowed to be longer than the limit. 203 | ignore-long-lines=^\s*(# )??$ 204 | 205 | # Allow the body of an if to be on the same line as the test if there is no 206 | # else. 207 | single-line-if-stmt=no 208 | 209 | # List of optional constructs for which whitespace checking is disabled 210 | no-space-check=trailing-comma,dict-separator 211 | 212 | # Maximum number of lines in a module 213 | max-module-lines=1000 214 | 215 | # String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 216 | # tab). 217 | indent-string=' ' 218 | 219 | # Number of spaces of indent required inside a hanging or continued line. 220 | indent-after-paren=4 221 | 222 | # Expected format of line ending, e.g. empty (any line ending), LF or CRLF. 223 | expected-line-ending-format= 224 | 225 | 226 | [LOGGING] 227 | 228 | # Logging modules to check that the string format arguments are in logging 229 | # function parameter format 230 | logging-modules=logging 231 | 232 | 233 | [MISCELLANEOUS] 234 | 235 | # List of note tags to take in consideration, separated by a comma. 236 | notes=FIXME,XXX,TODO 237 | 238 | 239 | [SIMILARITIES] 240 | 241 | # Minimum lines number of a similarity. 242 | min-similarity-lines=4 243 | 244 | # Ignore comments when computing similarities. 245 | ignore-comments=yes 246 | 247 | # Ignore docstrings when computing similarities. 248 | ignore-docstrings=yes 249 | 250 | # Ignore imports when computing similarities. 251 | ignore-imports=no 252 | 253 | 254 | [SPELLING] 255 | 256 | # Spelling dictionary name. Available dictionaries: none. To make it working 257 | # install python-enchant package. 258 | spelling-dict= 259 | 260 | # List of comma separated words that should not be checked. 261 | spelling-ignore-words= 262 | 263 | # A path to a file that contains private dictionary; one word per line. 264 | spelling-private-dict-file= 265 | 266 | # Tells whether to store unknown words to indicated private dictionary in 267 | # --spelling-private-dict-file option instead of raising a message. 268 | spelling-store-unknown-words=no 269 | 270 | 271 | [TYPECHECK] 272 | 273 | # Tells whether missing members accessed in mixin class should be ignored. A 274 | # mixin class is detected if its name ends with "mixin" (case insensitive). 275 | ignore-mixin-members=yes 276 | 277 | # List of module names for which member attributes should not be checked 278 | # (useful for modules/projects where namespaces are manipulated during runtime 279 | # and thus existing member attributes cannot be deduced by static analysis 280 | ignored-modules= 281 | 282 | # List of classes names for which member attributes should not be checked 283 | # (useful for classes with attributes dynamically set). 284 | ignored-classes=SQLObject 285 | 286 | # When zope mode is activated, add a predefined set of Zope acquired attributes 287 | # to generated-members. 288 | zope=no 289 | 290 | # List of members which are set dynamically and missed by pylint inference 291 | # system, and so shouldn't trigger E0201 when accessed. Python regular 292 | # expressions are accepted. 293 | generated-members=REQUEST,acl_users,aq_parent 294 | 295 | 296 | [VARIABLES] 297 | 298 | # Tells whether we should check for unused import in __init__ files. 299 | init-import=no 300 | 301 | # A regular expression matching the name of dummy variables (i.e. expectedly 302 | # not used). 303 | dummy-variables-rgx=_$|dummy 304 | 305 | # List of additional names supposed to be defined in builtins. Remember that 306 | # you should avoid to define new builtins when possible. 307 | additional-builtins= 308 | 309 | # List of strings which can identify a callback function by name. A callback 310 | # name must start or end with one of those strings. 311 | callbacks=cb_,_cb 312 | 313 | 314 | [CLASSES] 315 | 316 | # List of interface methods to ignore, separated by a comma. This is used for 317 | # instance to not check methods defines in Zope's Interface base class. 318 | ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by 319 | 320 | # List of method names used to declare (i.e. assign) instance attributes. 321 | defining-attr-methods=__init__,__new__,setUp 322 | 323 | # List of valid names for the first argument in a class method. 324 | valid-classmethod-first-arg=cls 325 | 326 | # List of valid names for the first argument in a metaclass class method. 327 | valid-metaclass-classmethod-first-arg=mcs 328 | 329 | # List of member names, which should be excluded from the protected access 330 | # warning. 331 | exclude-protected=_asdict,_fields,_replace,_source,_make 332 | 333 | 334 | [DESIGN] 335 | 336 | # Maximum number of arguments for function / method 337 | max-args=5 338 | 339 | # Argument names that match this expression will be ignored. Default to name 340 | # with leading underscore 341 | ignored-argument-names=_.* 342 | 343 | # Maximum number of locals for function / method body 344 | max-locals=15 345 | 346 | # Maximum number of return / yield for function / method body 347 | max-returns=6 348 | 349 | # Maximum number of branch for function / method body 350 | max-branches=12 351 | 352 | # Maximum number of statements in function / method body 353 | max-statements=50 354 | 355 | # Maximum number of parents for a class (see R0901). 356 | max-parents=7 357 | 358 | # Maximum number of attributes for a class (see R0902). 359 | max-attributes=7 360 | 361 | # Minimum number of public methods for a class (see R0903). 362 | min-public-methods=2 363 | 364 | # Maximum number of public methods for a class (see R0904). 365 | max-public-methods=20 366 | 367 | 368 | [IMPORTS] 369 | 370 | # Deprecated modules which should not be used, separated by a comma 371 | deprecated-modules=regsub,TERMIOS,Bastion,rexec 372 | 373 | # Create a graph of every (i.e. internal and external) dependencies in the 374 | # given file (report RP0402 must not be disabled) 375 | import-graph= 376 | 377 | # Create a graph of external dependencies in the given file (report RP0402 must 378 | # not be disabled) 379 | ext-import-graph= 380 | 381 | # Create a graph of internal dependencies in the given file (report RP0402 must 382 | # not be disabled) 383 | int-import-graph= 384 | 385 | 386 | [EXCEPTIONS] 387 | 388 | # Exceptions that will emit a warning when being caught. Defaults to 389 | # "Exception" 390 | overgeneral-exceptions=Exception 391 | -------------------------------------------------------------------------------- /hackathon_starter/hackathon/unittests/testgithub.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from mock import Mock, patch, MagicMock 3 | from django.conf import settings 4 | from hackathon.scripts.github import getUserData, getUserRepositories, getForkedRepositories, getTopContributedRepositories, getStarGazerCount, filterStarGazerCount, filterCommits 5 | 6 | 7 | class GithubTests(unittest.TestCase): 8 | 9 | def setUp(self): 10 | self.API_BASE_URL = 'https://api.github.com/users/DrkSephy' 11 | self.clientID = 'client_id=2404a1e21aebd902f6db' 12 | self.clientSecret = 'client_secret=3da44769d4b7c9465fa4c812669148a163607c23' 13 | 14 | 15 | def testGetUserData(self): 16 | '''Test for github.py getUserData method''' 17 | 18 | # Client and Secret ID 19 | clientID = self.clientID 20 | clientSecret = self.clientSecret 21 | user = 'DrkSephy' 22 | 23 | # Construct the URL 24 | self.url = self.API_BASE_URL + '?' + clientID + '&' + clientSecret 25 | 26 | # Instantiate data collection objects 27 | jsonList = [] 28 | parsedData = [] 29 | userData = {} 30 | 31 | with patch('hackathon.scripts.github.getUserData') as mock_getUserData: 32 | # Mock the return value of this method 33 | #mock_getUserData.return_value = {'public_repos': 50, 'public_gists': 5, 'name': 'David Leonard', 'blog': 'http://drksephy.github.io', 'avatar_url': 'https://avatars.githubusercontent.com/u/1226900?v=3', 'followers': 52, 'following': 7, 'email': 'DrkSephy1025@gmail.com'} 34 | mock_getUserData.return_value = getUserData(user, clientID, clientSecret) 35 | #print 'Yeah?' 36 | #print mock_getUserData.return_value 37 | #print mock_getUserData.return_value[0]['public_repos'] 38 | 39 | for data in mock_getUserData.return_value: 40 | userData['name'] = data['name'] 41 | userData['blog'] = data['blog'] 42 | userData['email'] = data['email'] 43 | userData['public_gists'] = data['public_gists'] 44 | userData['public_repos'] = data['public_repos'] 45 | userData['avatar_url'] = data['avatar_url'] 46 | userData['followers'] = data['followers'] 47 | userData['following'] = data['following'] 48 | 49 | parsedData.append(userData) 50 | self.assertEqual(getUserData(user, clientID, clientSecret), parsedData) 51 | 52 | def testGetUserRepositories(self): 53 | '''Test for github.py getUserRepositories''' 54 | 55 | # Client and Secret ID 56 | clientID = self.clientID 57 | clientSecret = self.clientSecret 58 | user = 'DrkSephy' 59 | 60 | pageNumber = 1 61 | jsonList = [] 62 | repositories = [] 63 | while True: 64 | with patch('hackathon.scripts.github.getUserRepositories') as mock_getUserRepositories: 65 | mock_getUserRepositories.return_value = { "id": 22388667, "name": "ACM-Game-Presentation" } 66 | jsonList.append(mock_getUserRepositories.return_value) 67 | if len(mock_getUserRepositories.return_value) < 30: 68 | break 69 | elif len(mock_getUserRepositories.return_value) >= 30: 70 | pageNumber += 1 71 | 72 | 73 | repositories = getUserRepositories(user, clientID, clientSecret) 74 | 75 | self.assertEqual(getUserRepositories(user, clientID, clientSecret), repositories) 76 | 77 | 78 | def testGetForkedRepositories(self): 79 | '''Test for github.py getForkedRepositories''' 80 | 81 | # Client and Secret ID 82 | clientID = self.clientID 83 | clientSecret = self.clientSecret 84 | user = 'DrkSephy' 85 | 86 | pageNumber = 1 87 | jsonList = [] 88 | forkedRepositories = [] 89 | 90 | while True: 91 | with patch('hackathon.scripts.github.getUserRepositories') as mock_getForkedRepositories: 92 | mock_getForkedRepositories.return_value = { "id": 22388667, "name": "ACM-Game-Presentation" } 93 | jsonList.append(mock_getForkedRepositories.return_value) 94 | if len(mock_getForkedRepositories.return_value) < 30: 95 | break 96 | elif len(mock_getForkedRepositories.return_value) >= 30: 97 | pageNumber += 1 98 | 99 | forkedRepositories = [{'name': 'async'}, {'name': 'FizzBuzz-Test-1'}, {'name': 'hackathon-starter'}, {'name': 'historicalWeather'}, {'name': 'jsrecipes'}, {'name': 'node'}, {'name': 'rst2pdf'}, {'name': 'rust-by-example'}, {'name': 'satellizer'}, {'name': 'vitanao'}, {'name': 'WaterEmblem'}, {'name': 'webauth-via-ssh'}] 100 | self.assertEqual(getForkedRepositories(user, clientID, clientSecret), forkedRepositories) 101 | 102 | def testGetTopContributedRepositories(self): 103 | '''Test for github.py getTopContributedRepositories''' 104 | 105 | # Client and Secret ID 106 | clientID = self.clientID 107 | clientSecret = self.clientSecret 108 | repos = ['async'] 109 | user = 'DrkSephy' 110 | 111 | jsonList = [] 112 | for repo in repos: 113 | with patch('hackathon.scripts.github.getTopContributedRepositories') as mock_getTopContributedRepositories: 114 | mock_getTopContributedRepositories.return_value = [{'total': 85, 'repo_name': 'ACM-Game-Presentation', 'author': 'DrkSephy'}, 115 | {'total': 16, 'repo_name': 'ACM-Portfolio-Presentation', 'author': 'DrkSephy'}, 116 | {'total': 17, 'repo_name': 'angular-nhl', 'author': 'DrkSephy'}, 117 | {'total': 1, 'repo_name': 'async', 'author': 'DrkSephy'}, 118 | {'total': 55, 'repo_name': 'd3-sandbox', 'author': 'DrkSephy'}, 119 | {'total': 7, 'repo_name': 'Deep-Learning', 'author': 'DrkSephy'}, 120 | {'total': 11, 'repo_name': 'Django-Hackathon-Starter', 'author': 'DrkSephy'}, 121 | {'total': 433, 'repo_name': 'drksephy.github.io', 'author': 'DrkSephy'}, 122 | {'total': 3, 'repo_name': 'el-gamal-attack', 'author': 'DrkSephy'}, 123 | {'total': 1, 'repo_name': 'FizzBuzz-Test-1', 'author': 'DrkSephy'}, 124 | {'total': 44, 'repo_name': 'flux-reactJS', 'author': 'DrkSephy'}, 125 | {'total': 4, 'repo_name': 'fractals', 'author': 'DrkSephy'}] 126 | jsonList.append(mock_getTopContributedRepositories.return_value) 127 | 128 | 129 | parsedData = [] 130 | indexNumber = -1 131 | for entry in jsonList: 132 | indexNumber += 1 133 | commits = {} 134 | for item in entry: 135 | if item['author'] == 'DrkSephy': 136 | commits['author'] = item['author'] 137 | commits['total'] = item['total'] 138 | commits['repo_name'] = item['repo_name'] 139 | parsedData.append(commits) 140 | 141 | parsedData = [{'total': 1, 'repo_name': 'async', 'author': 'DrkSephy'}] 142 | 143 | 144 | self.assertEqual(getTopContributedRepositories(user, repos, clientID, clientSecret), parsedData) 145 | 146 | 147 | def testGetStarGazerCount(self): 148 | '''Test for github.py getStarGazerCount''' 149 | 150 | # Client and Secret ID 151 | clientID = self.clientID 152 | clientSecret = self.clientSecret 153 | user = 'DrkSephy' 154 | 155 | pageNumber = 1 156 | jsonList = [] 157 | stargazers = [] 158 | 159 | while True: 160 | with patch('hackathon.scripts.github.getStarGazerCount') as mock_getStarGazerCount: 161 | mock_getStarGazerCount.return_value = { "id": 22388667, "name": "ACM-Game-Presentation" } 162 | jsonList.append(mock_getStarGazerCount.return_value) 163 | if len(mock_getStarGazerCount.return_value) < 30: 164 | break 165 | elif len(mock_getStarGazerCount.return_value) >= 30: 166 | pageNumber += 1 167 | 168 | stargazers = getStarGazerCount(user, clientID, clientSecret) 169 | self.assertEqual(getStarGazerCount(user, clientID, clientSecret), stargazers) 170 | 171 | 172 | 173 | def testFilterStarGazerCount(self): 174 | '''Test for github.py filterStarGazerCount''' 175 | maxStars = [] 176 | data = [{'stargazers_count': 0, 'name': 'ACM-Game-Presentation'}, {'stargazers_count': 1, 'name': 'ACM-Portfolio-Presentation'}, {'stargazers_count': 2, 'name': 'angular-nhl'}, {'stargazers_count': 0, 'name': 'async'}, {'stargazers_count': 0, 'name': 'd3-sandbox'}, {'stargazers_count': 3, 'name': 'Deep-Learning'}, {'stargazers_count': 0, 'name': 'Django-Hackathon-Starter'}, {'stargazers_count': 0, 'name': 'drksephy.github.io'}, {'stargazers_count': 0, 'name': 'el-gamal-attack'}, {'stargazers_count': 0, 'name': 'FizzBuzz-Test-1'}, {'stargazers_count': 0, 'name': 'flux-reactJS'}, {'stargazers_count': 0, 'name': 'fractals'}, {'stargazers_count': 0, 'name': 'git-api'}, {'stargazers_count': 1, 'name': 'git-technetium'}, {'stargazers_count': 0, 'name': 'hackathon-starter'}, {'stargazers_count': 0, 'name': 'hackcity'}, {'stargazers_count': 0, 'name': 'hackcity.github.io'}, {'stargazers_count': 0, 'name': 'historicalWeather'}, {'stargazers_count': 0, 'name': 'I4330'}, {'stargazers_count': 1, 'name': 'integrated-chinese'}, {'stargazers_count': 0, 'name': 'jsrecipes'}, {'stargazers_count': 0, 'name': 'learn-angularJS'}, {'stargazers_count': 1, 'name': 'legionJS'}, {'stargazers_count': 0, 'name': 'lehman-hackathon'}, {'stargazers_count': 0, 'name': 'mean-sandbox'}, {'stargazers_count': 0, 'name': 'mean-stack-talk'}, {'stargazers_count': 2, 'name': 'NOAA-Projects'}, {'stargazers_count': 0, 'name': 'node'}, {'stargazers_count': 0, 'name': 'nodeapps'}, {'stargazers_count': 1, 'name': 'pascal-compiler'}, {'stargazers_count': 0, 'name': 'pascal-js'}, {'stargazers_count': 0, 'name': 'Project-Euler'}, {'stargazers_count': 0, 'name': 'python-imp-interpreter'}, {'stargazers_count': 0, 'name': 'rst2pdf'}, {'stargazers_count': 0, 'name': 'rust-by-example'}, {'stargazers_count': 1, 'name': 'rust-sandbox'}, {'stargazers_count': 0, 'name': 'satellizer'}, {'stargazers_count': 0, 'name': 'smw-asm'}, {'stargazers_count': 2, 'name': 'swift-sandbox'}, {'stargazers_count': 1, 'name': 'Tales-of-Kratos'}, {'stargazers_count': 0, 'name': 'theano-sandbox'}, {'stargazers_count': 0, 'name': 'todo'}, {'stargazers_count': 0, 'name': 'TV-Show-Premieres'}, {'stargazers_count': 0, 'name': 'tv-show-tracker'}, {'stargazers_count': 0, 'name': 'vitanao'}, {'stargazers_count': 0, 'name': 'WaterEmblem'}, {'stargazers_count': 0, 'name': 'webauth-ssh-authentication'}, {'stargazers_count': 0, 'name': 'webauth-via-ssh'}, {'stargazers_count': 0, 'name': 'WebRing'}, {'stargazers_count': 0, 'name': 'yabe'}] 177 | with patch('hackathon.scripts.github.filterStarGazerCount') as mock_filterStarGazerCount: 178 | mock_filterStarGazerCount.return_value = [{'stargazers_count': 3, 'name': 'Deep-Learning'}, {'stargazers_count': 2, 'name': 'angular-nhl'}, {'stargazers_count': 2, 'name': 'NOAA-Projects'}, {'stargazers_count': 2, 'name': 'swift-sandbox'}, {'stargazers_count': 1, 'name': 'ACM-Portfolio-Presentation'}, {'stargazers_count': 1, 'name': 'git-technetium'}, {'stargazers_count': 1, 'name': 'integrated-chinese'}, {'stargazers_count': 1, 'name': 'legionJS'}, {'stargazers_count': 1, 'name': 'pascal-compiler'}] 179 | maxStars = filterStarGazerCount(data) 180 | self.assertEqual(maxStars, maxStars) 181 | 182 | def testFilterCommits(self): 183 | '''Test for github.py filtercommits''' 184 | maxCommits = [] 185 | data = [{'total': 85, 'repo_name': 'ACM-Game-Presentation', 'author': 'DrkSephy'}, {'total': 16, 'repo_name': 'ACM-Portfolio-Presentation', 'author': 'DrkSephy'}, {'total': 17, 'repo_name': 'angular-nhl', 'author': 'DrkSephy'}, {'total': 1, 'repo_name': 'async', 'author': 'DrkSephy'}, {'total': 55, 'repo_name': 'd3-sandbox', 'author': 'DrkSephy'}, {'total': 7, 'repo_name': 'Deep-Learning', 'author': 'DrkSephy'}, {'total': 11, 'repo_name': 'Django-Hackathon-Starter', 'author': 'DrkSephy'}, {'total': 433, 'repo_name': 'drksephy.github.io', 'author': 'DrkSephy'}, {'total': 3, 'repo_name': 'el-gamal-attack', 'author': 'DrkSephy'}, {'total': 1, 'repo_name': 'FizzBuzz-Test-1', 'author': 'DrkSephy'}, {'total': 44, 'repo_name': 'flux-reactJS', 'author': 'DrkSephy'}, {'total': 4, 'repo_name': 'fractals', 'author': 'DrkSephy'}, {'total': 32, 'repo_name': 'git-api', 'author': 'DrkSephy'}, {'total': 160, 'repo_name': 'git-technetium', 'author': 'DrkSephy'}, {'total': 1, 'repo_name': 'hackathon-starter', 'author': 'DrkSephy'}, {'total': 6, 'repo_name': 'hackcity', 'author': 'DrkSephy'}, {'total': 4, 'repo_name': 'hackcity.github.io', 'author': 'DrkSephy'}, {'total': 15, 'repo_name': 'I4330', 'author': 'DrkSephy'}, {'total': 31, 'repo_name': 'integrated-chinese', 'author': 'DrkSephy'}, {'total': 1, 'repo_name': 'jsrecipes', 'author': 'DrkSephy'}, {'total': 20, 'repo_name': 'learn-angularJS', 'author': 'DrkSephy'}, {'total': 13, 'repo_name': 'legionJS', 'author': 'DrkSephy'}, {'total': 26, 'repo_name': 'lehman-hackathon', 'author': 'DrkSephy'}, {'total': 55, 'repo_name': 'mean-sandbox', 'author': 'DrkSephy'}, {'total': 4, 'repo_name': 'mean-stack-talk', 'author': 'DrkSephy'}, {'total': 297, 'repo_name': 'NOAA-Projects', 'author': 'DrkSephy'}, {'total': 39, 'repo_name': 'nodeapps', 'author': 'DrkSephy'}, {'total': 488, 'repo_name': 'pascal-compiler', 'author': 'DrkSephy'}, {'total': 117, 'repo_name': 'pascal-js', 'author': 'DrkSephy'}, {'total': 12, 'repo_name': 'Project-Euler', 'author': 'DrkSephy'}, {'total': 139, 'repo_name': 'python-imp-interpreter', 'author': 'DrkSephy'}, {'total': 2, 'repo_name': 'rst2pdf', 'author': 'DrkSephy'}, {'total': 2, 'repo_name': 'rust-by-example', 'author': 'DrkSephy'}, {'total': 34, 'repo_name': 'rust-sandbox', 'author': 'DrkSephy'}, {'total': 2, 'repo_name': 'satellizer', 'author': 'DrkSephy'}, {'total': 45, 'repo_name': 'smw-asm', 'author': 'DrkSephy'}, {'total': 291, 'repo_name': 'swift-sandbox', 'author': 'DrkSephy'}, {'total': 101, 'repo_name': 'Tales-of-Kratos', 'author': 'DrkSephy'}, {'total': 12, 'repo_name': 'theano-sandbox', 'author': 'DrkSephy'}, {'total': 13, 'repo_name': 'todo', 'author': 'DrkSephy'}, {'total': 18, 'repo_name': 'TV-Show-Premieres', 'author': 'DrkSephy'}, {'total': 34, 'repo_name': 'tv-show-tracker', 'author': 'DrkSephy'}, {'total': 1, 'repo_name': 'vitanao', 'author': 'DrkSephy'}, {'total': 475, 'repo_name': 'WaterEmblem', 'author': 'DrkSephy'}, {'total': 3, 'repo_name': 'webauth-ssh-authentication', 'author': 'DrkSephy'}, {'total': 3, 'repo_name': 'WebRing', 'author': 'DrkSephy'}, {'total': 15, 'repo_name': 'yabe', 'author': 'DrkSephy'}] 186 | with patch('hackathon.scripts.github.filterCommits') as mock_filterCommits: 187 | mock_filterCommits.return_value = [{'total': 488, 'repo_name': 'pascal-compiler', 'author': 'DrkSephy'}, {'total': 475, 'repo_name': 'WaterEmblem', 'author': 'DrkSephy'}, {'total': 433, 'repo_name': 'drksephy.github.io', 'author': 'DrkSephy'}, {'total': 297, 'repo_name': 'NOAA-Projects', 'author': 'DrkSephy'}, {'total': 291, 'repo_name': 'swift-sandbox', 'author': 'DrkSephy'}, {'total': 160, 'repo_name': 'git-technetium', 'author': 'DrkSephy'}, {'total': 139, 'repo_name': 'python-imp-interpreter', 'author': 'DrkSephy'}, {'total': 117, 'repo_name': 'pascal-js', 'author': 'DrkSephy'}, {'total': 101, 'repo_name': 'Tales-of-Kratos', 'author': 'DrkSephy'}] 188 | maxCommits = [{'total': 488, 'repo_name': 'pascal-compiler', 'author': 'DrkSephy'}, {'total': 475, 'repo_name': 'WaterEmblem', 'author': 'DrkSephy'}, {'total': 433, 'repo_name': 'drksephy.github.io', 'author': 'DrkSephy'}, {'total': 297, 'repo_name': 'NOAA-Projects', 'author': 'DrkSephy'}, {'total': 291, 'repo_name': 'swift-sandbox', 'author': 'DrkSephy'}, {'total': 160, 'repo_name': 'git-technetium', 'author': 'DrkSephy'}, {'total': 139, 'repo_name': 'python-imp-interpreter', 'author': 'DrkSephy'}, {'total': 117, 'repo_name': 'pascal-js', 'author': 'DrkSephy'}, {'total': 101, 'repo_name': 'Tales-of-Kratos', 'author': 'DrkSephy'}] 189 | self.assertEqual(maxCommits, maxCommits) 190 | 191 | 192 | 193 | --------------------------------------------------------------------------------