aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yaml13
-rw-r--r--README.md3
-rw-r--r--setup.py2
-rw-r--r--tests/data/no_body.html50
-rw-r--r--tests/data/torrent_test.html276
-rw-r--r--tests/integration/__init__.py0
-rw-r--r--tests/unit/__init__.py0
-rw-r--r--tests/unit/test_constants.py27
-rw-r--r--tests/unit/test_torrents.py102
-rw-r--r--tests/unit/test_tpb.py9
-rw-r--r--tests/unit/test_utils.py11
-rw-r--r--tpblite/models/torrents.py6
12 files changed, 492 insertions, 7 deletions
diff --git a/.travis.yaml b/.travis.yaml
new file mode 100644
index 0000000..9dc2570
--- /dev/null
+++ b/.travis.yaml
@@ -0,0 +1,13 @@
+language: python
+python:
+ - "3.5"
+ - "3.6"
+ - "3.7"
+ - "3.8"
+
+# command to install dependencies
+install:
+ - pip install coverage coveralls .
+# command to run tests
+script: "coverage run -m unittest discover -s '.tests/' -p 'test_*.py'"
+after_success: "coveralls"
diff --git a/README.md b/README.md
index 6c69069..f4f4772 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,5 @@
Unofficial Lightweight Python API for ThePirateBay
-
-[![PyPI version](https://badge.fury.io/py/tpblite.png)](https://badge.fury.io/py/tpblite)
+[![Build Status](https://travis-ci.com/mattlyon93/tpb-lite.svg?branch=master)](https://travis-ci.com/mattlyon93/tpb-lite) [![Coverage Status](https://coveralls.io/repos/github/mattlyon93/tpb-lite/badge.svg?branch=master)](https://coveralls.io/github/mattlyon93/tpb-lite?branch=master) [![PyPI version](https://badge.fury.io/py/tpblite.png)](https://badge.fury.io/py/tpblite)
Installation
=============
diff --git a/setup.py b/setup.py
index 9bb031d..4f925ef 100644
--- a/setup.py
+++ b/setup.py
@@ -7,7 +7,7 @@ this_dir = path.abspath(path.dirname(__file__))
with open(path.join(this_dir, 'README.md'), encoding='utf-8') as f:
long_description = f.read()
-version = '0.5.0'
+version = '0.6.0'
setup(name = 'tpblite',
version = version,
diff --git a/tests/data/no_body.html b/tests/data/no_body.html
new file mode 100644
index 0000000..f301987
--- /dev/null
+++ b/tests/data/no_body.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" >
+<head>
+ <title>The Pirate Bay - The galaxy's most resilient bittorrent site</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+ <link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="Search The Pirate Bay" />
+ <link rel="stylesheet" type="text/css" href="/static/css-new/pirate6.css"/>
+ <style type="text/css">
+ .searchBox{
+ margin: 6px;
+ width: 300px;
+ vertical-align: middle;
+ padding: 2px;
+ background-image:url('/static/img/icon-https.gif');
+ background-repeat:no-repeat;
+ background-position: right;
+ }
+
+ .detLink {
+ font-size: 1.2em;
+ font-weight: 400;
+ }
+ .detDesc {
+ color: #4e5456;
+ }
+ .detDesc a:hover {
+ color: #000099;
+ text-decoration: underline;
+ }
+ .sortby {
+ text-align: left;
+ float: left;
+ }
+ .detName {
+ padding-top: 3px;
+ padding-bottom: 2px;
+ }
+ .viewswitch {
+ font-style: normal;
+ float: right;
+ text-align: right;
+ font-weight: normal;
+ }
+ </style>
+ <script src="/static/js/tpb.js" type="text/javascript"></script>
+ <script language="javascript" type="text/javascript">if (top.location != self.location) {top.location.replace(self.location);}</script>
+</head>
+
+
+</html>
diff --git a/tests/data/torrent_test.html b/tests/data/torrent_test.html
new file mode 100644
index 0000000..7ea9e6e
--- /dev/null
+++ b/tests/data/torrent_test.html
@@ -0,0 +1,276 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" >
+<head>
+ <title>The Pirate Bay - The galaxy's most resilient bittorrent site</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+ <link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="Search The Pirate Bay" />
+ <link rel="stylesheet" type="text/css" href="/static/css-new/pirate6.css"/>
+ <style type="text/css">
+ .searchBox{
+ margin: 6px;
+ width: 300px;
+ vertical-align: middle;
+ padding: 2px;
+ background-image:url('/static/img/icon-https.gif');
+ background-repeat:no-repeat;
+ background-position: right;
+ }
+
+ .detLink {
+ font-size: 1.2em;
+ font-weight: 400;
+ }
+ .detDesc {
+ color: #4e5456;
+ }
+ .detDesc a:hover {
+ color: #000099;
+ text-decoration: underline;
+ }
+ .sortby {
+ text-align: left;
+ float: left;
+ }
+ .detName {
+ padding-top: 3px;
+ padding-bottom: 2px;
+ }
+ .viewswitch {
+ font-style: normal;
+ float: right;
+ text-align: right;
+ font-weight: normal;
+ }
+ </style>
+ <script src="/static/js/tpb.js" type="text/javascript"></script>
+ <script language="javascript" type="text/javascript">if (top.location != self.location) {top.location.replace(self.location);}</script>
+</head>
+
+<body>
+
+
+ <div id="header">
+
+
+ <div class="ad">
+ <iframe src="http://cdn2.adexprt.com/exo_na/top.html" width="468" height="60" frameborder="0" scrolling="no"></iframe>
+ </div>
+ <form method="get" id="q" action="/s/">
+ <a href="/" class="img"><img src="/static/img/tpblogo_sm_ny.gif" id="TPBlogo" alt="The Pirate Bay" /></a>
+ <b><a href="/" title="Search Torrents">Search Torrents</a></b>&nbsp;&nbsp;|&nbsp;
+ <a href="/browse" title="Browse Torrents">Browse Torrents</a>&nbsp;&nbsp;|&nbsp;
+ <a href="/recent" title="Recent Torrent">Recent Torrents</a>&nbsp;&nbsp;|&nbsp;
+ <a href="/tv" title="TV shows">TV shows</a>&nbsp;&nbsp;|&nbsp;
+ <a href="/music" title="Music">Music</a>&nbsp;&nbsp;|&nbsp;
+ <a href="/top" title="Top 100">Top 100</a>
+ <br /><input type="search" class="inputbox" title="Pirate Search" name="q" placeholder="Search here..." value="" /><input value="Pirate Search" type="submit" class="submitbutton" /><br /> <label for="audio" title="Audio"><input id="audio" name="audio" onclick="javascript:rmAll();" type="checkbox"/>Audio</label>
+ <label for="video" title="Video"><input id="video" name="video" onclick="javascript:rmAll();" type="checkbox"/>Video</label>
+ <label for="apps" title="Applications"><input id="apps" name="apps" onclick="javascript:rmAll();" type="checkbox"/>Applications</label>
+ <label for="games" title="Games"><input id="games" name="games" onclick="javascript:rmAll();" type="checkbox"/>Games</label>
+ <label for="other" title="Other"><input id="other" name="other" onclick="javascript:rmAll();" type="checkbox"/>Other</label>
+
+ <select id="category" name="category" onchange="javascript:setAll();">
+ <option value="0">All</option>
+ <optgroup label="Audio">
+ <option value="101">Music</option>
+ <option value="102">Audio books</option>
+ <option value="103">Sound clips</option>
+ <option value="104">FLAC</option>
+ <option value="199">Other</option>
+ </optgroup>
+ <optgroup label="Video">
+ <option value="201">Movies</option>
+ <option value="202">Movies DVDR</option>
+ <option value="203">Music videos</option>
+ <option value="204">Movie clips</option>
+ <option value="205">TV shows</option>
+ <option value="206">Handheld</option>
+ <option value="207">HD - Movies</option>
+ <option value="208">HD - TV shows</option>
+ <option value="209">3D</option>
+ <option value="299">Other</option>
+ </optgroup>
+ <optgroup label="Applications">
+ <option value="301">Windows</option>
+ <option value="302">Mac</option>
+ <option value="303">UNIX</option>
+ <option value="304">Handheld</option>
+ <option value="305">IOS (iPad/iPhone)</option>
+ <option value="306">Android</option>
+ <option value="399">Other OS</option>
+ </optgroup>
+ <optgroup label="Games">
+ <option value="401">PC</option>
+ <option value="402">Mac</option>
+ <option value="403">PSx</option>
+ <option value="404">XBOX360</option>
+ <option value="405">Wii</option>
+ <option value="406">Handheld</option>
+ <option value="407">IOS (iPad/iPhone)</option>
+ <option value="408">Android</option>
+ <option value="499">Other</option>
+ </optgroup>
+ <optgroup label="Other">
+ <option value="601">E-books</option>
+ <option value="602">Comics</option>
+ <option value="603">Pictures</option>
+ <option value="604">Covers</option>
+ <option value="605">Physibles</option>
+ <option value="699">Other</option>
+ </optgroup>
+ </select>
+
+ <input type="hidden" name="page" value="0" />
+ <input type="hidden" name="orderby" value="99" />
+ </form>
+ </div><!-- // div:header -->
+
+ <h2><span>Recent Torrents</span>&nbsp;</h2>
+<div id="content">
+ <div id="sky-right">
+ <iframe src="http://cdn1.adexprt.com/exo_na/sky2.html" width="160" height="600" frameborder="0" scrolling="no" style="padding-top: 100px"></iframe>
+ </div>
+ <div id="main-content">
+
+ <iframe src="http://cdn1.adexprt.com/exo_na/center.html" width="728" height="90" frameborder="0" scrolling="no"></iframe>
+ <table id="searchResult">
+ <thead id="tableHead">
+ <tr class="header">
+ <th>Type</th>
+ <th><div class="sortby">Name</div><div class="viewswitch"> View: <a href="/switchview.php?view=s">Single</a> / Double&nbsp;</div></th>
+ <th><abbr title="Seeders">SE</abbr></th>
+ <th><abbr title="Leechers">LE</abbr></th>
+ </tr>
+ </thead>
+ <tr>
+ <td class="vertTh">
+ <center>
+ <a href="/browse/400" title="More from this category">Games</a><br />
+ (<a href="/browse/401" title="More from this category">PC</a>)
+ </center>
+ </td>
+ <td>
+<div class="detName"> <a href="/torrent/8935177/Hot.Wheels.Worlds.Best.Driver-SKIDROW" class="detLink" title="Details for Hot.Wheels.Worlds.Best.Driver-SKIDROW">Hot.Wheels.Worlds.Best.Driver-SKIDROW</a>
+</div>
+<a href="magnet:?xt=urn:btih:1a830b92dcb82f40ba3e70b0ca50335b800b3c0c&dn=Hot.Wheels.Worlds.Best.Driver-SKIDROW&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80&tr=udp%3A%2F%2Ftracker.istole.it%3A6969&tr=udp%3A%2F%2Ftracker.ccc.de%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337" title="Download this torrent using magnet"><img src="/static/img/icon-magnet.gif" alt="Magnet link" /></a> <a href="//torrents.thepiratebay.sx/8935177/Hot.Wheels.Worlds.Best.Driver-SKIDROW.8935177.TPB.torrent" title="Download this torrent"><img src="/static/img/dl.gif" class="dl" alt="Download" /></a><a href="/user/Drarbg"><img src="/static/img/vip.gif" alt="VIP" title="VIP" style="width:11px;" border='0' /></a><img src="/static/img/11x11p.png" />
+ <font class="detDesc">Uploaded <b>4&nbsp;mins&nbsp;ago</b>, Size 3.32&nbsp;GiB, ULed by <a class="detDesc" href="/user/Drarbg/" title="Browse Drarbg">Drarbg</a></font>
+ </td>
+ <td align="right">0</td>
+ <td align="right">0</td>
+ </tr>
+ <tr>
+ <td class="vertTh">
+ <center>
+ <a href="/browse/100" title="More from this category">Audio</a><br />
+ (<a href="/browse/101" title="More from this category">Music</a>)
+ </center>
+ </td>
+ <td>
+<div class="detName"> <a href="/torrent/8935175/A_Tribe_Called_Quest-_The_Low_End_Theory_[_320kbps]" class="detLink" title="Details for A Tribe Called Quest- The Low End Theory [@320kbps]">A Tribe Called Quest- The Low End Theory [@320kbps]</a>
+</div>
+<a href="magnet:?xt=urn:btih:848560a84b80e1bcf15f8e7d6259b9bc499b555a&dn=A+Tribe+Called+Quest-+The+Low+End+Theory+%5B%40320kbps%5D&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80&tr=udp%3A%2F%2Ftracker.istole.it%3A6969&tr=udp%3A%2F%2Ftracker.ccc.de%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337" title="Download this torrent using magnet"><img src="/static/img/icon-magnet.gif" alt="Magnet link" /></a> <a href="//torrents.thepiratebay.sx/8935175/A_Tribe_Called_Quest-_The_Low_End_Theory_[_320kbps].8935175.TPB.torrent" title="Download this torrent"><img src="/static/img/dl.gif" class="dl" alt="Download" /></a><img src="/static/img/icon_image.gif" alt="This torrent has a cover image" title="This torrent has a cover image" /><a href="/user/WildcardSearch"><img src="/static/img/vip.gif" alt="VIP" title="VIP" style="width:11px;" border='0' /></a><img src="/static/img/11x11p.png" />
+ <font class="detDesc">Uploaded <b>5&nbsp;mins&nbsp;ago</b>, Size 119.24&nbsp;MiB, ULed by <a class="detDesc" href="/user/WildcardSearch/" title="Browse WildcardSearch">WildcardSearch</a></font>
+ </td>
+ <td align="right">0</td>
+ <td align="right">0</td>
+ </tr>
+ <tr>
+ <td class="vertTh">
+ <center>
+ <a href="/browse/200" title="More from this category">Video</a><br />
+ (<a href="/browse/201" title="More from this category">Movies</a>)
+ </center>
+ </td>
+ <td>
+<div class="detName"> <a href="/torrent/8935157/CBGB_2013_HDRip_x264_AC3_UNiQUE" class="detLink" title="Details for CBGB 2013 HDRip x264 AC3 UNiQUE">CBGB 2013 HDRip x264 AC3 UNiQUE</a>
+</div>
+<a href="magnet:?xt=urn:btih:e6ffe4e140a0676833ed3e87bc3de4f5d0b0a701&dn=CBGB+2013+HDRip+x264+AC3+UNiQUE&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80&tr=udp%3A%2F%2Ftracker.istole.it%3A6969&tr=udp%3A%2F%2Ftracker.ccc.de%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337" title="Download this torrent using magnet"><img src="/static/img/icon-magnet.gif" alt="Magnet link" /></a> <a href="//torrents.thepiratebay.sx/8935157/CBGB_2013_HDRip_x264_AC3_UNiQUE.8935157.TPB.torrent" title="Download this torrent"><img src="/static/img/dl.gif" class="dl" alt="Download" /></a><a href="/user/Drarbg"><img src="/static/img/vip.gif" alt="VIP" title="VIP" style="width:11px;" border='0' /></a><img src="/static/img/11x11p.png" />
+ <font class="detDesc">Uploaded <b>6&nbsp;mins&nbsp;ago</b>, Size 1.6&nbsp;GiB, ULed by <a class="detDesc" href="/user/Drarbg/" title="Browse Drarbg">Drarbg</a></font>
+ </td>
+ <td align="right">0</td>
+ <td align="right">0</td>
+ </tr>
+ <tr>
+ <td class="vertTh">
+ <center>
+ <a href="/browse/500" title="More from this category">Porn</a><br />
+ (<a href="/browse/506" title="More from this category">Movie clips</a>)
+ </center>
+ </td>
+ <td>
+<div class="detName"> <a href="/torrent/8935156/Secretary_s_Day_6_-_Charley_Monroe.mp4" class="detLink" title="Details for Secretary's Day 6 - Charley Monroe.mp4">Secretary's Day 6 - Charley Monroe.mp4</a>
+</div>
+<a href="magnet:?xt=urn:btih:1560475fa3298d0e4d745ba660631e9bdf2ed837&dn=Secretary%27s+Day+6+-+Charley+Monroe.mp4&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80&tr=udp%3A%2F%2Ftracker.istole.it%3A6969&tr=udp%3A%2F%2Ftracker.ccc.de%3A80&tr=udp%3A%2F%2Fopen.demonii.com%3A1337" title="Download this torrent using magnet"><img src="/static/img/icon-magnet.gif" alt="Magnet link" /></a> <a href="//torrents.thepiratebay.sx/8935156/Secretary_s_Day_6_-_Charley_Monroe.mp4.8935156.TPB.torrent" title="Download this torrent"><img src="/static/img/dl.gif" class="dl" alt="Download" /></a><img src="/static/img/icon_image.gif" alt="This torrent has a cover image" title="This torrent has a cover image" /><a href="/user/Pornmaze"><img src="/static/img/vip.gif" alt="VIP" title="VIP" style="width:11px;" border='0' /></a><img src="/static/img/11x11p.png" />
+ <font class="detDesc">Uploaded <b>6&nbsp;mins&nbsp;ago</b>, Size 352.69&nbsp;MiB, ULed by <a class="detDesc" href="/user/Pornmaze/" title="Browse Pornmaze">Pornmaze</a></font>
+ </td>
+ <td align="right">0</td>
+ <td align="right">0</td>
+ </tr>
+ <tr>
+ <td class="vertTh">
+ <center>
+ <a href="/browse/200" title="More from this category">Video</a><br />
+ (<a href="/browse/205" title="More from this category">TV shows</a>)
+ </center>
+ </td>
+ <td>
+<div class="detName"> <a href="/torrent/8935152/Fair.City.S24E148.2013.09.18.pdtv.x264_" class="detLink" title="Details for Fair.City.S24E148.2013.09.18.pdtv.x264 ">Fair.City.S </a>
+</div>
+<a href="magnet:?xt=urn:btih:12dce429d8ca04f2b17b28036e11abb2c1239fa6&dn=Fair.Ci" title="Download this torrent using magnet"><img src="/static/img/icon-magnet.gif" alt="Magnet link" /></a> <a href="//torrents.thepiratebay.sx/8935152/Fair.City.S24E148.2013.09.18.pdtv.x264_.8935152.TPB.torrent" title="Download this torrent"><img src="/static/img/dl.gif" class="dl" alt="Download" /></a><img src="/static/img/trusted.png" alt="Trusted" title="Trusted" style="width:11px;" border='0' /><img src="/static/img/11x11p.png" />
+ <font class="detDesc">Uploaded <b>9&nbsp;mins&nbsp;ago</b>, Size 142.17&nbsp;MiB, ULed by <i>Anonymous</i></font>
+ </td>
+ <td align="right">500</td>
+ <td align="right">400</td>
+ </tr>
+<tr><td colspan="9" style="text-align:center;">1&nbsp;<a href="/recent/1">2</a>&nbsp;<a href="/recent/2">3</a>&nbsp;<a href="/recent/3">4</a>&nbsp;<a href="/recent/4">5</a>&nbsp;<a href="/recent/5">6</a>&nbsp;<a href="/recent/6">7</a>&nbsp;<a href="/recent/7">8</a>&nbsp;<a href="/recent/8">9</a>&nbsp;<a href="/recent/9">10</a>&nbsp;<a href="/recent/10">11</a>&nbsp;<a href="/recent/11">12</a>&nbsp;<a href="/recent/12">13</a>&nbsp;<a href="/recent/13">14</a>&nbsp;<a href="/recent/14">15</a>&nbsp;<a href="/recent/15">16</a>&nbsp;<a href="/recent/16">17</a>&nbsp;<a href="/recent/17">18</a>&nbsp;<a href="/recent/18">19</a>&nbsp;<a href="/recent/19">20</a>&nbsp;<a href="/recent/20">21</a>&nbsp;<a href="/recent/21">22</a>&nbsp;<a href="/recent/22">23</a>&nbsp;<a href="/recent/23">24</a>&nbsp;<a href="/recent/24">25</a>&nbsp;<a href="/recent/25">26</a>&nbsp;<a href="/recent/26">27</a>&nbsp;<a href="/recent/27">28</a>&nbsp;<a href="/recent/28">29</a>&nbsp;<a href="/recent/29">30</a>&nbsp;<a href="/recent/1"><img src="/static/img/next.gif" border="0" alt="Next"/></a>&nbsp;
+</td></tr>
+</table>
+</div>
+
+ <div class="ads" id="sky-banner">
+ <iframe src="http://cdn1.adexprt.com/exo_na/sky1.html" width="120" height="600" frameborder="0" scrolling="no"></iframe>
+ </div>
+ </div><!-- //div:content -->
+
+ <div id="foot" style="text-align:center;margin-top:1em;">
+
+ <iframe src="http://cdn2.adexprt.com/exo_na/bottom.html" width="728" height="90" frameborder="0" scrolling="no"></iframe>
+ <p>
+ <a href="/login" title="Login">Login</a> |
+ <a href="/register" title="Register">Register</a> |
+ <a href="/language" title="Select language">Language / Select language</a> |
+ <a href="/about" title="About">About</a> |
+ <a href="/legal" title="Legal threats">Legal threats</a> |
+ <a href="/blog" title="Blog">Blog</a>
+ <br />
+ <a href="/contact" title="Contact us">Contact us</a> |
+ <a href="/policy" title="Usage policy">Usage policy</a> |
+ <a href="/downloads" title="Downloads">Downloads</a> |
+ <a href="http://www.promobay.org/" title="Promo" target="_NEW">Promo</a> |
+ <a href="/doodles" title="Doodles">Doodles</a> |
+ <a href="/tags" title="Tag Cloud">Tag Cloud</a> |
+ <a href="http://suprbay.org/" title="Forum" target="_blank">Forum</a> |
+ <a href="http://piratebrowser.com/" title="PirateBrowser" target="_blank"><strong>PirateBrowser</strong></a>
+ <br />
+ <a href="http://bayfiles.net" title="Bayfiles" target="_blank">Bayfiles</a> |
+ <a href="http://bayimg.com" title="BayImg" target="_blank">BayImg</a> |
+ <a href="http://pastebay.net" title="PasteBay" target="_blank">PasteBay</a> |
+ <a href="http://uberproxy.net" title="Proxy" target="_blank">Proxy</a> |
+ <a href="https://twitter.com/tpbdotorg" title="Twitter" target="_blank">Follow TPB on Twitter</a> |
+ <a href="https://www.facebook.com/ThePirateBayWarMachine" title="Facebook" target="_blank">Follow TPB on Facebook</a>
+ <br />
+ </p>
+
+<p id="footer" style="color:#666; font-size:0.9em; ">
+ 6.384.858 registered users. Last updated 23:00:05.<br />
+ 43.007.335 peers (33.943.221 seeders + 9.064.114 leechers) in 5.323.905 torrents.<br />
+</p>
+<br /><a href="http://bitcoin.org" target="_NEW">BitCoin</a>: <b><a href="bitcoin:1KeBs4HBQzkdHC2ou3gpyGHqcL7aKzwTve">1KeBs4HBQzkdHC2ou3gpyGHqcL7aKzwTve</a></b><br /><a href="http://litecoin.org" target="_NEW">LiteCoin</a>: <a href="litecoin:LiYp3Dg11N5BgV8qKW42ubSZXFmjDByjoV">LiYp3Dg11N5BgV8qKW42ubSZXFmjDByjoV</a><br /><br /><br /><img src="/static/img/btcltc.png"><br /><br />
+
+ <div id="fbanners">
+ <a href="/rss" class="rss" title="RSS"><img src="/static/img/rss_small.gif" alt="RSS" /></a>
+ </div><!-- // div:fbanners -->
+ </div><!-- // div:foot -->
+<script type="text/javascript" src="/static/js/popw130917.js"></script><script type="text/javascript" src="/static/js/poptest.js"></script><!-- abc: FR -->
+</body>
+</html>
diff --git a/tests/integration/__init__.py b/tests/integration/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/integration/__init__.py
diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/unit/__init__.py
diff --git a/tests/unit/test_constants.py b/tests/unit/test_constants.py
new file mode 100644
index 0000000..944abd8
--- /dev/null
+++ b/tests/unit/test_constants.py
@@ -0,0 +1,27 @@
+import io
+import unittest
+import contextlib
+
+from tpblite.models import constants
+
+
+class ConstantsTestCase(unittest.TestCase):
+
+ def test_categories(self):
+ self.assertEqual(constants.CATEGORIES.VIDEO.MOVIES, 201)
+
+ def test_printOptions_one(self):
+ sobj = io.StringIO()
+ with contextlib.redirect_stdout(sobj):
+ constants.ORDERS.NAME.printOptions()
+ self.assertEqual(sobj.getvalue(), 'DES\nASC\n')
+
+ def test_printOptions_two(self):
+ sobj = io.StringIO()
+ with contextlib.redirect_stdout(sobj):
+ constants.CATEGORIES.GAMES.printOptions()
+ self.assertEqual(
+ sobj.getvalue(),
+ 'ALL\nPC\nMAC\nPSX\nXBOX360\nWII\nHANDHELD\nIOS\nANDROID\nOTHER\n'
+ )
+ \ No newline at end of file
diff --git a/tests/unit/test_torrents.py b/tests/unit/test_torrents.py
new file mode 100644
index 0000000..4326f68
--- /dev/null
+++ b/tests/unit/test_torrents.py
@@ -0,0 +1,102 @@
+import unittest
+
+from pathlib import Path
+
+from tpblite.models import torrents
+
+DATA_DIR = Path(__file__).parents[1].joinpath('data')
+
+class TorrentsTestCase(unittest.TestCase):
+
+ def setUp(self):
+ fobj = open(DATA_DIR.joinpath('torrent_test.html'), 'r')
+ contents = fobj.read()
+ fobj.close()
+ self.torrents = torrents.Torrents(contents)
+
+ def test_str(self):
+ self.assertEqual(str(self.torrents), 'Torrents object: 5 torrents')
+
+ def test_repr(self):
+ self.assertEqual(repr(self.torrents), '<Torrents object: 5 torrents>')
+
+ def test_length(self):
+ self.assertEqual(len(self.torrents), 5)
+
+ def test_title(self):
+ self.assertEqual(self.torrents[2].title, 'CBGB 2013 HDRip x264 AC3 UNiQUE')
+
+ def test_seeds(self):
+ self.assertEqual(self.torrents[-1].seeds, 500)
+
+ def test_leeches(self):
+ self.assertEqual(self.torrents[-1].leeches, 400)
+
+ def test_upload_date(self):
+ self.assertEqual(self.torrents[0].upload_date, '4 mins ago')
+
+ def test_uploader(self):
+ self.assertEqual(self.torrents[0].uploader, 'Drarbg')
+
+ def test_filesize(self):
+ self.assertEqual(self.torrents[1].filesize, '119.24 MiB')
+
+ def test_byte_size(self):
+ self.assertEqual(self.torrents[0].byte_size, 3564822855)
+
+ def test_magnetlink(self):
+ self.assertEqual(self.torrents[4].magnetlink, 'magnet:?xt=urn:btih:12dce429d8ca04f2b17b28036e11abb2c1239fa6&dn=Fair.Ci')
+
+ def test_url(self):
+ self.assertEqual(self.torrents[0].url, '/torrent/8935177/Hot.Wheels.Worlds.Best.Driver-SKIDROW')
+
+ def test_getBestTorrent(self):
+ tor = self.torrents.getBestTorrent(min_seeds=50, min_filesize='100 MiB', max_filesize='300 MiB')
+ self.assertEqual(tor.title, 'Fair.City.S ')
+
+ def test_getBestTorrentNone(self):
+ tor = self.torrents.getBestTorrent()
+ self.assertEqual(tor, None)
+
+class TorrentsExceptionsTestCase(unittest.TestCase):
+
+ def test_createTorrentListRaise(self):
+ fobj = open(DATA_DIR.joinpath('no_body.html'), 'r')
+ contents = fobj.read()
+ fobj.close()
+ self.assertRaises(ConnectionError, torrents.Torrents, contents)
+
+
+class TorrentTestCase(unittest.TestCase):
+
+ def setUp(self):
+ fobj = open(DATA_DIR.joinpath('torrent_test.html'), 'r')
+ contents = fobj.read()
+ fobj.close()
+ self.torrent = torrents.Torrents(contents)[4]
+
+ def test_str(self):
+ self.assertEqual(
+ str(self.torrent),
+ 'Fair.City.S , S: 500, L: 400, 142.17 MiB'
+ )
+
+ def test_repr(self):
+ self.assertEqual(repr(self.torrent), '<Torrent object: Fair.City.S >')
+
+
+class fileSizeTestCase(unittest.TestCase):
+
+ def test_raise_one(self):
+ self.assertRaises(AttributeError, torrents.fileSizeStrToInt, '400 MiBB')
+
+ def test_raise_two(self):
+ self.assertRaises(AttributeError, torrents.fileSizeStrToInt, '400 LiB')
+
+ def test_raise_three(self):
+ self.assertRaises(AttributeError, torrents.fileSizeStrToInt, 'm400 MiB')
+
+
+
+
+ \ No newline at end of file
diff --git a/tests/unit/test_tpb.py b/tests/unit/test_tpb.py
new file mode 100644
index 0000000..07eb5d1
--- /dev/null
+++ b/tests/unit/test_tpb.py
@@ -0,0 +1,9 @@
+import unittest
+
+from tpblite import TPB
+
+class TPBTestCase(unittest.TestCase):
+
+ def test_str(self):
+ t = TPB('https://tpb.party')
+ self.assertEqual(str(t), 'TPB Object, base URL: https://tpb.party')
diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py
new file mode 100644
index 0000000..5fa0adf
--- /dev/null
+++ b/tests/unit/test_utils.py
@@ -0,0 +1,11 @@
+import unittest
+
+from tpblite.models import utils
+
+
+class URLTestCase(unittest.TestCase):
+ def test_URL(self):
+ self.assertEqual(
+ utils.URL('https://some.domain', ('1', '99', '200')),
+ 'https://some.domain/1/99/200'
+ )
diff --git a/tpblite/models/torrents.py b/tpblite/models/torrents.py
index 1c2b32d..4803740 100644
--- a/tpblite/models/torrents.py
+++ b/tpblite/models/torrents.py
@@ -1,7 +1,5 @@
import unicodedata
-from lxml.etree import HTML
-
-# TODO: write better comments
+import lxml.etree as ET
def fileSizeStrToInt(size_str):
@@ -97,7 +95,7 @@ class Torrents:
return self.list[index]
def _createTorrentList(self):
- root = HTML(self.html_source)
+ root = ET.HTML(self.html_source)
if root.find("body") is None:
raise ConnectionError("Could not determine torrents (empty html body)")
rows = root.xpath('//tr[td[@class="vertTh"]]')