Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding Tor Requests #15

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@
env/
py1337x/__pycache__/
dist/
1337x.egg-info/
1337x.egg-info/
.python-version
build/
134 changes: 114 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,26 @@

<h2 align='center'>✖️Unofficial Python API Wrapper of 1337x</h2>
<h2 align='center'>✖️Unofficial Python Custom API Wrapper of 1337x</h2>
<p align="center">
<img src="https://github.com/hemantapkh/1337x/blob/main/images/1337x.png?raw=true" align="center" height=205 alt="1337x" />
<img src="https://github.com/LeGeRyChEeSe/1337x/blob/main/images/1337x.png?raw=true" align="center" height=205 alt="1337x" />
</p>
<p align="center">
<a href="https://pypi.org/project/1337x">
<img src='https://img.shields.io/pypi/v/1337x.svg'>
<img src='https://visitor-badge.laobi.icu/badge?page_id=LeGeRyChEeSe.1337x'>
<a href="https://github.com/LeGeRyChEeSe/1337x/stargazers">
<img src="https://img.shields.io/github/stars/LeGeRyChEeSe/1337x" alt="Stars"/>
</a>
<a href="https://pepy.tech/project/1337x">
<img src='https://pepy.tech/badge/1337x'>
</a>
<img src='https://visitor-badge.laobi.icu/badge?page_id=hemantapkh.1337x'>
<a href="https://github.com/hemantapkh/1337x/stargazers">
<img src="https://img.shields.io/github/stars/hemantapkh/1337x" alt="Stars"/>
</a>
<a href="https://github.com/hemantapkh/1337x/issues">
<img src="https://img.shields.io/github/issues/hemantapkh/1337x" alt="Issues"/>
<a href="https://github.com/LeGeRyChEeSe/1337x/issues">
<img src="https://img.shields.io/github/issues/LeGeRyChEeSe/1337x" alt="Issues"/>
</a>

<p align="center">
This is the unofficial API of 1337x. It supports all proxies of 1337x and almost all functions of 1337x. You can search, get trending, top and popular torrents. Furthermore, you can browse torrents of a certain category. It also supports filtering on result by category, supports sorting and caching.
This is the unofficial custom API of 1337x. It supports all proxies of 1337x and almost all functions of 1337x. You can search, get trending, top and popular torrents. Furthermore, you can browse torrents of a certain category. It also supports filtering on result by category, supports sorting and caching. Tor requests are now integrated with no more action to do. Works great and smoothly !
<p align="center">

## Table of Contents
- [Installation](#installation)
- [Start Guide](#start-guide)
- [Installation of Tor (NEW) **LINUX ONLY**](#installation-of-tor-new)
- [Requirements](#requirements)
- [Quick Examples](#quick-examples)
- [Searching Torrents](#1-searching-torrents)
- [Getting Trending Torrents](#2-getting-trending-torrents)
Expand All @@ -39,18 +35,110 @@ This is the unofficial API of 1337x. It supports all proxies of 1337x and almost
- [License](#license)

## Installation
- Install via [PyPi](https://www.pypi.org/project/1337x)
```bash
pip install 1337x
```

- Install from the source
```bash
git clone https://github.com/hemantapkh/1337x && cd 1337x && python setup.py sdist && pip install dist/*
git clone https://github.com/LeGeRyChEeSe/1337x.git && cd 1337x && python setup.py sdist && pip install dist/* && sudo apt-get install tor build-essential libssl-dev libffi-dev python-dev
```

## Start guide

### Installation of Tor (NEW) **LINUX ONLY**

#### Requirements

1. Generate a password that you should store at a **safe place** and remember it
```bash
tor --hash-password your-password
```
2. **Copy** the output of the previous command, it should looks like
```bash
16:05B7B9E8F3D0AB3160E030928F9517EDA5348ECD1CDCE2D95F0D230016
```

3. Configure the Tor controller to permit identity renewall requests
```bash
sudo nano /etc/tor/torrc
```
4. Uncomment those three lines
```bash
ControlPort 9051
CookieAuthentication 1
HashedControlPassword
```
5. **Paste** the hashed password you previously copied next to **HashedControlPassword**. If there is a password already, replace it with the newer. Now it should looks like
```bash
ControlPort 9051
CookieAuthentication 1
HashedControlPassword 16:05B7B9E8F3D0AB3160E030928F9517EDA5348ECD1CDCE2D95F0D230016
```
6. Save and exit the file and now it's time to start **Tor** service
```bash
sudo service tor start
```
7. If you did all well then you can run the following command from a terminal to check if it works
```bash
curl --socks5 localhost:9050 --socks5-hostname localhost:9050 -s https://check.torproject.org/ | cat | grep -m 1 Congratulations | xargs
```
- This command will display
```bash
Congratulations. This browser is configured to use Tor.
```

### Knowns Issues


#### You can't perform any Search

- The reason is probably because your Tor IP has been detected has SPAM so the solution is to reset a new Tor IP
```python
>>> from py1337x import py1337x

# Trying with 11337x.st proxy but we don't get any info of the torrent
>>> torrents = py1337x('1337x.to')
>>> torrents.search('harry potter')
None # Or possibly some errors

# Try to do the following
>>> torrents.getNewIp(passwd)
# passwd parameter is the clear password you've set in the Installation of Tor at the beginning of this guide.
# CLEAR password, not Hashed one.

# Then it should fix the issue temporarly until you need to renew the Tor IP again
# Of course you can do a for loop with many checks before you renew the IP
>>> torrents.search('harry potter')
{'items': [...], 'currentPage': 1, 'itemCount': 20, 'pageCount': 50}
```

#### You can't get Info of a torrent

- You should call this method once if you're getting no torrents for a while
```python
torrents.setNewProxy(other_proxy)
```
- If you don't want to do it manually so you can do a for loop in the new attribute `torrents.proxies` which is a list
```python
>>> from py1337x import py1337x

# Trying with 11337x.st proxy but we don't get any info of the torrent
>>> torrents = py1337x('11337x.st')
>>> torrents.info(torrentId=258188)
{'items': [], 'currentPage': 0, 'itemCount': 0, 'pageCount': 0}

# We can do a for loop to try every proxy until one returns the infos of the torrent.
# Useful when you don't remember which proxy you've used for searching or getting a torrent.
>>> for proxy in torrents.proxies:
>>> torrents.setNewProxy(proxy)
>>> torrents.info(torrentId=258188)
# Possible Output
{'items': [], 'currentPage': 0, 'itemCount': 0, 'pageCount': 0}
{'items': [], 'currentPage': 0, 'itemCount': 0, 'pageCount': 0}
.
.
.
{'items': [...], 'currentPage': 1, 'itemCount': 20, 'pageCount': 50} # So we've finally got our torrent data
```

### Quick Examples

#### 1. Searching torrents
Expand Down Expand Up @@ -126,7 +214,9 @@ torrents = py1337x(proxy='1337x.st', cookie='<cookie>', cache='py1337xCache', ca

**Proxy**

If the default domain is banned in your country, you can use an alternative domain of 1337x.
If the default domain is banned in your country, you can use an alternative domain of 1337x, or you can use the new [Tor Request](#tor-requests-new) system.

All categories are now accessible via the `torrents.proxies` attribute.

- [`1337x.to`](https://1337x.to) (**default**)
- [`1337x.tw`](https://www.1337x.tw)
Expand Down Expand Up @@ -199,9 +289,13 @@ torrents.top() | Get top torrents | self,<br>category (optional):
torrents.popular(category) | Get popular torrents | self,<br>category: [category](#available-categories),<br>week (Defaults to False): `True for weekely, False for daily`
torrents.browse(category) | Browse browse of certain category | self,<br>category: [category](#available-categories),<br>page (Defaults to 1): `Page to view`
torrents&#46;info(link or torrentId) | Get information of a torrent | self,<br>link: `Link of a torrent` or<br>torrentId: `ID of a torrent`
torrents.setNewProxy(proxy) | Set a new proxy for the instance | self,<br>proxy: `Proxy string of type '1337x.to'`
torrents.getNewIp(passwd) | Set a new IP for Tor requests | self,<br>passwd: `Clear Password set in` [Requirements (2./3.)](#requirements)

### Available categories

All categories are now accessible via the `torrents.categories` attribute.

- `'movies'`
- `'tv'`
- `'games'`
Expand Down
62 changes: 48 additions & 14 deletions py1337x/py1337x.py
Original file line number Diff line number Diff line change
@@ -1,61 +1,94 @@
import requests
import requests_cache
from py1337x import parser


from fake_useragent import UserAgent
from stem import Signal
from stem.control import Controller
class py1337x():
def __init__(self, proxy=None, cookie=None, cache=None, cacheTime=86400, backend='sqlite'):
self.baseUrl = f'https://www.{proxy}' if proxy else 'https://www.1377x.to'
self.baseUrl = f'https://www.{proxy}' if proxy else 'https://www.1337x.to'
self.headers = {
'user-agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:88.0) Gecko/20100101 Firefox/88.0',
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'accept-language': 'en-US,en;q=0.5',
'upgrade-insecure-requests': '1',
'te': 'trailers'
'User-Agent': UserAgent().random
}
self.tor_proxies = {'http': 'socks5h://127.0.0.1:9050', 'https': 'socks5h://127.0.0.1:9050'}
self.proxies = ['1337x.to', '1337x.tw', '1377x.to', '1337xx.to', '1337x.st', 'x1337x.ws', 'x1337x.eu', 'x1337x.se', '1337x.is', '1337x.gd']
self.categories = ['movies', 'tv', 'games', 'music', 'apps', 'anime', 'documentaries', 'xxx', 'others']

if cookie:
self.headers['cookie'] = f'cf_clearance={cookie}'

self.requests = requests_cache.CachedSession(cache, expire_after=cacheTime, backend=backend) if cache else requests

#: Define a New proxy
def setNewProxy(self, proxy: str):
"""
Define a new proxy for requests only if the original proxy didn't work

Parameters
----------
proxy: :class:`str`
Proxy of type '1337x.to'
"""
self.baseUrl = f'https://www.{proxy}'

#: Get New Tor IP if too many requests
def getNewIp(self, passwd: str):
"""
Define a new Tor IP if you can't access a proxy at all because of it's thinking you're actually spamming.

If you actually do, so please don't, thanks.

Parameters
----------
passwd: :class:`str`
Clear password of Tor Controller (it's never stored anywhere)
"""
with Controller.from_port(port = 9051) as controller:
controller.authenticate(passwd)
controller.signal(Signal.NEWNYM)

#: Searching torrents
def search(self, query, page=1, category=None, sortBy=None, order='desc'):
query = '+'.join(query.split())
category = category.upper() if category and category.lower() in ['xxx', 'tv'] else category.capitalize() if category else None
url = f"{self.baseUrl}/{'sort-' if sortBy else ''}{'category-' if category else ''}search/{query}/{category+'/' if category else ''}{sortBy.lower()+'/' if sortBy else ''}{order.lower()+'/' if sortBy else ''}{page}/"

response = self.requests.get(url, headers=self.headers)
response = self.requests.get(url, headers=self.headers, proxies=self.tor_proxies)

return parser.torrentParser(response, baseUrl=self.baseUrl, page=page)

#: Trending torrents
def trending(self, category=None, week=False):
url = f"{self.baseUrl}/trending{'-week' if week and not category else ''}{'/w/'+category.lower()+'/' if week and category else '/d/'+category.lower()+'/' if not week and category else ''}"

response = self.requests.get(url, headers=self.headers)
response = self.requests.get(url, headers=self.headers, proxies=self.tor_proxies)

return parser.torrentParser(response, baseUrl=self.baseUrl)

#: Top 100 torrents
def top(self, category=None):
category = 'applications' if category and category.lower() == 'apps' else 'television' if category and category.lower() == 'tv' else category.lower() if category else None
url = f"{self.baseUrl}/top-100{'-'+category if category else ''}"

response = self.requests.get(url, headers=self.headers)
response = self.requests.get(url, headers=self.headers, proxies=self.tor_proxies)

return parser.torrentParser(response, baseUrl=self.baseUrl)

#: Popular torrents
def popular(self, category, week=False):
url = f"{self.baseUrl}/popular-{category.lower()}{'-week' if week else ''}"

response = self.requests.get(url, headers=self.headers)
response = self.requests.get(url, headers=self.headers, proxies=self.tor_proxies)

return parser.torrentParser(response, baseUrl=self.baseUrl)

#: Browse torrents by category type
def browse(self, category, page=1):
category = category.upper() if category.lower() in ['xxx', 'tv'] else category.capitalize()
url = f'{self.baseUrl}/cat/{category}/{page}/'

response = self.requests.get(url, headers=self.headers)
response = self.requests.get(url, headers=self.headers, proxies=self.tor_proxies)

return parser.torrentParser(response, baseUrl=self.baseUrl, page=page)

#: Info of torrent
Expand All @@ -66,6 +99,7 @@ def info(self, link=None, torrentId=None):
raise TypeError('Got an unexpected argument: Pass either link or torrentId')

link = f'{self.baseUrl}/torrent/{torrentId}/h9/' if torrentId else link
response = self.requests.get(link, headers=self.headers)

response = self.requests.get(link, headers=self.headers, proxies=self.tor_proxies)

return parser.infoParser(response, baseUrl=self.baseUrl)
16 changes: 8 additions & 8 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@

setuptools.setup(
name="1337x",
version="1.2.4",
author="Hemanta Pokharel",
author_email="hemantapkh@yahoo.com",
description="Unofficial API of 1337x.to",
version="1.0.0",
author="LeGeRyChEeSe",
author_email="kilian.douarinou41@gmail.com",
description="Unofficial API of 1337x.to with Tor implementation",
long_description=readme,
long_description_content_type="text/markdown",
install_requires=["requests", "bs4", "requests-cache"],
url="https://github.com/hemantapkh/1337x",
install_requires=["requests", "requests[socks]", "requests[security]", "bs4", "requests-cache", "fake_useragent", "stem"],
url="https://github.com/LeGeRyChEeSe/1337x",
project_urls={
"Documentation": "https://github.com/hemantapkh/1337x/blob/main/README.md",
"Issue tracker": "https://github.com/hemantapkh/1337x/issues",
"Documentation": "https://github.com/LeGeRyChEeSe/1337x/blob/main/README.md",
"Issue tracker": "https://github.com/LeGeRyChEeSe/1337x/pulls",
},
packages=setuptools.find_packages(),
classifiers=[
Expand Down