URL短縮サービスつくってみた

日曜日, 1月 16th, 2011 by

GAE/PythonでURL短縮サービス作ってみたので、ソースコード丸ごと公開しちゃいます。

作成したサービスはこちらから利用できます。⇒http://pyshortener.appspot.com/

作成にあたってのポイント

実装上するにあたって工夫した点を紹介します。

連番の取得

短縮URLの短縮コードって連番を16進数や64進数などにエンコードしたものですよね。ということで、短縮URLを作成するためには、連番を作る必要があります。DBとしてMySQLを使っていればauto_incrementを指定するだけで連番が設定されます。だけど、GAE/Pythonには連番を自動生成する手法が容易されていません。そこで、最大値を管理するデータモデル(テーブル)を作成し、getNextNum()で取得できるようにしました。トランザクション内で操作しているので、同じ数字が2回発行されることは無いはずです。

短縮URLは出来るだけ短く

短縮URLはルートディレクトリに対して設定しました。/以降に何も記述されていない場合はURL作成フォームを表示しますが、1文字でも記述されていれば短縮URLが設定されているものと判断します。

ソースコード

1時間で作ったので細かい部分まではつめきれてません。まずい部分があれば指摘いただければと思います。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from google.appengine.ext import webapp
from google.appengine.ext.webapp import util
from google.appengine.ext import db
import os

class MyHandler(webapp.RequestHandler):
  def write(self, str):
    self.response.out.write(str)

class MainHandler(MyHandler):
  def get(self, pageStr):
    if pageStr == '':
      self.write(u"""
      <form method="post" action="/"><input type="hidden" name="phpMyAdmin" value="cfc2644bd9c947213a0141747c2608b0" />
        <input type="text" name="url"/>
        <input type="submit" value="短縮"
      </form>
  """
)
    else:
      url = URL.all().filter("num = ", int(pageStr, base = 16))
      for u in url:
        self.redirect(u.url)
  def post(self, dummy):
    num = getNextNum()
    url = URL(url = self.request.get('url'), num = num)
    url.put()
    self.redirect("/thanks/%x" % num)

class ThanksHandler(MyHandler):
  def get(self, code):
    self.write('<input type="text" size="40" value="http://%(appid)s.appspot.com/%(code)s"/><a href="/?phpMyAdmin=cfc2644bd9c947213a0141747c2608b0">戻る</a>' % {'appid':os.environ["APPLICATION_ID"], 'code':code})

def getNextNum():
  def procedure():
    num = MAXNUM.get_by_key_name('URL')
    if num is None:
      num = MAXNUM(key_name = 'URL')
    num.max_num = num.max_num + 1
    num.put()
    return num.max_num
  return db.run_in_transaction(procedure)

class URL(db.Model):
  url = db.URLProperty()
  num = db.IntegerProperty()

class MAXNUM(db.Model):
  max_num = db.IntegerProperty(default = 0)

def main():
  application = webapp.WSGIApplication([
    ('/thanks/(.*)', ThanksHandler),
    ('/(.*)', MainHandler)
  ], debug=True)
  util.run_wsgi_app(application)

if __name__ == '__main__':
  main()

まとめ

ドメイン

独自ドメインを設定していないため、短縮URLといっておきながら、全く短くなりません。後日、独自ドメインを設定したいと思います。

デザイン

デザイン面に関しては、協力いただける方がいれば、大歓迎です。

例外処理など

明日にでも実装します。

Facebook comments:

comments

Leave a Reply


Get Adobe Flash player
single