├── __init__.py ├── m ├── __init__.py └── views.py ├── api ├── __init__.py └── views.py ├── detail ├── __init__.py └── views.py ├── page ├── __init__.py └── views.py ├── search ├── __init__.py └── views.py ├── _config ├── __init__.py └── devconfig.py ├── transfer ├── __init__.py ├── BTL.py ├── views.py └── bencode.py ├── vodplay ├── __init__.py └── views.py ├── static ├── favicon.ico ├── images │ ├── logo.png │ ├── loading.gif │ └── magnet.png ├── img │ ├── glyphicons-halflings.png │ └── glyphicons-halflings-white.png ├── css │ └── bootstrap-fileupload.min.css └── js │ ├── bootstrap-fileupload.min.js │ ├── bootstrap.min.js │ └── jquery-1.8.2.min.js ├── README.md ├── database.py ├── .gitignore ├── templates ├── 404.html ├── page │ ├── about.html │ └── faq.html ├── vodplay │ ├── play_prepare.html │ ├── play.html │ └── index.html ├── transfer │ ├── indexm2t.html │ └── indext2m.html ├── search │ ├── index.html │ └── search_list.html ├── api │ └── index.html ├── m │ ├── show.html │ └── index.html ├── index.html ├── detail │ └── single_result.html └── base.html ├── .settings └── org.eclipse.core.resources.prefs ├── utils.py └── app.py /__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /m/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /api/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /detail/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /page/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /search/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_config/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /transfer/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vodplay/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /transfer/BTL.py: -------------------------------------------------------------------------------- 1 | class BTFailure(Exception): 2 | pass 3 | -------------------------------------------------------------------------------- /static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zlmoment/Magnet-Links-Search-Engine/HEAD/static/favicon.ico -------------------------------------------------------------------------------- /static/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zlmoment/Magnet-Links-Search-Engine/HEAD/static/images/logo.png -------------------------------------------------------------------------------- /static/images/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zlmoment/Magnet-Links-Search-Engine/HEAD/static/images/loading.gif -------------------------------------------------------------------------------- /static/images/magnet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zlmoment/Magnet-Links-Search-Engine/HEAD/static/images/magnet.png -------------------------------------------------------------------------------- /static/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zlmoment/Magnet-Links-Search-Engine/HEAD/static/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /static/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zlmoment/Magnet-Links-Search-Engine/HEAD/static/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | It's a magnet links search engine built with Python. 2 | 3 | You can see the demo here: [Mgnt.me](http://mgnt.me) (This link is no longer available) 4 | -------------------------------------------------------------------------------- /database.py: -------------------------------------------------------------------------------- 1 | import _mysql 2 | 3 | def getConn(): 4 | try: 5 | conn = _mysql.connect(host='localhost', user='root', passwd='', db='mgnt', port=3306) 6 | except Exception, e: 7 | print "Failed connection!", e 8 | return 9 | return conn -------------------------------------------------------------------------------- /_config/devconfig.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | 4 | # site inform 5 | SITE_TITLE = 'MGNT.me' 6 | SITE_DESC = u'磁力链接搜索引擎,云播放,磁连接短网址,磁性链接转换,磁性连接资源下载。' 7 | 8 | # This is a config file for development 9 | DEBUG = True 10 | 11 | SECRET_KEY = 'secret-key-for-development' 12 | 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.py[cod] 2 | 3 | # C extensions 4 | *.so 5 | 6 | # Packages 7 | *.egg 8 | *.egg-info 9 | dist 10 | build 11 | eggs 12 | parts 13 | bin 14 | var 15 | sdist 16 | develop-eggs 17 | .installed.cfg 18 | lib 19 | lib64 20 | 21 | # Installer logs 22 | pip-log.txt 23 | 24 | # Unit test / coverage reports 25 | .coverage 26 | .tox 27 | nosetests.xml 28 | 29 | # Translations 30 | *.mo 31 | 32 | # Mr Developer 33 | .mr.developer.cfg 34 | .project 35 | .pydevproject 36 | -------------------------------------------------------------------------------- /page/views.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from flask import Blueprint 4 | from flask import render_template 5 | 6 | app = Blueprint('page', __name__) 7 | 8 | @app.route('/', methods=['GET']) 9 | @app.route('', methods=['GET']) 10 | @app.route('/about', methods=['GET']) 11 | @app.route('/about/', methods=['GET']) 12 | def about(): 13 | return render_template("/page/about.html") 14 | 15 | @app.route('/faq', methods=['GET']) 16 | @app.route('/faq/', methods=['GET']) 17 | def faq(): 18 | return render_template("/page/faq.html") -------------------------------------------------------------------------------- /templates/404.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block container %} 4 | 5 | {% endblock%} 6 | 7 | {% block footer %} 8 | 14 | {% endblock%} 15 | 16 | -------------------------------------------------------------------------------- /templates/page/about.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block windowtitle %} 4 | 关于 MGNT.me 5 | {% endblock%} 6 | {% block container %} 7 |
8 |
9 |

关于 MGNT.me

10 |
11 |
12 |
13 |
14 |

关于本站

15 |

玛格磁力搜索(MGNT.me)致力于给用户提供一个开放、自由的互联网资源分享、搜索平台,本站不保存任何与资源有关的文件,所有资源均索引自互联网。

16 |
17 |
18 |
19 |
20 |
21 |

关于本站的资源

22 |

本站所有资源信息均从互联网搜索而来,本站不对显示的内容承担责任。本站也不保存有任何可直接下载的文件。

23 |

本站的云播放功能仅用于带宽测试,本站不保存任何影视文件,所有影视文件均由迅雷网络提供。

24 |

本站为非盈利性网站,请勿将本站资源用于商业用途。

25 |
26 |
27 |
28 |
29 |

感谢

30 |

感谢以下开源平台和产品

31 | 37 |
38 |
39 |
40 |
41 |

联系信息

42 |

如有任何问题请与 mgnt.me#gmail.com(将#换成@) 联系。 43 |

44 |
45 | {% endblock%} -------------------------------------------------------------------------------- /.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//_config/devconfig.py=utf-8 3 | encoding//api/views.py=utf-8 4 | encoding//detail/views.py=utf-8 5 | encoding//m/views.py=utf-8 6 | encoding//page/views.py=utf-8 7 | encoding//search/views.py=utf-8 8 | encoding//templates/404.html=UTF-8 9 | encoding//templates/api/index.html=UTF-8 10 | encoding//templates/detail/single_result.html=UTF-8 11 | encoding//templates/index.html=UTF-8 12 | encoding//templates/m/index.html=UTF-8 13 | encoding//templates/m/show.html=UTF-8 14 | encoding//templates/page/about.html=UTF-8 15 | encoding//templates/page/faq.html=UTF-8 16 | encoding//templates/search/index.html=UTF-8 17 | encoding//templates/search/search_list.html=UTF-8 18 | encoding//templates/transfer/indexm2t.html=UTF-8 19 | encoding//templates/transfer/indext2m.html=UTF-8 20 | encoding//templates/vodplay/index.html=UTF-8 21 | encoding//templates/vodplay/play.html=UTF-8 22 | encoding//templates/vodplay/play_prepare.html=UTF-8 23 | encoding//transfer/views.py=utf-8 24 | encoding//vodplay/views.py=utf-8 25 | encoding/=UTF-8 26 | encoding/utils.py=utf-8 27 | -------------------------------------------------------------------------------- /utils.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from random import choice 4 | from database import getConn 5 | 6 | def import_object(name, arg=None): 7 | if '.' not in name: 8 | return __import__(name) 9 | parts = name.split('.') 10 | obj = __import__('.'.join(parts[:-1]), None, None, [parts[-1]], 0) 11 | return getattr(obj, parts[-1], arg) 12 | 13 | def create_token(length=6): 14 | chars = ('0123456789' 15 | 'abcdefghijklmnopqrstuvwxyz' 16 | 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') 17 | salt = ''.join([choice(chars) for i in range(length)]) 18 | return salt 19 | 20 | def createShortLink(maglink): 21 | short_link = create_token() 22 | conn = getConn() 23 | conn.query("""select short_url from mgnt_url where long_url='%s';""" % maglink) 24 | result = conn.store_result().fetch_row() 25 | if result == (): 26 | sql = """ 27 | INSERT INTO `mgnt`.`mgnt_url` (`id` ,`short_url`, `long_url`, `ctime`) 28 | VALUES (NULL ,'%s','%s', CURRENT_TIMESTAMP); 29 | """ % (short_link, maglink) 30 | conn.query(sql) 31 | else: 32 | short_link = result[0][0] 33 | return short_link -------------------------------------------------------------------------------- /app.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | PROJDIR = os.path.abspath(os.path.dirname(__file__)) 5 | ROOTDIR = os.path.split(PROJDIR)[0] 6 | CONFDIR = os.path.join(PROJDIR, '_config') 7 | 8 | 9 | from flask import Flask 10 | from flask import render_template 11 | from utils import import_object 12 | 13 | 14 | app = Flask( 15 | __name__, 16 | static_folder='static', 17 | template_folder='templates' 18 | ) 19 | 20 | 21 | def register(blueprint, url_prefix=None): 22 | """blueprint structure: 23 | 24 | {{blueprint}}/ 25 | __init__.py 26 | models.py 27 | views.py 28 | """ 29 | 30 | if url_prefix is None: 31 | url_prefix = '/%s' % blueprint 32 | 33 | views = import_object('%s.views' % blueprint) 34 | app.register_blueprint(views.app, url_prefix=url_prefix) 35 | return app 36 | 37 | 38 | def prepare_app(): 39 | register('search') 40 | register('detail') 41 | register('vodplay') 42 | register('transfer') 43 | register('m') 44 | register('page') 45 | register('api') 46 | return app 47 | 48 | @app.route('/') 49 | def hello(): 50 | return render_template('index.html') 51 | 52 | @app.errorhandler(404) 53 | def page_not_found(e): 54 | return render_template('404.html'), 404 55 | 56 | if __name__ == '__main__': 57 | app.config.from_pyfile(os.path.join(CONFDIR, 'devconfig.py')) 58 | prepare_app() 59 | app.run(host='0.0.0.0') 60 | -------------------------------------------------------------------------------- /search/views.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from flask import Blueprint 4 | from flask import render_template, flash 5 | from flask import request 6 | 7 | import urllib2 8 | import json 9 | 10 | app = Blueprint('search', __name__) 11 | 12 | 13 | @app.route('/', methods=['GET']) 14 | @app.route('', methods=['GET']) 15 | def searchindex(): 16 | return render_template("/search/index.html") 17 | 18 | @app.route('/s/', methods=['GET']) 19 | @app.route('/s', methods=['GET']) 20 | def search(): 21 | searchword = request.args.get('kw', '') 22 | page = request.args.get('page', '1') 23 | if searchword == "" or page == "": 24 | flash(u"亲,搜索词不能为空哦~") 25 | return render_template("index.html") 26 | result = {} 27 | result["searchword"] = searchword 28 | url = "http://torrentproject.com/?s="+searchword+"&start="+str(int(page)-1)+"&orderby=best&out=json" 29 | url=url.encode('utf-8') 30 | url=urllib2.unquote(url) 31 | f = urllib2.urlopen(url) 32 | json_string = f.read() 33 | parsed_json = json.loads(json_string) 34 | result["total"] = int(parsed_json['total_found']) 35 | result["total_pages"] = int(result["total"])/50 + 1 36 | result["current_page"] = int(page) 37 | result_list = [] 38 | for ob in parsed_json: 39 | if ob == "total_found": 40 | pass 41 | else: 42 | result_list.append(parsed_json[ob]) 43 | result_list = sorted(result_list, key=lambda x:x['leechs'], reverse=True) 44 | result["list"] = enumerate(result_list) 45 | return render_template("/search/search_list.html", result = result, kw = searchword) -------------------------------------------------------------------------------- /templates/page/faq.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block windowtitle %} 4 | 常见问题 5 | {% endblock%} 6 | 7 | {% block container %} 8 |
9 |
10 |

常见问题

11 |
12 |
13 | 14 |
15 |
16 |

什么是磁力链接?

17 |

简单的说:类似下面这样以“magnet:?”开头的字符串,就是一条“磁力链接”:magnet:?xt=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C】

18 |

确切的说:“磁力链接”的主要作用是识别【能够通过“点对点技术(即:P2P)”下载的文件】。

19 |

这种链接是通过不同文件内容的Hash结果生成一个纯文本的“数字指纹”,来识别文件的。而不是基于文件的位置或者名称(例如:http://www.123.com/123.exe)。

20 |

这就类似生活中消费品包装上常见的条码。不同的是这个“数字指纹”可以被任何人从任何文件上生成,这也就注定了“磁力链接”不需要任何“中心机构”的支持(例如:BT Tracker服务器),且识别准确度极高。

21 |

因此任何人都可以生成一个Magnet链接并确保通过该链接下载的文件准确无误。

22 |
23 |
24 | 25 |
26 |
27 |

如何下载磁力链接?

28 |

如下客户端均支持磁力链接下载:

29 |
    30 |
  • 迅雷
  • 31 |
  • QQ旋风
  • 32 |
  • μTorrent
  • 33 |
  • BitComet
  • 34 |
  • BitSpirit
  • 35 |
  • Transmission
  • 36 |
  • 此外,支持磁力连结的应用程序还包括Vuze、BearShare、DC++、Deluge、gtk-gnutella、Kazaa、LimeWire、FrostWire、MP3 Rocket、Morpheus、Shareaza、MLdonkey、aMule、KCeasy和TrustyFiles等。
  • 37 |
38 |
39 |
40 | 41 |
42 |
43 |

为什么云点播有时候无法使用?

44 |

云点播使用的是迅雷云播放平台,如果遇到无法播放的情况,请稍等后刷新页面重新加载。

45 |
46 |
47 | 48 |
49 |
50 |

为什么一直停留在“获取磁力链接信息”?

51 |

“磁力链接”是通过DHT网络来索引需要下载的文件的,因此在某些环境下可能出现“获取磁力链接信息”时间较长,或者获取失败的问题。由于目前相关问题经验的积累很少,因此除了重试还没有明确的解决办法。

52 | 53 |
54 |
55 | {% endblock%} -------------------------------------------------------------------------------- /templates/vodplay/play_prepare.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% block windowtitle %} 3 | 播放页 4 | {% endblock%} 5 | 6 | {% block meta %} 7 | 8 | {% endblock %} 9 | 10 | {% block container %} 11 | 12 | {% if error %} 13 |
14 |
15 |
16 | 17 | 播放参数不能为空 18 |
19 |
20 |
21 | {% else %} 22 |
23 |
24 |
25 |

26 | logo 27 |
28 |
29 |
30 |
31 |

MGNT.me 正在为您准备点播文件,请等待网页自动跳转

32 |
33 |
34 |
35 |
36 | logo 37 |

38 |
39 |
40 |
41 |
42 |

43 |

{{title}}

44 |
45 |
46 |
47 |
48 |

如果网页10秒钟之后没有跳转,请点击这里继续

49 |
50 |
51 |
52 | 53 | {% endif %} 54 | 55 | {% endblock%} -------------------------------------------------------------------------------- /m/views.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from flask import Blueprint 4 | from flask import render_template,request,flash 5 | import re,urllib2 6 | 7 | from utils import createShortLink, getConn 8 | 9 | app = Blueprint('m', __name__) 10 | 11 | @app.route('/', methods=['GET']) 12 | @app.route('', methods=['GET']) 13 | def m(): 14 | return render_template("/m/index.html") 15 | 16 | @app.route('/create', methods=['POST']) 17 | def create(): 18 | item = {} 19 | maglink = request.form['magnet'] 20 | regex=ur"magnet:\?.*" 21 | if not re.search(regex, maglink): 22 | flash(u"亲,您输入的不是磁力链接哦~") 23 | return render_template("/m/index.html") 24 | else: 25 | item["short_link"] = createShortLink(maglink) 26 | return render_template("/m/index.html",item=item) 27 | 28 | @app.route('//', methods=['GET']) 29 | @app.route('/', methods=['GET']) 30 | def surl(surl): 31 | item = {} 32 | if len(surl) != 6: 33 | error = u"亲,您输入的段地址好像不对哦~" 34 | return render_template("/m/show.html", error = error) 35 | else: 36 | conn = getConn() 37 | conn.query("""select short_url,long_url from mgnt_url where short_url='%s';""" % surl) 38 | result = conn.store_result().fetch_row() 39 | if result == (): 40 | error = u"不好意思,没有找到此链接..." 41 | return render_template("/m/show.html", error = error) 42 | else: 43 | short_link = result[0][0] 44 | maglink = result[0][1] 45 | hashid = maglink[20:60] 46 | item["short_link"] = "http://mgnt.me/m/"+short_link 47 | item["maglink"] = maglink 48 | item["hashid"] = hashid 49 | item["vodlink"] = urllib2.quote(u"/vodplay/magnet:?xt=urn:btih:")+hashid+"/Unknown" 50 | return render_template("/m/show.html",item=item) 51 | 52 | -------------------------------------------------------------------------------- /detail/views.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from flask import Blueprint 4 | from flask import render_template 5 | import urllib2 6 | import json 7 | 8 | from utils import createShortLink 9 | 10 | app = Blueprint('detail', __name__) 11 | 12 | @app.route('', methods=['GET']) 13 | @app.route('/', methods=['GET']) 14 | def detail(): 15 | return render_template("/detail/single_result.html", error = True) 16 | 17 | 18 | @app.route('///<size>/<seeds>/<leechs>') 19 | @app.route('/<hashid>/<title>/<size>/<seeds>/<leechs>/') 20 | def single_result(hashid,title,size,seeds,leechs): 21 | item = {} 22 | item["hashid"] = hashid 23 | item["title"] = title 24 | item["size"] = size 25 | item["seeds"] = seeds 26 | item["leechs"] = leechs 27 | if hashid == "": 28 | return render_template("/detail/single_result.html", error = True) 29 | # get tracker json list 30 | url = "http://torrentproject.com/"+hashid+"/trackers_json" 31 | url=url.encode('utf-8') 32 | url=urllib2.unquote(url) 33 | f = urllib2.urlopen(url) 34 | json_string = f.read() 35 | trackerJson = json.loads(json_string) 36 | maglink = "magnet:?xt=urn:btih:"+hashid+"&dn=" + urllib2.quote(title.encode('utf-8')) 37 | for t in trackerJson: 38 | maglink += "&tr=" + t 39 | maglink += "&tr=http://tracker.openbittorrent.com/announce&tr=udp://tracker.openbittorrent.com:80/announce&tr=http://tracker.thepiratebay.org/announce&tr=http://tracker.publicbt.com/announce&tr=http://tracker.prq.to/announce&tr=udp://tracker.publicbt.com:80/announce" 40 | item["maglink"] = maglink 41 | item["perm_link"] = "http://mgnt.me/detail/"+hashid+"/"+title+"/"+size+"/"+seeds+"/"+leechs 42 | item["short_link"] = "http://mgnt.me/m/"+createShortLink(maglink) 43 | item["vodlink"] = urllib2.quote(u"/vodplay/magnet:?xt=urn:btih:")+hashid+"/"+urllib2.quote(title.encode('utf-8')) 44 | return render_template("/detail/single_result.html", item = item) 45 | 46 | -------------------------------------------------------------------------------- /templates/transfer/indexm2t.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block windowtitle %} 4 | 磁力链接转Torrent 5 | {% endblock%} 6 | 7 | {% block container %} 8 | <div class="row"> 9 | <div class="span12"> 10 | <h3>磁力链接转Torrent</h3> 11 | </div> 12 | </div> 13 | <div class="row" style="height:38px;"> 14 | <div class="span12"> 15 | <div class="jiathis_style_32x32"> 16 | <a class="jiathis_button_tsina"></a> 17 | <a class="jiathis_button_renren"></a> 18 | <a class="jiathis_button_tqq"></a> 19 | <a class="jiathis_button_qzone"></a> 20 | <a class="jiathis_button_fb"></a> 21 | <a class="jiathis_button_twitter"></a> 22 | <a class="jiathis_button_googleplus"></a> 23 | <a class="jiathis_button_tumblr"></a> 24 | <a href="http://www.jiathis.com/share?uid=906036" class="jiathis jiathis_txt jtico jtico_jiathis" target="_blank"></a> 25 | </div> 26 | </div> 27 | </div> 28 | <hr> 29 | {% with messages = get_flashed_messages() %} 30 | {% if messages %} 31 | <div class="alert alert-error" style="margin-top:10px;"> 32 | <button type="button" class="close" data-dismiss="alert">×</button> 33 | {% for message in messages %} 34 | {{ message }} 35 | {% endfor %} 36 | </div> 37 | {% endif %} 38 | {% endwith %} 39 | <div class="row"> 40 | <div class="span12"> 41 | <p>请将您得到的磁力链接粘贴到下方的输入框中,然后点击下载即可。<small>有些链接可能会提示找不到种子文件。</small></p> 42 | <form class="form-horizontal" method="post" action="http://magnet2torrent.com/upload/" id="m2bform"> 43 | <div class="control-group"> 44 | <input type="text" class="input-block-level" placeholder="请输入磁力链接" name="magnet" id="addressinput"> 45 | </div> 46 | <div class="control-group"> 47 | <a type="submit" class="btn btn-primary" href="javascript:submitform_m2b()" >获取种子文件</a> 48 | </div> 49 | <script type="text/javascript"> 50 | function submitform_m2b(){ 51 | if (document.getElementById('addressinput').value == "") 52 | alert("磁力链接不能为空"); 53 | else 54 | document.getElementById('m2bform').submit(); 55 | } 56 | </script> 57 | </form> 58 | </div> 59 | </div> 60 | <script type="text/javascript"> 61 | var jiathis_config = {data_track_clickback:'true'}; 62 | </script> 63 | <script type="text/javascript" src="http://v3.jiathis.com/code/jia.js?uid=906036" charset="utf-8"></script> 64 | {% endblock%} -------------------------------------------------------------------------------- /static/css/bootstrap-fileupload.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v2.2.2-j3 3 | * 4 | * Copyright 2012 Twitter, Inc 5 | * Licensed under the Apache License v2.0 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Designed and built with all the love in the world by @mdo and @fat, extended by @ArnoldDaniels. 9 | */ 10 | .clearfix{*zoom:1;}.clearfix:before,.clearfix:after{display:table;content:"";line-height:0;} 11 | .clearfix:after{clear:both;} 12 | .hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0;} 13 | .input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;} 14 | .btn-file{overflow:hidden;position:relative;vertical-align:middle;}.btn-file>input{position:absolute;top:0;right:0;margin:0;opacity:0;filter:alpha(opacity=0);transform:translate(-300px, 0) scale(4);font-size:23px;direction:ltr;cursor:pointer;} 15 | .fileupload{margin-bottom:9px;}.fileupload .uneditable-input{display:inline-block;margin-bottom:0px;vertical-align:middle;cursor:text;} 16 | .fileupload .thumbnail{overflow:hidden;display:inline-block;margin-bottom:5px;vertical-align:middle;text-align:center;}.fileupload .thumbnail>img{display:inline-block;vertical-align:middle;max-height:100%;} 17 | .fileupload .btn{vertical-align:middle;} 18 | .fileupload-exists .fileupload-new,.fileupload-new .fileupload-exists{display:none;} 19 | .fileupload-inline .fileupload-controls{display:inline;} 20 | .fileupload-new .input-append .btn-file{-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0;} 21 | .thumbnail-borderless .thumbnail{border:none;padding:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;} 22 | .fileupload-new.thumbnail-borderless .thumbnail{border:1px solid #ddd;} 23 | .control-group.warning .fileupload .uneditable-input{color:#a47e3c;border-color:#a47e3c;} 24 | .control-group.warning .fileupload .fileupload-preview{color:#a47e3c;} 25 | .control-group.warning .fileupload .thumbnail{border-color:#a47e3c;} 26 | .control-group.error .fileupload .uneditable-input{color:#b94a48;border-color:#b94a48;} 27 | .control-group.error .fileupload .fileupload-preview{color:#b94a48;} 28 | .control-group.error .fileupload .thumbnail{border-color:#b94a48;} 29 | .control-group.success .fileupload .uneditable-input{color:#468847;border-color:#468847;} 30 | .control-group.success .fileupload .fileupload-preview{color:#468847;} 31 | .control-group.success .fileupload .thumbnail{border-color:#468847;} 32 | -------------------------------------------------------------------------------- /vodplay/views.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from flask import Blueprint 4 | from flask import render_template 5 | from flask import request,flash, redirect 6 | 7 | from utils import createShortLink 8 | 9 | import re 10 | import base64 11 | 12 | app = Blueprint('vodplay', __name__) 13 | 14 | @app.route('/', methods=['GET']) 15 | @app.route('', methods=['GET']) 16 | def vodplay(): 17 | return render_template("/vodplay/index.html") 18 | 19 | @app.route('/<source>/<title>', methods=['GET']) 20 | @app.route('/<source>/<title>/', methods=['GET']) 21 | #def play_prepare(source,title): 22 | # playid = base64.b64encode(source) 23 | # return render_template("/vodplay/play_prepare.html",playid = playid,title = title) 24 | def playtvgua(source,title): 25 | url = "http://www.tvgua.com/vodtest.php?url="+source 26 | return redirect(url) 27 | 28 | 29 | @app.route('/p/<playid>/<title>', methods=['GET']) 30 | @app.route('/p/<playid>/<title>/', methods=['GET']) 31 | def playwithcookie(playid,title): 32 | return render_template("/vodplay/play.html",playid = playid,title = title) 33 | 34 | @app.route('/fromaddress', methods=['GET']) 35 | def playfromadd(): 36 | source = request.args.get('add', '') 37 | source = source.lower() 38 | if source == "": 39 | flash(u"亲~输入的资源地址不能为空!") 40 | return render_template("/vodplay/index.html") 41 | regex=[ur"thunder:.*",ur"http:.*",ur"ftp:.*",ur"magnet:.*",ur"ed2k:.*"] 42 | isright = False 43 | for r in regex: 44 | if re.search(r, source): 45 | isright = True 46 | if not isright: 47 | flash(u"亲~您输入的资源地址好像不对哦!") 48 | return render_template("/vodplay/index.html") 49 | else: 50 | #playid = base64.b64encode(source) 51 | #title = u"未知,内容资源来自用户输入" 52 | #return render_template("/vodplay/play_prepare.html",playid = playid,title = title) 53 | url = "http://www.tvgua.com/vodtest.php?url="+source 54 | return redirect(url) 55 | 56 | @app.route('/fromhashid', methods=['GET']) 57 | def playfromhashid(): 58 | source = request.args.get('hashid', '') 59 | source = source.lower() 60 | if source == "": 61 | flash(u"亲~输入的资源不能为空!") 62 | return render_template("/vodplay/index.html") 63 | if len(source) != 40: 64 | flash(u"亲~您输入的特征值好像不对哦!") 65 | return render_template("/vodplay/index.html") 66 | else: 67 | source = "magnet:?xt=urn:btih:"+source 68 | #playid = base64.b64encode(source) 69 | #title = u"未知,内容资源来自用户输入" 70 | #return render_template("/vodplay/play_prepare.html",playid = playid,title = title) 71 | url = "http://www.tvgua.com/vodtest.php?url="+source 72 | return redirect(url) 73 | 74 | -------------------------------------------------------------------------------- /templates/search/index.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block windowtitle %}磁力链资源搜索{% endblock%} 4 | {% block contentright %} 5 | {% with messages = get_flashed_messages() %} 6 | {% if messages %} 7 | <ul class=flashes> 8 | {% for message in messages %} 9 | <li>{{ message }}</li> 10 | {% endfor %} 11 | </ul> 12 | {% endif %} 13 | {% endwith %} 14 | 15 | <div class="verticle"></div> 16 | 17 | <div class="middle"> 18 | <img src="{{url_for('static', filename='images/logo.png')}}" alt="logo" /> 19 | </div> 20 | <p class="middle">磁力链资源搜索引擎</p> 21 | <div class="verticle clear"></div> 22 | 23 | 24 | <div class="search middle" style="float:none;margin:20px auto;"> 25 | <form method="get" action="/search/s"> 26 | <table border="0" cellspacing="0" cellpadding="0" id="torrent-search"> 27 | <tbody> 28 | <tr> 29 | <td class="liost-td"> 30 | <div style="position: relative;"> 31 | <input type="text" title="Search" value="{{kw}}" maxlength="2048" name="kw" class="liost" id="magsearch"> 32 | <input type="hidden" value="1" name="page"> 33 | </div> 34 | </td> 35 | <td> 36 | <div class="ds"> 37 | <div class="lsbb"> 38 | <input type="submit" value="搜索" class="lsb"> 39 | </div> 40 | </div> 41 | </td> 42 | </tr> 43 | </tbody> 44 | </table> 45 | </form> 46 | </div> 47 | <div class="verticle clear"></div> 48 | <p class="middle">亲,您还可以从任何页面的右上方直接搜索哦~</p> 49 | <p class="middle">目前索引资源数:4661177</p> 50 | <div class="verticle clear"></div> 51 | 52 | <div class="share middle" style="margin-left:220px;"> 53 | <!-- JiaThis Button BEGIN --> 54 | <div class="jiathis_style_32x32"> 55 | <a class="jiathis_button_tsina"></a> 56 | <a class="jiathis_button_renren"></a> 57 | <a class="jiathis_button_tqq"></a> 58 | <a class="jiathis_button_qzone"></a> 59 | <a class="jiathis_button_fb"></a> 60 | <a class="jiathis_button_twitter"></a> 61 | <a class="jiathis_button_googleplus"></a> 62 | <a class="jiathis_button_tumblr"></a> 63 | <a href="http://www.jiathis.com/share?uid=906036" class="jiathis jiathis_txt jtico jtico_jiathis" target="_blank"></a> 64 | </div> 65 | <!-- JiaThis Button END --> 66 | </div> 67 | <div class="verticle clear"></div> 68 | <p class="middle" style="font-size:12px;color:#ccc;">我们从DHT网络, thepiratebay.se, fenopy.eu, btjunkie.org, h33t.com, torrentfunk.com, torlock.com, isohunt.com, kat.ph, btscene.eu, torrentreactor.net, extratorrent.com, bitsnoop.com, mvgroup.org, bt-chat.com和其它300多个资源站收集资源并提供资源的磁力链接和种子(在线云播放功能火热测试中)。</p> 69 | <div class="verticle clear"></div> 70 | <p class="middle" style="font-size:12px;color:#ccc;">@2013</p> 71 | <div class="verticle clear"></div> 72 | <script type="text/javascript"> 73 | var jiathis_config = {data_track_clickback:'true'}; 74 | </script> 75 | <script type="text/javascript" src="http://v3.jiathis.com/code/jia.js?uid=906036" charset="utf-8"></script> 76 | {% endblock%} -------------------------------------------------------------------------------- /templates/search/search_list.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block windowtitle %} 4 | {{result.searchword}}结果列表 5 | {% endblock%} 6 | 7 | 8 | {% block container %} 9 | <div class="row"> 10 | <div class="span12"> 11 | <h3>{{result.searchword}}</span> 的磁力链接搜索结果</h3> 12 | <p>共找到 {{result.total}} 条结果</p> 13 | </div> 14 | </div> 15 | 16 | <div class="row"> 17 | <div class="span12"> 18 | <table class="table table-hover"> 19 | <thead> 20 | <tr> 21 | <th style="width: 64%;">名称</th> 22 | <th style="width: 10%;">分类</th> 23 | <th style="width: 10%;">文件大小</th> 24 | <th style="width: 8%;">种子数</th> 25 | <th style="width: 8%;">下载数</th> 26 | </tr> 27 | </thead> 28 | <tbody> 29 | {% for i,item in result.list %} 30 | <tr onMouseOver="rowOver(this)" onMouseOut="rowOut(this)"> 31 | {% if item.torrent_size>1073741824 %} 32 | {% set size = '%4.2f' % (item.torrent_size/1073741824) %} 33 | <td><a href="/detail/{{item.torrent_hash}}/{{item.title}}/{{size}}GB/{{item.seeds}}/{{item.leechs}}" target="_blank">{{item.title}}</a></td> 34 | <td>{{item.category}}</td> 35 | <td>{{size}} GB</td> 36 | <td>{{item.seeds}}</td> 37 | <td>{{item.leechs}}</td> 38 | {% else %} 39 | {% set size = '%4.2f' % (item.torrent_size/1048576) %} 40 | <td><a href="/detail/{{item.torrent_hash}}/{{item.title}}/{{size}}MB/{{item.seeds}}/{{item.leechs}}" target="_blank">{{item.title}}</a></td> 41 | <td>{{item.category}}</td> 42 | <td>{{size}} MB</td> 43 | <td>{{item.seeds}}</td> 44 | <td>{{item.leechs}}</td> 45 | {% endif %}</td> 46 | </tr> 47 | {% endfor %} 48 | <tr><td colspan="5">本站资源均来自网络,本站不保存任何实际的下载文件,也不对任何资源负责。</td></tr> 49 | </tbody> 50 | </table> 51 | 52 | <div class="row"> 53 | <div class="span1"></div> 54 | <div class="span10"> 55 | </div> 56 | <div class="span1"></div> 57 | </div> 58 | {% if result.total_pages > 1 %} 59 | <div class="pagination pagination-centered"> 60 | <ul> 61 | {% if result.current_page > 1 %} 62 | {% set num = result.current_page - 1 %} 63 | <li class="prev"><a href="/search/s?kw={{ result.searchword }}&page={{ num }}">←</a></li> 64 | {% else %} 65 | <li class="prev disabled"><a href="#">←</a></li> 66 | {% endif %} 67 | 68 | {% for num in range( 1, result.total_pages ) %} 69 | <li class="{{ 'active' if num == result.current_page else '' }}"><a href="/search/s?kw={{ result.searchword }}&page={{ num }}">{{ num }}</a></li> 70 | {% endfor %} 71 | 72 | {% if result.current_page < result.total_pages %} 73 | {% set num = result.current_page + 1 %} 74 | <li class="next"><a href="/search/s?kw={{ result.searchword }}&page={{ num }}">→</a></li> 75 | {% else %} 76 | <li class="next disabled"><a href="#">→</a></li> 77 | {% endif %} 78 | </ul> 79 | </div> 80 | {% endif %} 81 | </div> 82 | </div> 83 | 84 | {% endblock%} -------------------------------------------------------------------------------- /transfer/views.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from flask import Blueprint 4 | from flask import render_template, flash, redirect 5 | from flask import request 6 | import urllib2 7 | import json 8 | 9 | from BTL import BTFailure 10 | import bencode 11 | import hashlib 12 | 13 | from utils import createShortLink 14 | 15 | app = Blueprint('transfer', __name__) 16 | 17 | @app.route('/t2m', methods=['GET']) 18 | @app.route('/t2m/', methods=['GET']) 19 | def indext2m(): 20 | return render_template("/transfer/indext2m.html") 21 | 22 | @app.route('/m2t', methods=['GET']) 23 | @app.route('/m2t/', methods=['GET']) 24 | def indexm2t(): 25 | return render_template("/transfer/indexm2t.html") 26 | 27 | @app.route('/upload', methods=['POST']) 28 | def tor2mag(): 29 | data = request.files['upload_file'] 30 | if data: 31 | torrent = data.read() 32 | try: 33 | item={} 34 | metainfo = bencode.bdecode(torrent) 35 | info = metainfo['info'] 36 | hashid=hashlib.sha1(bencode.bencode(info)).hexdigest() 37 | title=metainfo['info']['name'] 38 | url = "http://torrentproject.com/"+hashid+"/trackers_json" 39 | url=url.encode('utf-8') 40 | url=urllib2.unquote(url) 41 | f = urllib2.urlopen(url) 42 | json_string = f.read() 43 | trackerJson = json.loads(json_string) 44 | maglink = "magnet:?xt=urn:btih:"+hashid+"&dn=" + urllib2.quote(title) 45 | for t in trackerJson: 46 | maglink += "&tr=" + t 47 | maglink += "&tr=http://tracker.openbittorrent.com/announce&tr=udp://tracker.openbittorrent.com:80/announce&tr=http://tracker.thepiratebay.org/announce&tr=http://tracker.publicbt.com/announce&tr=http://tracker.prq.to/announce&tr=udp://tracker.publicbt.com:80/announce" 48 | item["hashid"] = hashid 49 | item["maglink"] = maglink 50 | item["short_link"] = "http://mgnt.me/m/"+createShortLink(maglink) 51 | item["vodlink"] = urllib2.quote(u"/vodplay/magnet:?xt=urn:btih:")+hashid+"/"+urllib2.quote(title) 52 | return render_template("/transfer/indext2m.html",item = item) 53 | except BTFailure: 54 | flash(u"转换失败了...请重试...") 55 | return render_template("/transfer/indext2m.html") 56 | flash(u"出现未知错误,请重试...") 57 | return render_template("/transfer/indext2m.html") 58 | 59 | @app.route('/upload/toplay', methods=['POST']) 60 | def tor2play(): 61 | data = request.files['upload_file'] 62 | if data: 63 | torrent = data.read() 64 | try: 65 | metainfo = bencode.bdecode(torrent) 66 | info = metainfo['info'] 67 | hashid=hashlib.sha1(bencode.bencode(info)).hexdigest() 68 | title=metainfo['info']['name'] 69 | vodlink = urllib2.quote(u"/vodplay/magnet:?xt=urn:btih:")+hashid+"/"+urllib2.quote(title) 70 | return redirect(vodlink) 71 | except BTFailure: 72 | flash(u"转换种子文件失败了...请重试...") 73 | return render_template("/transfer/indext2m.html") 74 | flash(u"出现未知错误,请重试...") 75 | return render_template("/transfer/indext2m.html") -------------------------------------------------------------------------------- /templates/vodplay/play.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% block windowtitle %} 3 | 播放页 4 | {% endblock%} 5 | 6 | {% block container %} 7 | 8 | {% if error %} 9 | 10 | <div class="row"> 11 | <div class="span12"> 12 | <div class="alert alert-error" style="margin-top:10px;"> 13 | <button type="button" class="close" data-dismiss="alert">×</button> 14 | 播放参数不能为空 15 | </div> 16 | </div> 17 | </div> 18 | 19 | {% else %} 20 | <div class="row"> 21 | <div class="span12"> 22 | <h3>MGNT.me 正在为您云点播</h3> 23 | </div> 24 | </div> 25 | <div class="row"> 26 | <div class="span12"> 27 | <p style="word-wrap: break-word;overflow: hidden;"><span class="item_list_name">文件名称:</span>{{title}}</p> 28 | <p>如果您喜欢,记得点击左边的分享告诉你的好友们哦~</p> 29 | <p><span class="label label-info">注意!</span> 如果出现“服务器忙”或302错误的提示,请<a href="/vodplay/{{playid}}/{{title}}">点击这里</a>重新加载。</p> 30 | </div> 31 | </div> 32 | <div class="row"> 33 | <div class="span12"> 34 | <iframe width=970 height=560 frameborder=0 scrolling=auto src="http://www.tvgua.com/play_1.php?url={{playid}}"></iframe> 35 | </div> 36 | </div> 37 | <div class="row"> 38 | <div class="span12"> 39 | <div class="jiathis_share_slide jiathis_share_32x32" id="jiathis_share_slide"> 40 | <div class="jiathis_share_slide_top" id="jiathis_share_title"> 41 | </div> 42 | <div class="jiathis_share_slide_inner"> 43 | <div class="jiathis_style_32x32"> 44 | <a class="jiathis_button_tsina"></a> 45 | <a class="jiathis_button_tqq"></a> 46 | <a class="jiathis_button_renren"></a> 47 | <a class="jiathis_button_qzone"></a> 48 | <a class="jiathis_button_fb"></a> 49 | <a class="jiathis_button_twitter"></a> 50 | <a class="jiathis_button_googleplus"></a> 51 | <a href="http://www.jiathis.com/share" class="jiathis jiathis_txt jtico jtico_jiathis" target="_blank"></a> 52 | <script type="text/javascript"> 53 | var jiathis_config = {data_track_clickback:'true' 54 | ,slide:{ 55 | divid:'container', 56 | pos:'left' 57 | } 58 | }; 59 | </script> 60 | </div> 61 | </div> 62 | </div> 63 | </div> 64 | </div> 65 | <div class="row"> 66 | <div class="span12"> 67 | <h4>此播放页面地址,您可以加入收藏或分享</h4> 68 | <p>本页面永久地址:</p> 69 | <input type="text" class="input-block-level" value="http://mgnt.me/vodplay/{{playid}}/{{title}}"> 70 | <div class="share"> 71 | <div class="jiathis_style_32x32"> 72 | <a class="jiathis_button_tsina"></a> 73 | <a class="jiathis_button_renren"></a> 74 | <a class="jiathis_button_tqq"></a> 75 | <a class="jiathis_button_qzone"></a> 76 | <a class="jiathis_button_fb"></a> 77 | <a class="jiathis_button_twitter"></a> 78 | <a class="jiathis_button_googleplus"></a> 79 | <a class="jiathis_button_tumblr"></a> 80 | <a href="http://www.jiathis.com/share?uid=906036" class="jiathis jiathis_txt jtico jtico_jiathis" target="_blank"></a> 81 | </div> 82 | </div> 83 | <p class="myblock"></p> 84 | </div> 85 | </div> 86 | 87 | <script type="text/javascript" src="http://v3.jiathis.com/code/jia.js?uid=906036" charset="utf-8"></script> 88 | <script type="text/javascript" src="http://v3.jiathis.com/code/jiathis_slide.js" charset="utf-8"></script> 89 | {% endif %} 90 | 91 | {% endblock%} -------------------------------------------------------------------------------- /templates/api/index.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block windowtitle %} 4 | API支持文档 5 | {% endblock%} 6 | 7 | {% block container %} 8 | <div class="row"> 9 | <div class="span12"> 10 | <h3>MGNT.me 开放API支持文档</h3> 11 | <p>请注意,您需要在api请求中包括您的apikey,请查看本页下方说明如何获得apikey</p> 12 | </div> 13 | </div> 14 | 15 | <div class="row"> 16 | <div class="span12"> 17 | <h4>获取搜索结果</h4> 18 | <p>获取某关键字的搜索结果,结果包括如下关键字</p> 19 | <ul> 20 | <li>title(标题)</li> 21 | <li>category(分类)</li> 22 | <li>seeds(种子数)</li> 23 | <li>leechs(下载数)</li> 24 | <li>torrent_size(文件大小)</li> 25 | <li>torrent_hash(文件特征值HASH)</li> 26 | </ul> 27 | <p style="margin-top:10px;">示例</p> 28 | <p style="margin-left:16px;">搜索 spiderman 的搜索结果:</p> 29 | <p style="margin-left:16px;"><a href="http://mgnt.me/api/getresult?key=jyObEa&s=spiderman&page=1" target="_blank">http://mgnt.me/api/getresult?key=jyObEa&s=spiderman&page=1</a></p> 30 | </div> 31 | </div> 32 | 33 | <div class="row"> 34 | <div class="span12"> 35 | <h4>获取某磁力链接的短网址</h4> 36 | <p><span class="label label-info">注意!</span> 您必须在GET方式传入磁力链接时将磁力链接地址进行URL编码,否则无法生成。</p> 37 | <p>例如,可以将以下长磁力连接:</p> 38 | <p style="margin-left:16px;word-wrap: break-word;overflow: hidden;"> 39 | magnet:?xt=urn:btih:0a84d05e9e1b426add4bd1166bfd5b311aee16ed&dn=The Amazing Spiderman (2012) HDCAM x264 AAC UNiQUE&tr=http://121.14.98.151:9090/announce&tr=http://bigtorrent.org:2710/announce&tr=http://coppersurfer.tk:6969/announce&tr=http://tracker1.wasabii.com.tw:6969/announce&tr=http://www.h33t.com:3310/announce&tr=udp://tracker.istole.it:80/announce&tr=udp://tracker.publicbt.com:80/announce&tr=udp://www.h33t.com:3310/announce 40 | </p> 41 | <p>转换为:</p> 42 | <p style="margin-left:16px;"> 43 | http://mgnt.me/m/pzFUVL 44 | </p> 45 | <p style="margin-top:10px;">示例</p> 46 | <p style="margin-left:16px;word-wrap: break-word;overflow: hidden;"> 47 | <a href="http://mgnt.me/api/getshorturl?key=jyObEa&mag=magnet%3A%3Fxt%3Durn%3Abtih%3A0a84d05e9e1b426add4bd1166bfd5b311aee16ed%26dn%3DThe%20Amazing%20Spiderman%20%282012%29%20HDCAM%20x264%20AAC%20UNiQUE%26tr%3Dhttp%3A//121.14.98.151%3A9090/announce%26tr%3Dhttp%3A//bigtorrent.org%3A2710/announce%26tr%3Dhttp%3A//coppersurfer.tk%3A6969/announce%26tr%3Dhttp%3A//tracker1.wasabii.com.tw%3A6969/announce%26tr%3Dhttp%3A//www.h33t.com%3A3310/announce%26tr%3Dudp%3A//tracker.istole.it%3A80/announce%26tr%3Dudp%3A//tracker.publicbt.com%3A80/announce%26tr%3Dudp%3A//www.h33t.com%3A3310/announce 48 | " target="_blank"> 49 | http://mgnt.me/api/getshorturl?key=jyObEa&mag=magnet%3A%3Fxt%3Durn%3Abtih%3A0a84d05e9e1b426add4bd1166bfd5b311aee16ed%26dn%3DThe%20Amazing%20Spiderman%20%282012%29%20HDCAM%20x264%20AAC%20UNiQUE%26tr%3Dhttp%3A//121.14.98.151%3A9090/announce%26tr%3Dhttp%3A//bigtorrent.org%3A2710/announce%26tr%3Dhttp%3A//coppersurfer.tk%3A6969/announce%26tr%3Dhttp%3A//tracker1.wasabii.com.tw%3A6969/announce%26tr%3Dhttp%3A//www.h33t.com%3A3310/announce%26tr%3Dudp%3A//tracker.istole.it%3A80/announce%26tr%3Dudp%3A//tracker.publicbt.com%3A80/announce%26tr%3Dudp%3A//www.h33t.com%3A3310/announce 50 | </a> 51 | </div> 52 | </div> 53 | 54 | 55 | <h4>如何获取apikey</h4> 56 | <p>您必须加本站为友情链接,才能申请到具有永久访问权限的apikey。</p> 57 | <p>添加完毕后,请将页面地址和网站信息发送到 mgnt.me#gmail.com(请将#换成@)</p> 58 | <div class="verticle"></div> 59 | {% endblock%} -------------------------------------------------------------------------------- /templates/m/show.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block windowtitle %} 4 | 磁力链短网址 5 | {% endblock%} 6 | 7 | {% block container %} 8 | 9 | 10 | {% if error %} 11 | 12 | {% with messages = get_flashed_messages() %} 13 | {% if messages %} 14 | <div class="alert alert-error" style="margin-top:10px;"> 15 | <button type="button" class="close" data-dismiss="alert">×</button> 16 | {{error}} 17 | </div> 18 | {% endif %} 19 | {% endwith %} 20 | 21 | {% else %} 22 | 23 | <div class="row"> 24 | <div class="span12"> 25 | <h3>感谢使用 MGNT.me 磁力链短网址服务,以下是您的链接信息:</h3> 26 | </div> 27 | </div> 28 | <div class="row" style="height:46px;"> 29 | <div class="span12"> 30 | <div class="jiathis_style_32x32"> 31 | <a class="jiathis_button_tsina"></a> 32 | <a class="jiathis_button_renren"></a> 33 | <a class="jiathis_button_tqq"></a> 34 | <a class="jiathis_button_qzone"></a> 35 | <a class="jiathis_button_fb"></a> 36 | <a class="jiathis_button_twitter"></a> 37 | <a class="jiathis_button_googleplus"></a> 38 | <a class="jiathis_button_tumblr"></a> 39 | <a href="http://www.jiathis.com/share?uid=906036" class="jiathis jiathis_txt jtico jtico_jiathis" target="_blank"></a> 40 | </div> 41 | </div> 42 | </div> 43 | <div class="row"> 44 | <div class="span12"> 45 | <div class="well" style="background-color:white;"> 46 | <div class="row"> 47 | <div class="span12"> 48 | <div> 49 | </div> 50 | </div> 51 | </div> 52 | <p><small>磁力特征值:{{item.hashid}}</small></p> 53 | <p> 54 | <span class="label label-success"><i class="icon-magnet icon-white"></i> 本磁力链短网址:</span> 55 | <input type="text" style="width:50%;margin:-2px 0 0 2px;color:black;" value="{{item.short_link}}" id="short_link" onMouseOver="SelectAll('short_link')"> 56 | </p> 57 | <p><span class="label label-success"><i class="icon-magnet icon-white"></i> 原磁力链接地址:</span><small>(可直接复制到相应客户端下载,或者点击下面的下载按钮):</small></p> 58 | <textarea rows="8" id="maglink" onMouseOver="SelectAll('maglink')" style="width:100%">{{item.maglink}}</textarea> 59 | <h4>您还可以云播放这个文件:</h4> 60 | <div> 61 | <div style="margin:6px 0;"> 62 | <div class="span12"> 63 | </div> 64 | </div> 65 | <a href="{{item.maglink}}" class="btn btn-danger"><i class="icon-magnet icon-white"></i> 磁力链接下载 </a> 66 | <a href="{{item.vodlink}}" class="btn btn-danger" target="_blank"><i class="icon-play icon-white"></i> 云播放(Beta) </a> 67 | 68 | </div> 69 | <h4>或下载这个文件:</h4> 70 | <div> 71 | <a href="{{item.maglink}}" class="btn btn-primary"><i class="icon-download-alt"></i> 迅雷下载 </a> 72 | <a href="{{item.maglink}}" class="btn btn-success"><i class="icon-download-alt"></i> QQ旋风下载 </a> 73 | <a href="http://torrage.com/torrent/{{item.hashid | upper}}.torrent" class="btn btn-warning"><i class="icon-download-alt"></i> 下载BT种子 </a> 74 | </div> 75 | </div> 76 | </div> 77 | </div> 78 | 79 | <script type="text/javascript"> 80 | function SelectAll(id) 81 | { 82 | document.getElementById(id).focus(); 83 | document.getElementById(id).select(); 84 | } 85 | </script> 86 | <script type="text/javascript"> 87 | var jiathis_config = {data_track_clickback:'true'}; 88 | </script> 89 | <script type="text/javascript" src="http://v3.jiathis.com/code/jia.js?uid=906036" charset="utf-8"></script> 90 | 91 | {% endif %} 92 | 93 | {% endblock%} -------------------------------------------------------------------------------- /static/js/bootstrap-fileupload.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Bootstrap.js by @mdo and @fat, extended by @ArnoldDaniels. 3 | * plugins: bootstrap-fileupload.js 4 | * Copyright 2012 Twitter, Inc. 5 | * http://www.apache.org/licenses/LICENSE-2.0.txt 6 | */ 7 | !function(a){var b=function(b,c){this.$element=a(b),this.type=this.$element.data("uploadtype")||(this.$element.find(".thumbnail").length>0?"image":"file"),this.$input=this.$element.find(":file");if(this.$input.length===0)return;this.name=this.$input.attr("name")||c.name,this.$hidden=this.$element.find('input[type=hidden][name="'+this.name+'"]'),this.$hidden.length===0&&(this.$hidden=a('<input type="hidden" />'),this.$element.prepend(this.$hidden)),this.$preview=this.$element.find(".fileupload-preview");var d=this.$preview.css("height");this.$preview.css("display")!="inline"&&d!="0px"&&d!="none"&&this.$preview.css("line-height",d),this.original={exists:this.$element.hasClass("fileupload-exists"),preview:this.$preview.html(),hiddenVal:this.$hidden.val()},this.$remove=this.$element.find('[data-dismiss="fileupload"]'),this.$element.find('[data-trigger="fileupload"]').on("click.fileupload",a.proxy(this.trigger,this)),this.listen()};b.prototype={listen:function(){this.$input.on("change.fileupload",a.proxy(this.change,this)),a(this.$input[0].form).on("reset.fileupload",a.proxy(this.reset,this)),this.$remove&&this.$remove.on("click.fileupload",a.proxy(this.clear,this))},change:function(a,b){var c=a.target.files!==undefined?a.target.files[0]:a.target.value?{name:a.target.value.replace(/^.+\\/,"")}:null;if(b==="clear")return;if(!c){this.clear();return}this.$hidden.val(""),this.$hidden.attr("name",""),this.$input.attr("name",this.name);if(this.type==="image"&&this.$preview.length>0&&(typeof c.type!="undefined"?c.type.match("image.*"):c.name.match("\\.(gif|png|jpe?g)$"))&&typeof FileReader!="undefined"){var d=new FileReader,e=this.$preview,f=this.$element;d.onload=function(a){e.html('<img src="'+a.target.result+'" '+(e.css("max-height")!="none"?'style="max-height: '+e.css("max-height")+';"':"")+" />"),f.addClass("fileupload-exists").removeClass("fileupload-new")},d.readAsDataURL(c)}else this.$preview.text(c.name),this.$element.addClass("fileupload-exists").removeClass("fileupload-new")},clear:function(b){this.$hidden.val(""),this.$hidden.attr("name",this.name),this.$input.attr("name","");if(a.browser.msie){var c=this.$input.clone(!0);this.$input.after(c),this.$input.remove(),this.$input=c}else this.$input.val("");this.$preview.html(""),this.$element.addClass("fileupload-new").removeClass("fileupload-exists"),b&&(this.$input.trigger("change",["clear"]),b.preventDefault())},reset:function(a){this.clear(),this.$hidden.val(this.original.hiddenVal),this.$preview.html(this.original.preview),this.original.exists?this.$element.addClass("fileupload-exists").removeClass("fileupload-new"):this.$element.addClass("fileupload-new").removeClass("fileupload-exists")},trigger:function(a){this.$input.trigger("click"),a.preventDefault()}},a.fn.fileupload=function(c){return this.each(function(){var d=a(this),e=d.data("fileupload");e||d.data("fileupload",e=new b(this,c)),typeof c=="string"&&e[c]()})},a.fn.fileupload.Constructor=b,a(function(){a("body").on("click.fileupload.data-api",'[data-provides="fileupload"]',function(b){var c=a(this);if(c.data("fileupload"))return;c.fileupload(c.data());var d=a(b.target).is("[data-dismiss=fileupload],[data-trigger=fileupload]")?a(b.target):a(b.target).parents("[data-dismiss=fileupload],[data-trigger=fileupload]").first();d.length>0&&(d.trigger("click.fileupload"),b.preventDefault())})})}(window.jQuery) -------------------------------------------------------------------------------- /templates/index.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | 4 | 5 | {% block navbar %} 6 | <div class="navbar navbar-fixed-top"> 7 | <div class="navbar-inner"> 8 | <div class="container"> 9 | <a class="brand" href="/" style="color:black;">MGNT.me</a> 10 | <div class="nav-collapse"> 11 | <ul class="nav"> 12 | <li><a href="/vodplay">云播放</a></li> 13 | <li><a href="/m">磁力短网址</a></li> 14 | <li class="dropdown"> 15 | <a href="#" class="dropdown-toggle" data-toggle="dropdown">磁力转换 <b class="caret"></b></a> 16 | <ul class="dropdown-menu"> 17 | <li><a href="/transfer/t2m">Torrent转磁力链接</a></li> 18 | <li><a href="/transfer/m2t">磁力链接转Torrent</a></li> 19 | </ul> 20 | </li> 21 | <li><a href="/page/about">关于</a></li> 22 | <li><a href="/api">API</a></li> 23 | <li><a href="/page/faq">FAQ</a></li> 24 | </ul> 25 | </div> 26 | </div> 27 | </div> 28 | </div> 29 | {% endblock%} 30 | 31 | {% block container %} 32 | <div style="text-align:center;margin-top:70px;margin-bottom:80px;"> 33 | <img src="{{url_for('static', filename='images/logo.png')}}" alt="logo" /> 34 | <p style="margin:20px;">我们致力于建造最大的磁力链资源搜索引擎</p> 35 | 36 | <form class="input-append" action="/search/s" method="get" id="form_search"> 37 | <div class="input-append"> 38 | <input type="text" class="span6" value="{{kw}}" name="kw"> 39 | <input type="hidden" value="1" name="page"> 40 | <a type="submit" class="btn" href="javascript:submitform_search();">搜索磁力资源</a> 41 | </div> 42 | <script type="text/javascript"> 43 | function submitform_search(){ 44 | document.getElementById('form_search').submit(); 45 | } 46 | </script> 47 | </form> 48 | {% with messages = get_flashed_messages() %} 49 | {% if messages %} 50 | <div class="alert alert-error" style="margin-top:10px;"> 51 | <button type="button" class="close" data-dismiss="alert">×</button> 52 | {% for message in messages %} 53 | {{ message }} 54 | {% endfor %} 55 | </div> 56 | {% endif %} 57 | {% endwith %} 58 | <p style="margin:100px 0 0 0;">目前索引资源数:4672691</p> 59 | <div class="row" style="height:38px;"> 60 | <div class="span12" style="padding:20px 0 10px 310px;"> 61 | <div class="jiathis_style_32x32"> 62 | <a class="jiathis_button_tsina"></a> 63 | <a class="jiathis_button_renren"></a> 64 | <a class="jiathis_button_tqq"></a> 65 | <a class="jiathis_button_qzone"></a> 66 | <a class="jiathis_button_fb"></a> 67 | <a class="jiathis_button_twitter"></a> 68 | <a class="jiathis_button_googleplus"></a> 69 | <a class="jiathis_button_tumblr"></a> 70 | <a href="http://www.jiathis.com/share?uid=906036" class="jiathis jiathis_txt jtico jtico_jiathis" target="_blank"></a> 71 | </div> 72 | </div> 73 | </div> 74 | </div> 75 | {% endblock%} 76 | 77 | {% block footer %} 78 | <footer class="footer navbar-fixed-bottom" style="text-align: center;padding: 10px 0 0 0;margin-top: 70px;border-top: 1px solid #E5E5E5;background-color:white;"> 79 | <div class="container"> 80 | <small>@2013</small> 81 | <p><small>本站所有资源信息均从互联网搜索而来,本站不对显示的内容承担责任。本站也不保存有任何可直接下载的文件。</small></p> 82 | </div> 83 | </footer> 84 | {% endblock%} 85 | 86 | {% block footjs %} 87 | <script type="text/javascript"> 88 | var jiathis_config = {data_track_clickback:'true'}; 89 | </script> 90 | <script type="text/javascript" src="http://v3.jiathis.com/code/jia.js?uid=906036" charset="utf-8"></script> 91 | {% endblock %} 92 | 93 | -------------------------------------------------------------------------------- /templates/m/index.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block windowtitle %} 4 | 磁力链短网址 5 | {% endblock%} 6 | 7 | 8 | {% block meta %} 9 | {% if item %} 10 | <meta http-equiv="refresh" content="2;url=/m/{{item.short_link}}"> 11 | {% endif %} 12 | {% endblock %} 13 | 14 | 15 | {% block container %} 16 | <div class="row"> 17 | <div class="span12"> 18 | <h3>MGNT.me 磁力链短网址</h3> 19 | </div> 20 | </div> 21 | <div class="row" style="height:38px;"> 22 | <div class="span12"> 23 | <div class="jiathis_style_32x32"> 24 | <a class="jiathis_button_tsina"></a> 25 | <a class="jiathis_button_renren"></a> 26 | <a class="jiathis_button_tqq"></a> 27 | <a class="jiathis_button_qzone"></a> 28 | <a class="jiathis_button_fb"></a> 29 | <a class="jiathis_button_twitter"></a> 30 | <a class="jiathis_button_googleplus"></a> 31 | <a class="jiathis_button_tumblr"></a> 32 | <a href="http://www.jiathis.com/share?uid=906036" class="jiathis jiathis_txt jtico jtico_jiathis" target="_blank"></a> 33 | </div> 34 | </div> 35 | </div> 36 | <hr> 37 | {% with messages = get_flashed_messages() %} 38 | {% if messages %} 39 | <div class="alert alert-error" style="margin-top:10px;"> 40 | <button type="button" class="close" data-dismiss="alert">×</button> 41 | {% for message in messages %} 42 | {{ message }} 43 | {% endfor %} 44 | </div> 45 | {% endif %} 46 | {% endwith %} 47 | 48 | 49 | {% if item %} 50 | <div class="row"> 51 | <div class="span12"> 52 | <div class="alert alert-success" style="margin-top:10px;text-align:center;"> 53 | <h4>恭喜!生成成功!2秒钟后将跳转到结果网址....</h4> 54 | <div> 55 | <img src="{{url_for('static', filename='images/loading.gif')}}" alt="loading" /> 56 | </div> 57 | <p class="myblock;"></p> 58 | <p>如果2秒钟之后还没有跳转,请<a href="/m/{{item.short_link}}" style="color:blue;">点击这里继续</a>。</p> 59 | </div> 60 | </div> 61 | </div> 62 | {% endif %} 63 | 64 | <div class="row"> 65 | <div class="span12"> 66 | <p>请输入磁力链接的完整地址,然后点击生成磁力短网址:</p> 67 | <div style="margin:30px auto;"> 68 | <form class="form-horizontal" method="post" action="/m/create" id="urlform"> 69 | <div class="control-group"> 70 | <input type="text" class="input-block-level" placeholder="请输入磁力资源地址" name="magnet" id="addressinput"> 71 | </div> 72 | <div class="control-group"> 73 | <a type="submit" class="btn" href="javascript:submitform_url();" >点击生成短地址</a> 74 | </div> 75 | <script type="text/javascript"> 76 | function submitform_url(){ 77 | if (document.getElementById('addressinput').value == "") 78 | alert("磁力资源地址不能为空"); 79 | else 80 | document.getElementById('urlform').submit(); 81 | } 82 | </script> 83 | </form> 84 | </div> 85 | </div> 86 | </div> 87 | <div class="row"> 88 | <div class="span12"> 89 | <h4>怎样玩转磁力短网址?</h4> 90 | <p>你可曾因为那么那么那么长的磁力链接而烦恼?你都不好意思给好友发过去有没有!有了短网址服务,您就可以将那么那么那么长的磁力链接轻松地保存、分享了~自己看着也舒心哦</p> 91 | <p>想给好友传种子文件...先利用<a href="/transfer/t2m">Torrent转磁力链接</a>服务把种子转成磁力链接,再发送给好友磁力短网址,摆脱传文件的烦恼~</p> 92 | <p>嘘...宅男们有福了,不解释..</p> 93 | </div> 94 | </div> 95 | 96 | 97 | 98 | 99 | <script type="text/javascript"> 100 | function SelectAll(id) 101 | { 102 | document.getElementById(id).focus(); 103 | document.getElementById(id).select(); 104 | } 105 | </script> 106 | 107 | {% if not item %} 108 | <script type="text/javascript"> 109 | var jiathis_config = {data_track_clickback:'true'}; 110 | </script> 111 | <script type="text/javascript" src="http://v3.jiathis.com/code/jia.js?uid=906036" charset="utf-8"></script> 112 | {% endif %} 113 | {% endblock%} -------------------------------------------------------------------------------- /templates/detail/single_result.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block windowtitle %} 4 | {% if not error %} 5 | {{item.title}} 6 | {% else %} 7 | 出错了 8 | {% endif %} 9 | {% endblock%} 10 | 11 | {% block container %} 12 | 13 | {% if error %} 14 | <div class="row"> 15 | <div class="span12"> 16 | <div class="alert alert-error" style="margin-top:10px;"> 17 | <button type="button" class="close" data-dismiss="alert">×</button> 18 | 您好像没有提供资源信息,玛格无法为您显示结果,点击<a href="/">返回主页</a>。 19 | </div> 20 | </div> 21 | </div> 22 | {% else %} 23 | <div class="row"> 24 | <div class="span12"> 25 | <h3>{{item.title}}</h3> 26 | </div> 27 | </div> 28 | <div class="row" style="height:38px;"> 29 | <div class="span12"> 30 | <div class="jiathis_style_32x32"> 31 | <a class="jiathis_button_tsina"></a> 32 | <a class="jiathis_button_renren"></a> 33 | <a class="jiathis_button_tqq"></a> 34 | <a class="jiathis_button_qzone"></a> 35 | <a class="jiathis_button_fb"></a> 36 | <a class="jiathis_button_twitter"></a> 37 | <a class="jiathis_button_googleplus"></a> 38 | <a class="jiathis_button_tumblr"></a> 39 | <a href="http://www.jiathis.com/share?uid=906036" class="jiathis jiathis_txt jtico jtico_jiathis" target="_blank"></a> 40 | </div> 41 | </div> 42 | </div> 43 | <hr> 44 | <div class="row"> 45 | <div class="span12"> 46 | <h4>资源磁力信息</h4> 47 | <p><small>文件大小:{{item.size}}</small><br> 48 | <small>种子数/下载数:{{item.seeds}} / {{item.leechs}}</small><br> 49 | <small>特征码:{{item.hashid}}</small><br></p> 50 | <p><span class="label label-success"><i class="icon-magnet icon-white"></i> 磁力链接地址</span><small>(可直接复制到相应客户端下载,或者点击下面的下载按钮):</small></p> 51 | <textarea rows="6" id="maglink" onMouseOver="SelectAll('maglink')" style="width:100%">{{item.maglink}}</textarea> 52 | 53 | </div> 54 | </div> 55 | <div class="row"> 56 | <div class="span5"> 57 | <h4>下载信息</h4> 58 | <div> 59 | <a href="{{item.maglink}}" class="btn btn-danger"><i class="icon-magnet icon-white"></i> 磁力链接下载 </a> 60 | <a href="{{item.vodlink}}" class="btn btn-danger" target="_blank"><i class="icon-play icon-white"></i> 云播放(Beta) </a> 61 | </div> 62 | <p class="myblock"></p> 63 | <div> 64 | <a href="{{item.maglink}}" class="btn btn-primary"><i class="icon-download-alt"></i> 迅雷下载 </a> 65 | <a href="{{item.maglink}}" class="btn btn-success"><i class="icon-download-alt"></i> QQ旋风下载 </a> 66 | <a href="http://torrage.com/torrent/{{item.hashid | upper}}.torrent" class="btn btn-warning"><i class="icon-download-alt"></i> 下载BT种子 </a> 67 | </div> 68 | </div> 69 | <div class="span7"> 70 | <div style="margin-top:40px;width:470px;height:62px;"> 71 | </div> 72 | </div> 73 | </div> 74 | <div class="row" style="padding-top:10px;"> 75 | <div class="span12"> 76 | <h4>页面信息</h4> 77 | <div class="input-prepend"> 78 | <span class="add-on">本页永久地址:</span> 79 | <input class="input-xxlarge" id="prependedInput" type="text" style="width:88%" value="{{item.perm_link}}"> 80 | </div> 81 | <div class="input-prepend"> 82 | <span class="add-on">本资源短网址:</span> 83 | <input class="input-xxlarge" id="prependedInput" type="text" style="width:88%" value="{{item.short_link}}"> 84 | </div> 85 | <p class="myblock"></p> 86 | </div> 87 | </div> 88 | <script type="text/javascript"> 89 | function SelectAll(id) 90 | { 91 | document.getElementById(id).focus(); 92 | document.getElementById(id).select(); 93 | } 94 | </script> 95 | <script type="text/javascript"> 96 | var jiathis_config = {data_track_clickback:'true'}; 97 | </script> 98 | <script type="text/javascript" src="http://v3.jiathis.com/code/jia.js?uid=906036" charset="utf-8"></script> 99 | {% endif %} 100 | 101 | {% endblock%} -------------------------------------------------------------------------------- /api/views.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from flask import Blueprint 4 | from flask import render_template,request 5 | import re,urllib2 6 | import json 7 | from utils import createShortLink,getConn 8 | 9 | 10 | app = Blueprint('api', __name__) 11 | 12 | @app.route('/', methods=['GET']) 13 | @app.route('', methods=['GET']) 14 | def api(): 15 | return render_template("/api/index.html") 16 | 17 | # http://mgnt.me/api/getresult?key=jyObEa&s=spiderman&page=1 18 | @app.route('/getresult/', methods=['GET']) 19 | @app.route('/getresult', methods=['GET']) 20 | def getresult(): 21 | apikey = request.args.get('key', '').lower() 22 | searchword = request.args.get('s', '').lower() 23 | page = request.args.get('page', '1') 24 | if apikey == "": 25 | return json.dumps([u"Please provide an apikey to access mgnt.me apis"]) 26 | if apikey == "jyobea" and searchword != "spiderman": 27 | return json.dumps([u"This is a demo api, if you want full access, please contact mgnt.me to get an apikey."]) 28 | if not checkapikey(apikey): 29 | return json.dumps([u"Invalid apikey, please contact mgnt.me"]) 30 | else: 31 | addtimes(apikey) 32 | url = "http://torrentproject.com/?s="+searchword+"&start="+str(int(page)-1)+"&orderby=best&out=json" 33 | url=url.encode('utf-8') 34 | url=urllib2.unquote(url) 35 | f = urllib2.urlopen(url) 36 | json_string = f.read() 37 | return json_string 38 | 39 | # http://mgnt.me/api/getshorturl?key=jyObEa&mag=magnet%3A%3Fxt%3Durn%3Abtih%3A0a84d05e9e1b426add4bd1166bfd5b311aee16ed%26dn%3DThe%20Amazing%20Spiderman%20%282012%29%20HDCAM%20x264%20AAC%20UNiQUE%26tr%3Dhttp%3A//121.14.98.151%3A9090/announce%26tr%3Dhttp%3A//bigtorrent.org%3A2710/announce%26tr%3Dhttp%3A//coppersurfer.tk%3A6969/announce%26tr%3Dhttp%3A//tracker1.wasabii.com.tw%3A6969/announce%26tr%3Dhttp%3A//www.h33t.com%3A3310/announce%26tr%3Dudp%3A//tracker.istole.it%3A80/announce%26tr%3Dudp%3A//tracker.publicbt.com%3A80/announce%26tr%3Dudp%3A//www.h33t.com%3A3310/announce 40 | # original: 41 | # magnet:?xt=urn:btih:0a84d05e9e1b426add4bd1166bfd5b311aee16ed&dn=The Amazing Spiderman (2012) HDCAM x264 AAC UNiQUE&tr=http://121.14.98.151:9090/announce&tr=http://bigtorrent.org:2710/announce&tr=http://coppersurfer.tk:6969/announce&tr=http://tracker1.wasabii.com.tw:6969/announce&tr=http://www.h33t.com:3310/announce&tr=udp://tracker.istole.it:80/announce&tr=udp://tracker.publicbt.com:80/announce&tr=udp://www.h33t.com:3310/announce 42 | @app.route('/getshorturl/', methods=['GET']) 43 | @app.route('/getshorturl', methods=['GET']) 44 | def getshorturl(): 45 | apikey = request.args.get('key', '').lower() 46 | maglink = urllib2.unquote(request.args.get('mag', '').lower()) 47 | if apikey == "": 48 | return json.dumps([u"Please provide an apikey to access mgnt.me apis"]) 49 | if apikey == "jyobea" and maglink != "magnet:?xt=urn:btih:0a84d05e9e1b426add4bd1166bfd5b311aee16ed&dn=The Amazing Spiderman (2012) HDCAM x264 AAC UNiQUE&tr=http://121.14.98.151:9090/announce&tr=http://bigtorrent.org:2710/announce&tr=http://coppersurfer.tk:6969/announce&tr=http://tracker1.wasabii.com.tw:6969/announce&tr=http://www.h33t.com:3310/announce&tr=udp://tracker.istole.it:80/announce&tr=udp://tracker.publicbt.com:80/announce&tr=udp://www.h33t.com:3310/announce".lower(): 50 | return json.dumps([u"This is a demo api, if you want full access, please contact mgnt.me to get an apikey."]) 51 | if not checkapikey(apikey): 52 | return json.dumps([u"Invalid apikey, please contact mgnt.me"]) 53 | else: 54 | addtimes(apikey) 55 | regex=ur"magnet:\?.*" 56 | if not re.search(regex, maglink): 57 | return json.dumps([u"Invalid magnet link."]) 58 | short_link = createShortLink(maglink) 59 | return json.dumps({"short_url":"http://mgnt.me/m/"+short_link}) 60 | 61 | 62 | def checkapikey(apikey): 63 | conn = getConn() 64 | conn.query("""select apikey from mgnt_apikey where apikey='%s';""" % apikey) 65 | result = conn.store_result().fetch_row() 66 | if result == (): 67 | return False 68 | else: 69 | return True 70 | 71 | def addtimes(apikey): 72 | conn = getConn() 73 | conn.query("""update mgnt_apikey set times=times+1 where apikey='%s'""" % apikey) 74 | 75 | 76 | -------------------------------------------------------------------------------- /templates/base.html: -------------------------------------------------------------------------------- 1 | <!DOCTYPE html> 2 | <html> 3 | <head> 4 | <title>{% block windowtitle %}{{ config.SITE_TITLE }}{% endblock%} 5 | 6 | 7 | {% block meta %}{% endblock %} 8 | 9 | 10 | 14 | 15 | 16 | {% block navbar %} 17 | 52 | {% endblock %} 53 |
54 | 55 | {% block container %}{% endblock%} 56 |
57 | 58 | 59 | 60 | 61 | {% block footer %} 62 |
63 | 75 |
76 | 83 |

@2013

84 |

本站所有资源信息均从互联网搜索而来,本站不对显示的内容承担责任。本站也不保存有任何可直接下载的文件。

85 |
86 |
87 | {% endblock%} 88 | {% block footjs %}{% endblock%} 89 | 102 | 106 | 107 | -------------------------------------------------------------------------------- /templates/transfer/indext2m.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block windowtitle %} 4 | Torrent转磁力链接 5 | {% endblock%} 6 | {% block container %} 7 |
8 |
9 |

Torrent转磁力链接

10 |
11 |
12 |
13 |
14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 |
26 |
27 |
28 | {% with messages = get_flashed_messages() %} 29 | {% if messages %} 30 |
31 | 32 | {% for message in messages %} 33 | {{ message }} 34 | {% endfor %} 35 |
36 | {% endif %} 37 | {% endwith %} 38 | 39 | {% if item %} 40 |
41 |
42 |
43 |

44 |

恭喜!转换成功!您可以将它复制到相应软件下载或与好友分享了~

45 |

磁力特征值:{{item.hashid}}

46 | 47 |

磁力链接地址(可直接复制到相应客户端下载,或者点击下面的下载按钮):

48 | 49 |

50 | 我们还为您生成了本磁力链的短网址: 51 | 52 | 点击打开 53 |

54 |

您还可以云播放这个文件:

55 |

56 | 61 |

62 |

或下载这个文件:

63 |

64 | 69 |

70 |
71 |
72 |
73 | {% endif %} 74 | 75 |
76 |
77 |

请选择种子文件,然后点击转换按钮稍等片刻即可得到结果。本站不保存您的种子文件,分析完后将立即删除。

78 |
79 |
80 |
81 |
82 | 83 |
84 | 85 | 选择种子文件 86 | 重新选择 87 | 88 | 89 | 移除 90 |
91 |
92 | 95 | 128 |
129 |
130 |
131 | 132 | 133 | 134 | 135 | 136 | 139 | 140 | {% endblock%} 141 | 142 | {% block footjs %}{% endblock%} -------------------------------------------------------------------------------- /templates/vodplay/index.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% block windowtitle %} 3 | 欢迎使用云播放 4 | {% endblock%} 5 | 6 | {% block container %} 7 |
8 |
9 |

欢迎使用 MGNT.me 云点播系统

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 | {% with messages = get_flashed_messages() %} 37 | {% if messages %} 38 |
39 | 40 | {% for message in messages %} 41 | {{ message }} 42 | {% endfor %} 43 |
44 | {% endif %} 45 | {% endwith %} 46 | 47 |
48 |
49 |
50 | 55 |
56 |
57 |

请输入资源地址,支持ed2k、magnet、thunder等开头的地址:

58 |
59 |
60 |
61 | 62 |
63 | 66 | 71 |
72 |
73 |
74 |
75 |

您可以上传视频的种子文件,然后点击播放,便可进行在线云播放。

76 |
77 |
78 |
79 |
80 |
81 | 82 |
83 | 84 | 选择种子文件 85 | 重新选择 86 | 87 | 88 | 移除 89 |
90 |
91 | 94 | 119 |
120 |
121 |
122 |
123 |

请输入种子资源的特征码(HASH值):

124 |
125 |
126 |
127 | 128 |
129 | 132 | 137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 | 145 | 146 | 147 | 150 | 151 | {% endblock%} 152 | 153 | {% block footjs %}{% endblock%} 154 | 155 | -------------------------------------------------------------------------------- /transfer/bencode.py: -------------------------------------------------------------------------------- 1 | # Written by Petru Paler 2 | # see LICENSE.txt for license information 3 | 4 | def decode_int(x, f): 5 | f += 1 6 | newf = x.index('e', f) 7 | try: 8 | n = int(x[f:newf]) 9 | except (OverflowError, ValueError): 10 | n = long(x[f:newf]) 11 | if x[f] == '-': 12 | if x[f + 1] == '0': 13 | raise ValueError 14 | elif x[f] == '0' and newf != f+1: 15 | raise ValueError 16 | return (n, newf+1) 17 | 18 | def decode_string(x, f): 19 | colon = x.index(':', f) 20 | try: 21 | n = int(x[f:colon]) 22 | except (OverflowError, ValueError): 23 | n = long(x[f:colon]) 24 | if x[f] == '0' and colon != f+1: 25 | raise ValueError 26 | colon += 1 27 | return (x[colon:colon+n], colon+n) 28 | 29 | def decode_list(x, f): 30 | r, f = [], f+1 31 | while x[f] != 'e': 32 | v, f = decode_func[x[f]](x, f) 33 | r.append(v) 34 | return (r, f + 1) 35 | 36 | def decode_dict(x, f): 37 | r, f = {}, f+1 38 | lastkey = None 39 | while x[f] != 'e': 40 | k, f = decode_string(x, f) 41 | if lastkey >= k: 42 | raise ValueError 43 | lastkey = k 44 | r[k], f = decode_func[x[f]](x, f) 45 | return (r, f + 1) 46 | 47 | decode_func = {} 48 | decode_func['l'] = decode_list 49 | decode_func['d'] = decode_dict 50 | decode_func['i'] = decode_int 51 | decode_func['0'] = decode_string 52 | decode_func['1'] = decode_string 53 | decode_func['2'] = decode_string 54 | decode_func['3'] = decode_string 55 | decode_func['4'] = decode_string 56 | decode_func['5'] = decode_string 57 | decode_func['6'] = decode_string 58 | decode_func['7'] = decode_string 59 | decode_func['8'] = decode_string 60 | decode_func['9'] = decode_string 61 | 62 | def bdecode(x): 63 | try: 64 | r, l = decode_func[x[0]](x, 0) 65 | except (IndexError, KeyError): 66 | raise ValueError 67 | if l != len(x): 68 | raise ValueError 69 | return r 70 | 71 | def test_bdecode(): 72 | try: 73 | bdecode('0:0:') 74 | assert 0 75 | except ValueError: 76 | pass 77 | try: 78 | bdecode('ie') 79 | assert 0 80 | except ValueError: 81 | pass 82 | try: 83 | bdecode('i341foo382e') 84 | assert 0 85 | except ValueError: 86 | pass 87 | assert bdecode('i4e') == 4L 88 | assert bdecode('i0e') == 0L 89 | assert bdecode('i123456789e') == 123456789L 90 | assert bdecode('i-10e') == -10L 91 | try: 92 | bdecode('i-0e') 93 | assert 0 94 | except ValueError: 95 | pass 96 | try: 97 | bdecode('i123') 98 | assert 0 99 | except ValueError: 100 | pass 101 | try: 102 | bdecode('') 103 | assert 0 104 | except ValueError: 105 | pass 106 | try: 107 | bdecode('i6easd') 108 | assert 0 109 | except ValueError: 110 | pass 111 | try: 112 | bdecode('35208734823ljdahflajhdf') 113 | assert 0 114 | except ValueError: 115 | pass 116 | try: 117 | bdecode('2:abfdjslhfld') 118 | assert 0 119 | except ValueError: 120 | pass 121 | assert bdecode('0:') == '' 122 | assert bdecode('3:abc') == 'abc' 123 | assert bdecode('10:1234567890') == '1234567890' 124 | try: 125 | bdecode('02:xy') 126 | assert 0 127 | except ValueError: 128 | pass 129 | try: 130 | bdecode('l') 131 | assert 0 132 | except ValueError: 133 | pass 134 | assert bdecode('le') == [] 135 | try: 136 | bdecode('leanfdldjfh') 137 | assert 0 138 | except ValueError: 139 | pass 140 | assert bdecode('l0:0:0:e') == ['', '', ''] 141 | try: 142 | bdecode('relwjhrlewjh') 143 | assert 0 144 | except ValueError: 145 | pass 146 | assert bdecode('li1ei2ei3ee') == [1, 2, 3] 147 | assert bdecode('l3:asd2:xye') == ['asd', 'xy'] 148 | assert bdecode('ll5:Alice3:Bobeli2ei3eee') == [['Alice', 'Bob'], [2, 3]] 149 | try: 150 | bdecode('d') 151 | assert 0 152 | except ValueError: 153 | pass 154 | try: 155 | bdecode('defoobar') 156 | assert 0 157 | except ValueError: 158 | pass 159 | assert bdecode('de') == {} 160 | assert bdecode('d3:agei25e4:eyes4:bluee') == {'age': 25, 'eyes': 'blue'} 161 | assert bdecode('d8:spam.mp3d6:author5:Alice6:lengthi100000eee') == {'spam.mp3': {'author': 'Alice', 'length': 100000}} 162 | try: 163 | bdecode('d3:fooe') 164 | assert 0 165 | except ValueError: 166 | pass 167 | try: 168 | bdecode('di1e0:e') 169 | assert 0 170 | except ValueError: 171 | pass 172 | try: 173 | bdecode('d1:b0:1:a0:e') 174 | assert 0 175 | except ValueError: 176 | pass 177 | try: 178 | bdecode('d1:a0:1:a0:e') 179 | assert 0 180 | except ValueError: 181 | pass 182 | try: 183 | bdecode('i03e') 184 | assert 0 185 | except ValueError: 186 | pass 187 | try: 188 | bdecode('l01:ae') 189 | assert 0 190 | except ValueError: 191 | pass 192 | try: 193 | bdecode('9999:x') 194 | assert 0 195 | except ValueError: 196 | pass 197 | try: 198 | bdecode('l0:') 199 | assert 0 200 | except ValueError: 201 | pass 202 | try: 203 | bdecode('d0:0:') 204 | assert 0 205 | except ValueError: 206 | pass 207 | try: 208 | bdecode('d0:') 209 | assert 0 210 | except ValueError: 211 | pass 212 | try: 213 | bdecode('00:') 214 | assert 0 215 | except ValueError: 216 | pass 217 | try: 218 | bdecode('l-3:e') 219 | assert 0 220 | except ValueError: 221 | pass 222 | try: 223 | bdecode('i-03e') 224 | assert 0 225 | except ValueError: 226 | pass 227 | bdecode('d0:i3ee') 228 | 229 | from types import StringType, IntType, LongType, DictType, ListType, TupleType 230 | 231 | class Bencached(object): 232 | __slots__ = ['bencoded'] 233 | 234 | def __init__(self, s): 235 | self.bencoded = s 236 | 237 | def encode_bencached(x,r): 238 | r.append(x.bencoded) 239 | 240 | def encode_int(x, r): 241 | r.extend(('i', str(x), 'e')) 242 | 243 | def encode_string(x, r): 244 | r.extend((str(len(x)), ':', x)) 245 | 246 | def encode_list(x, r): 247 | r.append('l') 248 | for i in x: 249 | encode_func[type(i)](i, r) 250 | r.append('e') 251 | 252 | def encode_dict(x,r): 253 | r.append('d') 254 | ilist = x.items() 255 | ilist.sort() 256 | for k, v in ilist: 257 | r.extend((str(len(k)), ':', k)) 258 | encode_func[type(v)](v, r) 259 | r.append('e') 260 | 261 | encode_func = {} 262 | encode_func[type(Bencached(0))] = encode_bencached 263 | encode_func[IntType] = encode_int 264 | encode_func[LongType] = encode_int 265 | encode_func[StringType] = encode_string 266 | encode_func[ListType] = encode_list 267 | encode_func[TupleType] = encode_list 268 | encode_func[DictType] = encode_dict 269 | 270 | try: 271 | from types import BooleanType 272 | encode_func[BooleanType] = encode_int 273 | except ImportError: 274 | pass 275 | 276 | def bencode(x): 277 | r = [] 278 | encode_func[type(x)](x, r) 279 | return ''.join(r) 280 | 281 | def test_bencode(): 282 | assert bencode(4) == 'i4e' 283 | assert bencode(0) == 'i0e' 284 | assert bencode(-10) == 'i-10e' 285 | assert bencode(12345678901234567890L) == 'i12345678901234567890e' 286 | assert bencode('') == '0:' 287 | assert bencode('abc') == '3:abc' 288 | assert bencode('1234567890') == '10:1234567890' 289 | assert bencode([]) == 'le' 290 | assert bencode([1, 2, 3]) == 'li1ei2ei3ee' 291 | assert bencode([['Alice', 'Bob'], [2, 3]]) == 'll5:Alice3:Bobeli2ei3eee' 292 | assert bencode({}) == 'de' 293 | assert bencode({'age': 25, 'eyes': 'blue'}) == 'd3:agei25e4:eyes4:bluee' 294 | assert bencode({'spam.mp3': {'author': 'Alice', 'length': 100000}}) == 'd8:spam.mp3d6:author5:Alice6:lengthi100000eee' 295 | assert bencode(Bencached(bencode(3))) == 'i3e' 296 | try: 297 | bencode({1: 'foo'}) 298 | except TypeError: 299 | return 300 | assert 0 301 | 302 | try: 303 | import psyco 304 | psyco.bind(bdecode) 305 | psyco.bind(bencode) 306 | except ImportError: 307 | pass -------------------------------------------------------------------------------- /static/js/bootstrap.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap.js by @fat & @mdo 3 | * Copyright 2012 Twitter, Inc. 4 | * http://www.apache.org/licenses/LICENSE-2.0.txt 5 | */ 6 | !function($){"use strict";$(function(){$.support.transition=function(){var transitionEnd=function(){var name,el=document.createElement("bootstrap"),transEndEventNames={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(name in transEndEventNames)if(void 0!==el.style[name])return transEndEventNames[name]}();return transitionEnd&&{end:transitionEnd}}()})}(window.jQuery),!function($){"use strict";var dismiss='[data-dismiss="alert"]',Alert=function(el){$(el).on("click",dismiss,this.close)};Alert.prototype.close=function(e){function removeElement(){$parent.trigger("closed").remove()}var $parent,$this=$(this),selector=$this.attr("data-target");selector||(selector=$this.attr("href"),selector=selector&&selector.replace(/.*(?=#[^\s]*$)/,"")),$parent=$(selector),e&&e.preventDefault(),$parent.length||($parent=$this.hasClass("alert")?$this:$this.parent()),$parent.trigger(e=$.Event("close")),e.isDefaultPrevented()||($parent.removeClass("in"),$.support.transition&&$parent.hasClass("fade")?$parent.on($.support.transition.end,removeElement):removeElement())};var old=$.fn.alert;$.fn.alert=function(option){return this.each(function(){var $this=$(this),data=$this.data("alert");data||$this.data("alert",data=new Alert(this)),"string"==typeof option&&data[option].call($this)})},$.fn.alert.Constructor=Alert,$.fn.alert.noConflict=function(){return $.fn.alert=old,this},$(document).on("click.alert.data-api",dismiss,Alert.prototype.close)}(window.jQuery),!function($){"use strict";var Button=function(element,options){this.$element=$(element),this.options=$.extend({},$.fn.button.defaults,options)};Button.prototype.setState=function(state){var d="disabled",$el=this.$element,data=$el.data(),val=$el.is("input")?"val":"html";state+="Text",data.resetText||$el.data("resetText",$el[val]()),$el[val](data[state]||this.options[state]),setTimeout(function(){"loadingText"==state?$el.addClass(d).attr(d,d):$el.removeClass(d).removeAttr(d)},0)},Button.prototype.toggle=function(){var $parent=this.$element.closest('[data-toggle="buttons-radio"]');$parent&&$parent.find(".active").removeClass("active"),this.$element.toggleClass("active")};var old=$.fn.button;$.fn.button=function(option){return this.each(function(){var $this=$(this),data=$this.data("button"),options="object"==typeof option&&option;data||$this.data("button",data=new Button(this,options)),"toggle"==option?data.toggle():option&&data.setState(option)})},$.fn.button.defaults={loadingText:"loading..."},$.fn.button.Constructor=Button,$.fn.button.noConflict=function(){return $.fn.button=old,this},$(document).on("click.button.data-api","[data-toggle^=button]",function(e){var $btn=$(e.target);$btn.hasClass("btn")||($btn=$btn.closest(".btn")),$btn.button("toggle")})}(window.jQuery),!function($){"use strict";var Carousel=function(element,options){this.$element=$(element),this.options=options,"hover"==this.options.pause&&this.$element.on("mouseenter",$.proxy(this.pause,this)).on("mouseleave",$.proxy(this.cycle,this))};Carousel.prototype={cycle:function(e){return e||(this.paused=!1),this.options.interval&&!this.paused&&(this.interval=setInterval($.proxy(this.next,this),this.options.interval)),this},to:function(pos){var $active=this.$element.find(".item.active"),children=$active.parent().children(),activePos=children.index($active),that=this;if(!(pos>children.length-1||0>pos))return this.sliding?this.$element.one("slid",function(){that.to(pos)}):activePos==pos?this.pause().cycle():this.slide(pos>activePos?"next":"prev",$(children[pos]))},pause:function(e){return e||(this.paused=!0),this.$element.find(".next, .prev").length&&$.support.transition.end&&(this.$element.trigger($.support.transition.end),this.cycle()),clearInterval(this.interval),this.interval=null,this},next:function(){return this.sliding?void 0:this.slide("next")},prev:function(){return this.sliding?void 0:this.slide("prev")},slide:function(type,next){var e,$active=this.$element.find(".item.active"),$next=next||$active[type](),isCycling=this.interval,direction="next"==type?"left":"right",fallback="next"==type?"first":"last",that=this;if(this.sliding=!0,isCycling&&this.pause(),$next=$next.length?$next:this.$element.find(".item")[fallback](),e=$.Event("slide",{relatedTarget:$next[0]}),!$next.hasClass("active")){if($.support.transition&&this.$element.hasClass("slide")){if(this.$element.trigger(e),e.isDefaultPrevented())return;$next.addClass(type),$next[0].offsetWidth,$active.addClass(direction),$next.addClass(direction),this.$element.one($.support.transition.end,function(){$next.removeClass([type,direction].join(" ")).addClass("active"),$active.removeClass(["active",direction].join(" ")),that.sliding=!1,setTimeout(function(){that.$element.trigger("slid")},0)})}else{if(this.$element.trigger(e),e.isDefaultPrevented())return;$active.removeClass("active"),$next.addClass("active"),this.sliding=!1,this.$element.trigger("slid")}return isCycling&&this.cycle(),this}}};var old=$.fn.carousel;$.fn.carousel=function(option){return this.each(function(){var $this=$(this),data=$this.data("carousel"),options=$.extend({},$.fn.carousel.defaults,"object"==typeof option&&option),action="string"==typeof option?option:options.slide;data||$this.data("carousel",data=new Carousel(this,options)),"number"==typeof option?data.to(option):action?data[action]():options.interval&&data.cycle()})},$.fn.carousel.defaults={interval:5e3,pause:"hover"},$.fn.carousel.Constructor=Carousel,$.fn.carousel.noConflict=function(){return $.fn.carousel=old,this},$(document).on("click.carousel.data-api","[data-slide]",function(e){var href,$this=$(this),$target=$($this.attr("data-target")||(href=$this.attr("href"))&&href.replace(/.*(?=#[^\s]+$)/,"")),options=$.extend({},$target.data(),$this.data());$target.carousel(options),e.preventDefault()})}(window.jQuery),!function($){"use strict";var Collapse=function(element,options){this.$element=$(element),this.options=$.extend({},$.fn.collapse.defaults,options),this.options.parent&&(this.$parent=$(this.options.parent)),this.options.toggle&&this.toggle()};Collapse.prototype={constructor:Collapse,dimension:function(){var hasWidth=this.$element.hasClass("width");return hasWidth?"width":"height"},show:function(){var dimension,scroll,actives,hasData;if(!this.transitioning){if(dimension=this.dimension(),scroll=$.camelCase(["scroll",dimension].join("-")),actives=this.$parent&&this.$parent.find("> .accordion-group > .in"),actives&&actives.length){if(hasData=actives.data("collapse"),hasData&&hasData.transitioning)return;actives.collapse("hide"),hasData||actives.data("collapse",null)}this.$element[dimension](0),this.transition("addClass",$.Event("show"),"shown"),$.support.transition&&this.$element[dimension](this.$element[0][scroll])}},hide:function(){var dimension;this.transitioning||(dimension=this.dimension(),this.reset(this.$element[dimension]()),this.transition("removeClass",$.Event("hide"),"hidden"),this.$element[dimension](0))},reset:function(size){var dimension=this.dimension();return this.$element.removeClass("collapse")[dimension](size||"auto")[0].offsetWidth,this.$element[null!==size?"addClass":"removeClass"]("collapse"),this},transition:function(method,startEvent,completeEvent){var that=this,complete=function(){"show"==startEvent.type&&that.reset(),that.transitioning=0,that.$element.trigger(completeEvent)};this.$element.trigger(startEvent),startEvent.isDefaultPrevented()||(this.transitioning=1,this.$element[method]("in"),$.support.transition&&this.$element.hasClass("collapse")?this.$element.one($.support.transition.end,complete):complete())},toggle:function(){this[this.$element.hasClass("in")?"hide":"show"]()}};var old=$.fn.collapse;$.fn.collapse=function(option){return this.each(function(){var $this=$(this),data=$this.data("collapse"),options="object"==typeof option&&option;data||$this.data("collapse",data=new Collapse(this,options)),"string"==typeof option&&data[option]()})},$.fn.collapse.defaults={toggle:!0},$.fn.collapse.Constructor=Collapse,$.fn.collapse.noConflict=function(){return $.fn.collapse=old,this},$(document).on("click.collapse.data-api","[data-toggle=collapse]",function(e){var href,$this=$(this),target=$this.attr("data-target")||e.preventDefault()||(href=$this.attr("href"))&&href.replace(/.*(?=#[^\s]+$)/,""),option=$(target).data("collapse")?"toggle":$this.data();$this[$(target).hasClass("in")?"addClass":"removeClass"]("collapsed"),$(target).collapse(option)})}(window.jQuery),!function($){"use strict";function clearMenus(){$(toggle).each(function(){getParent($(this)).removeClass("open")})}function getParent($this){var $parent,selector=$this.attr("data-target");return selector||(selector=$this.attr("href"),selector=selector&&/#/.test(selector)&&selector.replace(/.*(?=#[^\s]*$)/,"")),$parent=$(selector),$parent.length||($parent=$this.parent()),$parent}var toggle="[data-toggle=dropdown]",Dropdown=function(element){var $el=$(element).on("click.dropdown.data-api",this.toggle);$("html").on("click.dropdown.data-api",function(){$el.parent().removeClass("open")})};Dropdown.prototype={constructor:Dropdown,toggle:function(){var $parent,isActive,$this=$(this);if(!$this.is(".disabled, :disabled"))return $parent=getParent($this),isActive=$parent.hasClass("open"),clearMenus(),isActive||$parent.toggleClass("open"),$this.focus(),!1},keydown:function(e){var $this,$items,$parent,isActive,index;if(/(38|40|27)/.test(e.keyCode)&&($this=$(this),e.preventDefault(),e.stopPropagation(),!$this.is(".disabled, :disabled"))){if($parent=getParent($this),isActive=$parent.hasClass("open"),!isActive||isActive&&27==e.keyCode)return $this.click();$items=$("[role=menu] li:not(.divider):visible a",$parent),$items.length&&(index=$items.index($items.filter(":focus")),38==e.keyCode&&index>0&&index--,40==e.keyCode&&$items.length-1>index&&index++,~index||(index=0),$items.eq(index).focus())}}};var old=$.fn.dropdown;$.fn.dropdown=function(option){return this.each(function(){var $this=$(this),data=$this.data("dropdown");data||$this.data("dropdown",data=new Dropdown(this)),"string"==typeof option&&data[option].call($this)})},$.fn.dropdown.Constructor=Dropdown,$.fn.dropdown.noConflict=function(){return $.fn.dropdown=old,this},$(document).on("click.dropdown.data-api touchstart.dropdown.data-api",clearMenus).on("click.dropdown touchstart.dropdown.data-api",".dropdown form",function(e){e.stopPropagation()}).on("touchstart.dropdown.data-api",".dropdown-menu",function(e){e.stopPropagation()}).on("click.dropdown.data-api touchstart.dropdown.data-api",toggle,Dropdown.prototype.toggle).on("keydown.dropdown.data-api touchstart.dropdown.data-api",toggle+", [role=menu]",Dropdown.prototype.keydown)}(window.jQuery),!function($){"use strict";var Modal=function(element,options){this.options=options,this.$element=$(element).delegate('[data-dismiss="modal"]',"click.dismiss.modal",$.proxy(this.hide,this)),this.options.remote&&this.$element.find(".modal-body").load(this.options.remote)};Modal.prototype={constructor:Modal,toggle:function(){return this[this.isShown?"hide":"show"]()},show:function(){var that=this,e=$.Event("show");this.$element.trigger(e),this.isShown||e.isDefaultPrevented()||(this.isShown=!0,this.escape(),this.backdrop(function(){var transition=$.support.transition&&that.$element.hasClass("fade");that.$element.parent().length||that.$element.appendTo(document.body),that.$element.show(),transition&&that.$element[0].offsetWidth,that.$element.addClass("in").attr("aria-hidden",!1),that.enforceFocus(),transition?that.$element.one($.support.transition.end,function(){that.$element.focus().trigger("shown")}):that.$element.focus().trigger("shown")}))},hide:function(e){e&&e.preventDefault(),e=$.Event("hide"),this.$element.trigger(e),this.isShown&&!e.isDefaultPrevented()&&(this.isShown=!1,this.escape(),$(document).off("focusin.modal"),this.$element.removeClass("in").attr("aria-hidden",!0),$.support.transition&&this.$element.hasClass("fade")?this.hideWithTransition():this.hideModal())},enforceFocus:function(){var that=this;$(document).on("focusin.modal",function(e){that.$element[0]===e.target||that.$element.has(e.target).length||that.$element.focus()})},escape:function(){var that=this;this.isShown&&this.options.keyboard?this.$element.on("keyup.dismiss.modal",function(e){27==e.which&&that.hide()}):this.isShown||this.$element.off("keyup.dismiss.modal")},hideWithTransition:function(){var that=this,timeout=setTimeout(function(){that.$element.off($.support.transition.end),that.hideModal()},500);this.$element.one($.support.transition.end,function(){clearTimeout(timeout),that.hideModal()})},hideModal:function(){this.$element.hide().trigger("hidden"),this.backdrop()},removeBackdrop:function(){this.$backdrop.remove(),this.$backdrop=null},backdrop:function(callback){var animate=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var doAnimate=$.support.transition&&animate;this.$backdrop=$('