-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
karapoi
committed
Jul 1, 2023
0 parents
commit baf00fc
Showing
12 changed files
with
1,598 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
config/ | ||
log/ | ||
torrents/ | ||
test/ | ||
data*/ | ||
upload/ | ||
__pycache__/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[submodule "gog-games"] | ||
path = gog-games | ||
url = https://github.com/GOG-Games-com/GOG.com-Game-Collection-Verification |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
# bug: a tale of paper: refold | ||
# bug: cookie导入但未能登录 | ||
import configparser | ||
import csv | ||
import datetime | ||
from time import strftime | ||
import json | ||
|
||
class Configuration: | ||
def __init__(self): | ||
self.get_config() | ||
|
||
self.ignored_entries = [] | ||
self.completed_entries = [] | ||
|
||
self.records_file = 'log/records.csv' | ||
self.records = [] | ||
|
||
def get_config(self): | ||
with open('config/cookies.json', 'r') as r: | ||
self.cookies = json.load(r) | ||
self.pter_cookies = self.cookies['pter'] | ||
self.pic_cookies = self.cookies['pic'] | ||
|
||
config = configparser.ConfigParser() | ||
config.read('config/config.ini') | ||
self.upload_dir_on = (config['MODE']['upload_dir_on'] == 'True') | ||
self.hlink_on = (config['MODE']['hlink_on'] == 'True') | ||
self.proxies = config['MODE']['proxies'] | ||
self.use_pic_host = (config['MODE']['use_pic_host'] == 'True') | ||
self.check_compressed = (config['MODE']['check_compressed'] == 'True') | ||
self.comment = config['MODE']['comment'] | ||
self.passkey = config['PTER']['passkey'] | ||
self.announce = 'https://tracker.pterclub.com:443/announce?passkey=' + self.passkey | ||
self.anonymous = 'yes' if config['PTER']['anonymous'] == 'True' else 'no' | ||
self.torrent_dir = config['WORKDIR']['torrent_dir'] | ||
self.data_dir = config['WORKDIR']['data_dir'] | ||
self.upload_dir = config['WORKDIR']['upload_dir'] | ||
self.seed = (config['MODE']['seed'] == 'True') | ||
self.client_type = config['CLIENT']['type'] | ||
self.client_ip = config['CLIENT']['ip'] | ||
self.client_port = config['CLIENT']['port'] | ||
self.client_username = config['CLIENT']['username'] | ||
self.client_password = config['CLIENT']['password'] | ||
self.save_path = config['CLIENT']['save_path'] | ||
|
||
def add_ignored_entry(self, entry_path): | ||
if entry_path: | ||
if not entry_path in self.ignored_entries: | ||
self.ignored_entries.append(entry_path) | ||
|
||
def remove_ignored_entry(self, entry_path): | ||
if entry_path: | ||
if entry_path in self.ignored_entries: | ||
self.ignored_entries.remove(entry_path) | ||
|
||
def add_completed_entry(self, entry_path): | ||
if entry_path: | ||
if not entry_path in self.completed_entries: | ||
self.completed_entries.append(entry_path) | ||
|
||
def remove_completed_entry(self, entry_path): | ||
if entry_path: | ||
if entry_path in self.completed_entries: | ||
self.completed_entries.remove(entry_path) | ||
|
||
def add_record(self, entry): | ||
header = ['时间', '条目', '结果', '备注信息'] | ||
data = [{'时间':datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), '条目':entry.path, '结果':entry.status, '备注信息':entry.info}] | ||
self.records.append(data) | ||
with open(self.records_file, mode='a', encoding='utf-8-sig', newline='') as record_f: | ||
writer = csv.DictWriter(record_f, header) | ||
writer.writerows(data) |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import os | ||
import re | ||
import utils | ||
|
||
class GameHashTable(): | ||
def __init__(self, logger): | ||
self.logger = logger | ||
|
||
self.src_dir = 'gog-games' | ||
self.src = os.path.join(self.src_dir, 'gog_collection.sfv') | ||
self.version = '' | ||
self.htable = {} | ||
self.ntable = {} | ||
self._get_repo() | ||
self._gen_hash_table() | ||
|
||
# pull git repo | ||
def _get_repo(self): | ||
pass | ||
#if not os.path.exists(self.src_dir): | ||
# self.logger.info('-------- Cloning gog game repo ------------') | ||
# os.system('git clone https://github.com/GOG-Games-com/GOG.com-Game-Collection-Verification') | ||
# self.logger.info('----------------- Done --------------------') | ||
#else: | ||
# self.logger.info('-------- Updating gog game repo ------------') | ||
# os.system('cd ' + self.src_dir + '; git fetch; git merge origin/main') | ||
# self.logger.info('----------------- Done --------------------') | ||
|
||
# create hash-game table from sfv file | ||
def _gen_hash_table(self): | ||
with open(self.src) as f: | ||
lines = f.readlines() | ||
for line in lines: | ||
line = line.strip() | ||
if line: | ||
file_hash = re.split('\s+', line) | ||
if len(file_hash) == 2: | ||
file = file_hash[0] | ||
crc = file_hash[1] | ||
game_filename = file.split('/', 1) | ||
if len(game_filename) == 2: | ||
game = game_filename[0] | ||
filename = game_filename[1] | ||
self.htable[crc] = game | ||
self.ntable[filename] = game | ||
else: | ||
print('Failed to parse line:' + line) | ||
self.version = os.popen('cd ' + self.src_dir + '; git rev-parse HEAD').read() | ||
|
||
def update(self): | ||
self._get_repo() | ||
cur_version = os.popen('cd ' + self.src_dir + '; git rev-parse HEAD').read() | ||
if cur_version != self.version: | ||
self._gen_hash_table() | ||
|
||
def search(self, crc): | ||
crc = crc.lower() | ||
if crc in self.htable.keys(): | ||
return self.htable[crc] | ||
else: | ||
return '' | ||
|
||
def guess(self, game): | ||
print(game) | ||
for k in self.ntable.keys(): | ||
if game in k: | ||
print('猜测到可能的游戏名为:', self.ntable[k]) | ||
right = utils.check_yes('是否正确[Y/[N]:') | ||
if right: | ||
return self.ntable[k] | ||
return '' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
# gog2pter快捷转种工具<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->[](#contributors-)<!-- ALL-CONTRIBUTORS-BADGE:END --> | ||
|
||
# 重要提示 Important Note | ||
```diff | ||
- 请勿以任何方式在此求邀(包括但不限于issue、discussion、PR) | ||
|
||
- Plese don't ask for any invite here, this is not your place! | ||
``` | ||
|
||
## 简介 | ||
|
||
该脚本能够在检测gog games下载的文件后自动获取相关信息并制作种子,同时自动将种子上传至PTerClub | ||
|
||
--- | ||
## 工具特点 | ||
* 自动分析指定目录下的游戏文件,分析获取游戏名 | ||
* 自动制种,方便配合BT客户端实现自动做种 | ||
* 自动从gog商店获取游戏信息 | ||
* 自动新建PTer游戏条目 | ||
* 自动上传游戏种子 | ||
* 支持 `游戏本体` `Goodies`分别自动制种 | ||
|
||
## 依赖环境 | ||
|
||
### python模式 | ||
|
||
* Python 3 | ||
* Git | ||
* Mac, Linux, Windows | ||
|
||
## 安装指南 | ||
|
||
### Python 模式 | ||
|
||
#### 1.克隆我的仓库 | ||
由于项目依赖于GOG-Games-com/GOG.com-Game-Collection-Verification,请添加--recursive选项 | ||
~~~~shell | ||
git clone --recursive https://github.com/karapoi/gog2pter.git | ||
~~~~ | ||
#### 2.安装相关依赖 | ||
~~~~shell | ||
pip install -r requirements.txt | ||
~~~~ | ||
如果你无法安装的话可能是你的用户权限不够,尝试使用`sudo`安装;对于某些同时装有`python2` 与 `python3` 的用户,可能需要指明`pip`的版本,如 `pip3` | ||
~~~~shell | ||
sudo -H pip install -r requirements.txt | ||
~~~~ | ||
#### 3.运行使用 | ||
##### 3.1 gog2pter | ||
~~~~shell | ||
mkdir config | ||
python main.py | ||
~~~~ | ||
另外可以使用以下命令来查看可以的命令选项和说明: | ||
~~~~shell | ||
python main.py --help | ||
~~~~ | ||
##### 3.2 find games | ||
发现可能尚未发布的游戏,注意最好发布前再手动搜索确认一次~ | ||
需要完成gog2pter的配置后才能使用。 | ||
~~~~shell | ||
python find_games.py | ||
~~~~ | ||
## 使用指南 | ||
|
||
### 1.填写配置信息 | ||
第一次运行时,程序会让你填写一些配置信息,按照实际情况填写即可: | ||
* 猫站`cookies` | ||
* 猫站`passkey` | ||
* 匿名选项 | ||
* 数据目录(即自动检测的目录) | ||
* 是否启用上传目录(强烈建议同硬链接模式一同启用) | ||
* 是否启用硬链接模式(强烈建议启用) | ||
* 种子目录(种子的保存目录) | ||
|
||
### 2 填写cookies | ||
第一次运行程序时,程序会让你输入猫站的cookies,按照提示输入即可: | ||
 | ||
cookies在登录猫站的情况下,按F12打开调试窗口,在控制台中输入document.cookie即可获得,注意不包括前后的引号。 | ||
也可按照常见问题所述方法获取。 | ||
|
||
### 3.等待程序运行 | ||
|
||
### 4.选择游戏信息 | ||
如果程序认为将要上传的种子的游戏信息可能已经存在于猫站,会返回一个列表让你选择游戏信息,如果不存在相关游戏的话,系统会自动上传到猫站。 | ||
```shell | ||
我们在猫站找到以下游戏,请选择要上传的游戏分组(输入编号(并非gid)即可,如果没有请输入0): | ||
1.Windows: Cooking Simulator GID:3409 | ||
编号: <输入编号> | ||
``` | ||
|
||
### 5.输入种子额外信息 | ||
由于无法从gog获取游戏地区的相关信息,需要用户手动输入: | ||
 | ||
|
||
### 6.审查种子标题 | ||
脚本会自动检测主安装文件(即文件夹下符合set_*.exe命名的名字最短的文件)的名字并生成符合猫站规则的标题,但是仍然需要用户进行检查。如果有错误请输入正确的标题,无误则直接回车。 | ||
|
||
### 7.上传Goodies | ||
脚本会自动检测目录下的zip或rar文件,并将其视作Goodies单独建立文件夹,单独制种,单独上传,其标题也需要用户进行检查。如果有错误请输入正确的标题,无误则直接回车。 | ||
|
||
### 8.上传完成 | ||
|
||
## 常见问题 | ||
* Q. cookies 是个什么东西呀?怎么获取呀? | ||
* A. cookie 是来存储你登陆信息的一串字符,下面我以firefox为例演示一下怎么获取。 | ||
* * 按下F12进入开发者工具,并切换至`NETWORK/网络`栏目: | ||
* *  | ||
* * 单击你左上角的用户名,载入你的用户界面 | ||
* * 找到`NEWWORK/网络`栏目里加载出来的user.php之类文件,并单击它: | ||
* *  | ||
* * 找到`request header/请求头` 中cookie项目中的字段并复制下来: | ||
* *  | ||
|
||
--> | ||
|
||
## 贡献者 ✨ | ||
|
||
脚本编写过程中大量参考了[ggn2pter](https://github.com/inerfire/ggn2pter),同时,部分内容参考了[happyfunc](https://github.com/inerfire/happyfunc)在此对原作者提出感谢。 | ||
|
||
感谢以下诸位的共同协作: | ||
|
||
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --> | ||
<!-- prettier-ignore-start --> | ||
<!-- markdownlint-disable --> | ||
<table> | ||
<tr> | ||
<td align="center"><a href="https://github.com/karapoi"><img src="https://avatars.githubusercontent.com/u/9048968?v=4?s=100" width="100px;" alt=""/><br /><sub><b>karapoi</b></sub></a><br /><a href="https://github.com/karapoi/gog2pter/commits?author=karapoi" title="Code">💻</a></td> | ||
</tr> | ||
</table> | ||
|
||
<!-- markdownlint-restore --> | ||
<!-- prettier-ignore-end --> | ||
|
||
<!-- ALL-CONTRIBUTORS-LIST:END --> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import requests | ||
import re | ||
from bs4 import BeautifulSoup | ||
import json | ||
import time | ||
import random | ||
|
||
HEADERS = { | ||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0', | ||
'Accept': 'application/json, text/javascript, */*; q=0.01', | ||
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2', | ||
'X-Requested-With': 'XMLHttpRequest', | ||
'Connection': 'keep-alive', | ||
'Pragma': 'no-cache', | ||
'Cache-Control': 'no-cache', } | ||
|
||
PTER_DOMAIN = 'https://pterclub.com/' | ||
|
||
class PTerApi: | ||
def __init__(self): | ||
self.session = requests.Session() | ||
self.session.headers = HEADERS | ||
with open('config/cookies.json', 'r') as r: | ||
self.cookies = json.load(r) | ||
self.cookies = self.cookies['pter'] | ||
self._install_cookies() | ||
|
||
# 加载cookie到session | ||
def _install_cookies(self): | ||
self.session.headers.update({'Referer': PTER_DOMAIN}) | ||
cookies = dict([field.split('=', 1) for field in self.cookies.split('; ')]) | ||
self.session.cookies = requests.utils.cookiejar_from_dict(cookies) | ||
|
||
def find_game(self, name): | ||
# 搜索游戏 | ||
url = PTER_DOMAIN + 'searchgameinfo.php' | ||
data = {'name': name} | ||
res = self.session.post(url, data=data) | ||
res_soup = BeautifulSoup(res.text, 'lxml') | ||
game_list = res_soup.select('a[title="点击发布这游戏设备的种子"]') | ||
platform_list = res_soup.select('img[src^="/pic/category/chd/scenetorrents/"]') | ||
if not game_list: | ||
return False | ||
else: | ||
return True | ||
#game_dict = {} | ||
#num = 1 | ||
## 获取游戏列表 | ||
#for game, platform in zip(game_list[::2], platform_list): | ||
# gid = re.search(r'detailsgameinfo.php\?id=(\d+)', game['href']).group(1) | ||
# game_dict[str(num)] = '{}: {} GID:{}'.format(platform['title'], game.text, gid) | ||
# num += 1 | ||
## 选择上传的目标游戏 | ||
#print('我们在猫站找到以下游戏:') | ||
#for num, game in game_dict.items(): | ||
# print('{}.{}'.format(num, game)) | ||
|
||
def main(): | ||
games = [] | ||
with open('gog-games/gog_collection.sfv') as f: | ||
lines = f.readlines() | ||
for line in lines: | ||
line = line.strip() | ||
if line: | ||
file_hash = re.split('\s+', line) | ||
if len(file_hash) == 2: | ||
file = file_hash[0] | ||
crc = file_hash[1] | ||
game_filename = file.split('/', 1) | ||
if len(game_filename) == 2: | ||
game = game_filename[0] | ||
if len(game) > 4: | ||
game = game.replace('_', ' ') | ||
if not game in games: | ||
games.append(game) | ||
pter = PTerApi() | ||
print('正在查找尚未发布的游戏...') | ||
start = random.randint(1, len(games)) | ||
for i in range(start, len(games)): | ||
game = games[i] | ||
time.sleep(3) | ||
if pter.find_game(game): | ||
continue | ||
else: | ||
print('发现以下游戏可能尚未发布:' + game) | ||
if input('是否继续,继续直接回车:'): | ||
break | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
Oops, something went wrong.