├── README.md ├── ButtShortener ├── api │ ├── __init__.py │ └── v1.py ├── models.py ├── __init__.py └── generator.py ├── requirements.txt ├── .gitignore └── LICENSE /README.md: -------------------------------------------------------------------------------- 1 | # ButtShortener 2 | A URL Shortener Service for butts.so 3 | -------------------------------------------------------------------------------- /ButtShortener/api/__init__.py: -------------------------------------------------------------------------------- 1 | from flask import Blueprint 2 | from flask.ext.restful import Api 3 | 4 | api = Blueprint('api', __name__) 5 | restv1 = Api(api, prefix="/v1") -------------------------------------------------------------------------------- /ButtShortener/models.py: -------------------------------------------------------------------------------- 1 | from ButtShortener import db 2 | 3 | 4 | class ShortURL(db.Model): 5 | key = db.Column(db.String(32), primary_key=True) 6 | target = db.Column(db.Text) -------------------------------------------------------------------------------- /ButtShortener/api/v1.py: -------------------------------------------------------------------------------- 1 | from ButtShortener.api import restv1 2 | from flask.ext.restful import Resource, reqparse 3 | 4 | parser = reqparse.RequestParser() 5 | 6 | 7 | class MainResource(Resource): 8 | def post(self): 9 | '''Create a new short URL''' 10 | args = parser.parse_args() -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | alembic==0.7.4 2 | aniso8601==0.92 3 | Flask==0.10.1 4 | Flask-Assets==0.10 5 | Flask-Login==0.2.11 6 | Flask-Migrate==1.3.0 7 | Flask-RESTful==0.3.1 8 | Flask-Script==2.0.5 9 | Flask-SQLAlchemy==2.0 10 | itsdangerous==0.24 11 | Jinja2==2.7.3 12 | Mako==1.0.1 13 | MarkupSafe==0.23 14 | pytz==2014.10 15 | six==1.9.0 16 | SQLAlchemy==0.9.8 17 | webassets==0.10.1 18 | Werkzeug==0.10.1 19 | -------------------------------------------------------------------------------- /ButtShortener/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from flask import Flask 4 | from flask.ext.assets import Bundle, Environment 5 | from flask.ext.login import LoginManager, current_user 6 | from flask.ext.migrate import Migrate 7 | from flask.ext.sqlalchemy import SQLAlchemy 8 | 9 | from raven.contrib.flask import Sentry 10 | 11 | app = Flask(__name__) 12 | app.config.from_object('config') 13 | 14 | # Load Flask Extensions 15 | assets = Environment(app) 16 | db = SQLAlchemy(app) 17 | login_manager = LoginManager(app) 18 | migrate = Migrate(app, db) 19 | sentry = Sentry(app) 20 | 21 | # Load blueprints 22 | from ButtShortener.api import api 23 | app.register_blueprint(api, url_prefix='/api') -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | .Python 10 | env/ 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | lib/ 17 | lib64/ 18 | parts/ 19 | sdist/ 20 | var/ 21 | *.egg-info/ 22 | .installed.cfg 23 | *.egg 24 | 25 | # PyInstaller 26 | # Usually these files are written by a python script from a template 27 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 28 | *.manifest 29 | *.spec 30 | 31 | # Installer logs 32 | pip-log.txt 33 | pip-delete-this-directory.txt 34 | 35 | # Unit test / coverage reports 36 | htmlcov/ 37 | .tox/ 38 | .coverage 39 | .cache 40 | nosetests.xml 41 | coverage.xml 42 | 43 | # Translations 44 | *.mo 45 | *.pot 46 | 47 | # Django stuff: 48 | *.log 49 | 50 | # Sphinx documentation 51 | docs/_build/ 52 | 53 | # PyBuilder 54 | target/ 55 | 56 | # PyCharm 57 | .idea/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Harry Reeder 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /ButtShortener/generator.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | beginnings = [ 4 | 'pb', 5 | 'f', 6 | 'ph', 7 | 'bl', 8 | ] 9 | middles = [ 10 | 'f', 11 | 'b', 12 | 'p', 13 | 'r', 14 | 'a', 15 | '4' 16 | ] 17 | ends = [ 18 | 't', 19 | 'p', 20 | 'r', 21 | 'b', 22 | '7' 23 | ] 24 | words = [ 25 | 'good', 26 | 'awesome', 27 | 'epic', 28 | 'bootylicious', 29 | 'outtathisworld', 30 | 'amazing', 31 | 'trashy', 32 | 'bubbly' 33 | ] 34 | 35 | 36 | def make_fart_sound(): 37 | output = random.choice(beginnings) 38 | length = random.randint(3, 10) 39 | for x in range(length): 40 | output += random.choice(middles) 41 | output += random.choice(ends) 42 | 43 | return output 44 | 45 | 46 | def generate_shortened_url(): 47 | real_word = not bool(random.randint(0, 250)) 48 | if real_word: 49 | shortcode = random.choice(words) 50 | else: 51 | shortcode = make_fart_sound() 52 | 53 | output = "" 54 | for letter in shortcode: 55 | uppercase = bool(random.randint(0, 1)) 56 | if uppercase: 57 | letter = letter.upper() 58 | output += letter 59 | 60 | return output --------------------------------------------------------------------------------