Skip to content
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
144 changes: 144 additions & 0 deletions Magnet_To_Torrent2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
#!/usr/bin/env python
'''
Created on Apr 19, 2012
@author: dan, Faless

GNU GENERAL PUBLIC LICENSE - Version 3

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.

http://www.gnu.org/licenses/gpl-3.0.txt

'''

import shutil
import tempfile
import os.path as pt
import sys
import libtorrent as lt
from time import sleep
from argparse import ArgumentParser


def magnet2torrent(magnet, output_name=None):
if output_name and \
not pt.isdir(output_name) and \
not pt.isdir(pt.dirname(pt.abspath(output_name))):
print("Invalid output folder: " + pt.dirname(pt.abspath(output_name)))
print("")
sys.exit(0)

tempdir = tempfile.mkdtemp()
ses = lt.session()
params = {
'save_path': tempdir,
'storage_mode': lt.storage_mode_t(2),
'paused': False,
'auto_managed': True,
'duplicate_is_error': True
}
handle = lt.add_magnet_uri(ses, magnet, params)

print("Downloading Metadata (this may take a while)")
while (not handle.has_metadata()):
try:
sleep(1)
except KeyboardInterrupt:
print("Aborting...")
ses.pause()
print("Cleanup dir " + tempdir)
shutil.rmtree(tempdir)
sys.exit(0)
ses.pause()
print("Done")

torinfo = handle.get_torrent_info()
torfile = lt.create_torrent(torinfo)

output = pt.abspath(torinfo.name() + ".torrent")

if output_name:
if pt.isdir(output_name):
output = pt.abspath(pt.join(
output_name, torinfo.name() + ".torrent"))
elif pt.isdir(pt.dirname(pt.abspath(output_name))):
output = pt.abspath(output_name)

print("Saving torrent file here : " + output + " ...")
torcontent = lt.bencode(torfile.generate())
f = open(output, "wb")
f.write(lt.bencode(torfile.generate()))
f.close()
print("Saved! Cleaning up dir: " + tempdir)
ses.remove_torrent(handle)
shutil.rmtree(tempdir)

return output

def main():
parser = ArgumentParser(description="A command line tool that converts magnet links in to .torrent files")
parser.add_argument('-m','--magnet', help='The magnet url')
parser.add_argument('-o','--output', help='The output torrent file name')

#
# This second parser is created to force the user to provide
# the 'output' arg if they provide the 'magnet' arg.
#
# The current version of argparse does not have support
# for conditionally required arguments. That is the reason
# for creating the second parser
#
# Side note: one should look into forking argparse and adding this
# feature.
#
conditionally_required_arg_parser = ArgumentParser(description="A command line tool that converts magnet links in to .torrent files")
conditionally_required_arg_parser.add_argument('-m','--magnet', help='The magnet url')
conditionally_required_arg_parser.add_argument('-o','--output', help='The output torrent file name', required=True)

magnet = None
output_name = None

#
# Attempting to retrieve args using the new method
#
args = vars(parser.parse_known_args()[0])
if args['magnet'] is not None:
magnet = args['magnet']
argsHack = vars(conditionally_required_arg_parser.parse_known_args()[0])
output_name = argsHack['output']
if args['output'] is not None and output_name is None:
output_name = args['output']
if magnet is None:
#
# This is a special case.
# This is when the user provides only the "output" args.
# We're forcing him to provide the 'magnet' args in the new method
#
print ('usage: {0} [-h] [-m MAGNET] -o OUTPUT'.format(sys.argv[0]))
print ('{0}: error: argument -m/--magnet is required'.format(sys.argv[0]))
sys.exit()
#
# Defaulting to the old of doing things
#
if output_name is None and magnet is None:
if len(sys.argv) >= 2:
magnet = sys.argv[1]
if len(sys.argv) >= 3:
output_name = sys.argv[2]

magnet2torrent(magnet, output_name)


if __name__ == "__main__":
main()
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ The result will be something like :

The href portion contains the page where the torrent link is. Since this is a new torrent, we scrape that page using the function "scrape\_page"

The last step is to simply use wget to download the torrent file that is linked. We specify the directory in the "static/config.json" file for each differnt race.
The last step is to simply use wget or Dan Folkes "Magnet\_To\_Torrent2" module to convert the magnet to a torrent, and then to download the torrent file that is linked. We specify the directory in the "static/config.json" file for each differnt race.

From there, rtorrent is used to download the file.

Rtorrent can also send notification when a download is complete. To do this we can simply use a bash file to call the "send\_email.py" script. That is the reason the call to main
Expand All @@ -47,6 +48,7 @@ login = {
"emailPass": "<SMTP LOGIN PASSWORD>",
"emailServer": "<SMTP SERVER>",
"emailPort": "<SMTP SERVER PORT>" }
}
```

In the file "static/config.json", you will need to specify the directories you would like the downloads to end up.
Expand Down
85 changes: 61 additions & 24 deletions check_races.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,13 @@
import re
import os
import subprocess
import glob
import shutil
import json

import update_json
import read_json
import send_email

import Magnet_To_Torrent2 as m2t

# vars
page = Request("https://www.ettv.tv/user/smcgill1969/index.html", headers={'User-Agent': 'Mozilla5/0'})
Expand All @@ -47,27 +46,31 @@
function to actually scrape where the torrent is from
the link that we read from the json file
'''
class scrape:

def scrape_page(page):
global torrent_file
def __init__(self,ettv_page):
self.page = Request(ettv_page,headers={'User-Agent': 'Mozilla5/0'})
self.webpage = urlopen(self.page).read()
self.soup = BeautifulSoup(self.webpage,'html.parser')
self.result = self.soup.find_all("a", class_="download_link")

for self.a in self.result:
self.torrent_title = self.a["class"]
self.torrent_file = self.a["href"]

page = Request(page,headers={'User-Agent': 'Mozilla5/0'})
webpage = urlopen(page).read()
soup = BeautifulSoup(webpage,'html.parser')
for a in soup.find_all("a", {"class":"download_link file"}):
torrent_file = a['href']
return(torrent_file)

'''
Main function will simply scrape the page finding where the MotoGP and F1 info is for Races, 2019 and in SD
Then we are going to grab that info and update the list in the JSON file /static/config.json
The config.json file is used to determine if the latest race is new or not
'''

def main():

formula1_watch = read_json.output_config()["formula1_watch_directory_base"]
motogp_watch = read_json.output_config()["motogp_watch_directory_base"]


for data in soup.find_all('table', class_='table table-hover table-bordered'):
for a in data.find_all('a'):
titles.append(a.get('title'))
Expand All @@ -90,43 +93,77 @@ def main():
if("Formula" in torrent_title):
formula1.append(torrent_title + " : " + "https://ettv.tv" + torrent_link)

'''
now that the lists are built we check to see if what is in the config file
is the same as the first entry in the list. If it is, we scrape the page.
If it's not, we need to do something so we just change the update status
to "no". This seems a bit of a hack because if there are no entries
to build the list, it errors. So I just added an exception to catch it
and do something.
'''
# MotoGP
try:
if(read_json.output_config()["motogp_title"] != str(motogp[0])):
update_json.updateJsonFile("motogp_title",motogp[0])
update_json.updateJsonFile("motogp_update","Yes")
motogp_output = read_json.output_config()["motogp_title"]
motogp_partition = (motogp_output.partition(":"))

scrape_page(motogp_partition[2])
subprocess.call(["wget",torrent_file,"-P",motogp_watch])
t = scrape(motogp_partition[2])
t_title = t.torrent_title
t_file = t.torrent_file

# check if there is a file or just a magnet
if(t_title[1] == "file"):
# here we can proceed with the wget method since we have
# an actual torrent file
print("Processing a torrent file...")
subprocess.call(["wget",t_file,"-P",motogp_watch])

if(t_title[1] == "magnet"):

#else:
# here we need to run a different process
# we can use the mag2torrent module to convert
# magnet to torrent and then move it to the
# proper watch folder
print("Processing a magnet...")
m2t.magnet2torrent(t_file, motogp_watch + motogp_partition[0].replace(" ","") + ".torrent")

update_json.updateJsonFile("motogp_update","No")
update_json.updateJsonFile("motogp_rtorrent_email","No")
send_email.send_email("TESTING AGAIN!!!",motogp[0])

send_email.send_email("New MotoGP Race",motogp[0])
except:
update_json.updateJsonFile("motogp_update","No")


# Formula 1
try:
if(read_json.output_config()["formula1_title"] != str(formula1[0])):
update_json.updateJsonFile("formula1_title",formula1[0])
update_json.updateJsonFile("formula1_update","Yes")
formula1_output = read_json.output_config()["formula1_title"]
formula1_partition = (formula1_output.partition(":"))

scrape_page(formula1_partition[2])
subprocess.call(["wget",torrent_file,"-P",formula1_watch])
t = scrape(formula1_partition[2])
t_title = t.torrent_title
t_file = t.torrent_file


# check if there is a file or just a magnet
if(t_title[1] == "file"):
# here we can proceed with the wget method since we have
# an actual torrent file
print("Processing a torrent file...")
subprocess.call(["wget",t_file,"-P",formula1_watch])

if(t_title[1] == "magnet"):

#else:
# here we need to run a different process
# we can use the mag2torrent module to convert
# magnet to torrent and then move it to the
# proper watch folder
print("Processing a magnet...")
m2t.magnet2torrent(t_file, formula1_watch + formula1_partition[0].replace(" ","") + ".torrent")

update_json.updateJsonFile("formula1_update","No")
update_json.updateJsonFile("formula1_rtorrent_email","No")

send_email.send_email("New Formula 1 Race", formula1[0])

except:
update_json.updateJsonFile("formula1_update","No")

Expand Down