Completed
Push — master ( febe31...ca2a85 )
by Angus
02:52
created

WebToons::handleCustomFollow()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 10
nc 1
nop 3
dl 0
loc 16
ccs 0
cts 0
cp 0
crap 2
rs 9.4285
c 0
b 0
f 0
1
<?php declare(strict_types=1); defined('BASEPATH') OR exit('No direct script access allowed');
2
3
class WebToons extends Base_Site_Model {
4
	/* Webtoons.com has a very weird and pointless URL format.
5
	   TITLE URL:   /#LANG#/#GENRE#/#TITLE#/list?title_no=#TITLEID#
6
	   RSS URL:     /#LANG#/#GENRE#/#TITLE#/rss?title_no=#TITLEID#
7
	   CHAPTER URL: /#LANG#/#GENRE#/#TITLE#/#CHAPTER#/viewer?title_no=#TITLEID#&episode_no=#CHAPTERID#
8
9
	   For both the title and chapter URLs, only the TITLEID and CHAPTERID are needed. Everything else can be anything at all (Well, alphanumeric at least).
10
	   The RSS URL however, requires everything to be exactly correct. I have no idea why this is, but it does mean we need to store all that info too.
11
	   We <could> not use the RSS url, and just parse via the title url, but rss is much better in the long run as it shouldn't change much.
12
13
	   FORMATS:
14
	   TITLE_URL: ID:--:LANG:--:TITLE:--:GENRE
15
	   CHAPTER:   ID:--:CHAPTER_N
16
	*/
17
	//private $validLang = ['en', 'zh-hant', 'zh-hans', 'th', 'id'];
18
19
	public $titleFormat   = '/^[0-9]+:--:(?:en|zh-hant|zh-hans|th|id):--:[a-z0-9-]+:--:(?:drama|fantasy|comedy|action|slice-of-life|romance|superhero|thriller|sports|sci-fi)$/';
20
	public $chapterFormat = '/^[0-9]+:--:.*$/';
21
22
	public function getFullTitleURL(string $title_url) : string {
23
		$title_parts = explode(':--:', $title_url);
24
		return "http://www.webtoons.com/{$title_parts[1]}/{$title_parts[3]}/{$title_parts[2]}/list?title_no={$title_parts[0]}";
25
	}
26
27
	public function getChapterData(string $title_url, string $chapter) : array {
28
		$title_parts   = explode(':--:', $title_url);
29
		$chapter_parts = explode(':--:', $chapter);
30
31
		return [
32
			'url'    => "http://www.webtoons.com/{$title_parts[1]}/{$title_parts[3]}/{$title_parts[2]}/{$chapter_parts[1]}/viewer?title_no={$title_parts[0]}&episode_no={$chapter_parts[0]}",
33
			'number' => $chapter_parts[1] //TODO: Possibly replace certain formats in here? Since webtoons doesn't have a standard chapter format
34
		];
35
	}
36
37
	public function getTitleData(string $title_url, bool $firstGet = FALSE) {
38
		$titleData = [];
39
40
		//FIXME: We don't use parseTitleDOM here due to using rss. Should probably have an alternate method for XML parsing.
41
42
		//NOTE: getTitleData uses a different FullTitleURL due to it grabbing the rss ver. instead.
43
		$title_parts = explode(':--:', $title_url);
44
		$fullURL = "http://www.webtoons.com/{$title_parts[1]}/{$title_parts[3]}/{$title_parts[2]}/rss?title_no={$title_parts[0]}";
45
46
		$content = $this->get_content($fullURL);
47
		$data = $content['body'];
48
		if($data !== 'Can\'t find the manga series.') { //FIXME: We should check for he proper error here.
49
			$xml = simplexml_load_string($data) or die("Error: Cannot create object");
50
			if(isset($xml->{'channel'}->item[0])) {
51
				$titleData['title'] = trim((string) $xml->{'channel'}->title);
52
53
				$chapterURLSegments = explode('/', ((string) $xml->{'channel'}->item[0]->link));
54
				$titleData['latest_chapter'] = preg_replace('/^.*?([0-9]+)$/', '$1', $chapterURLSegments[7]) . ':--:' . $chapterURLSegments[6];
55
				$titleData['last_updated'] =  date("Y-m-d H:i:s", strtotime((string) $xml->{'channel'}->item[0]->pubDate));
56
57
				if($firstGet) {
58
					$titleData = array_merge($titleData, $this->doCustomFollow($content['body'], ['id' => $title_parts[0]]));
59
				}
60
			}
61
		} else {
62
			log_message('error', "Series missing? (WebToons): {$title_url}");
63
			return NULL;
64
		}
65
66
		return (!empty($titleData) ? $titleData : NULL);
67
	}
68
69
	public function handleCustomFollow(callable $callback, string $data = "", array $extra = []) {
70
		$formData = [
71
			'titleNo'       => $extra['id'],
72
			'currentStatus' => 'false',
73
			'promotionName' => ''
74
		];
75
76
		$cookies = [
77
			"NEO_SES={$this->config->item('webtoons_cookie')}"
78
		];
79
		$content = $this->get_content('http://www.webtoons.com/setFavorite?'.http_build_query($formData), implode("; ", $cookies), "", TRUE);
80
81
		$callback($content, $extra['id'], function($body) {
82
			return strpos($body, '"favorite":true') !== FALSE;
83
		});
84
	}
85
	public function doCustomUpdate() {
86
		/*$titleDataList = [];
87
88
		$cookies = [
89
			"NEO_SES={$this->config->item('webtoons_cookie')}"
90
		];
91
		$content = $this->get_content('http://www.webtoons.com/favorite', implode("; ", $cookies), "", TRUE);
92
93
		if(!is_array($content)) {
94
			log_message('error', "{$this->site} /favorite | Failed to grab URL (See above curl error)");
95
		} else {
96
			$headers     = $content['headers'];
97
			$status_code = $content['status_code'];
98
			$data        = $content['body'];
99
100
			if(!($status_code >= 200 && $status_code < 300)) {
101
				log_message('error', "{$this->site} /favorite | Bad Status Code ({$status_code})");
102
			} else if(empty($data)) {
103
				log_message('error', "{$this->site} /favorite | Data is empty? (Status code: {$status_code})");
104
			} else {
105
				$data = preg_replace('/^[\s\S]+<\!-- container -->/', '<!-- container -->', $data);
106
				$data = preg_replace('/<\!-- \/\/container -->[\s\S]+$/', '<!-- //container -->', $data);
107
108
				$dom = new DOMDocument();
109
				libxml_use_internal_errors(TRUE);
110
				$dom->loadHTML($data);
111
				libxml_use_internal_errors(FALSE);
112
113
				$xpath      = new DOMXPath($dom);
114
				$nodes_rows = $xpath->query("//ul[@id='_webtoonList']/li/a");
115
				if($nodes_rows->length > 0) {
116
					foreach($nodes_rows as $row) {
117
						$titleData = [];
118
119
						$nodes_title   = $xpath->query("span[@class='update']", $row);
120
						$nodes_chapter = $xpath->query("dl/dt[1]/a[@class='chapter']", $row);
121
						$nodes_latest  = $xpath->query("span[@class='update']", $row);
122
123
						print $nodes_latest->length;
124
						if($nodes_title->length === 1 && $nodes_chapter->length === 1 && $nodes_latest->length === 1) {
125
					//		$title = $nodes_title->item(0);
126
					//
127
					//		$titleData['title'] = trim($title->textContent);
128
					//
129
					//
130
					//		$link = preg_replace('/^(.*\/)(?:[0-9]+\.html)?$/', '$1', (string) $nodes_chapter->item(0)->getAttribute('href'));
131
					//		$chapterURLSegments = explode('/', $link);
132
					//		$titleData['latest_chapter'] = $chapterURLSegments[5] . (isset($chapterURLSegments[6]) && !empty($chapterURLSegments[6]) ? "/{$chapterURLSegments[6]}" : "");
133
					//
134
					//		$titleData['last_updated'] =  date("Y-m-d H:i:s", strtotime((string) $nodes_latest->item(0)->nodeValue));
135
					//
136
					//		$title_url = explode('/', $title->getAttribute('href'))[4];
137
					//		$titleDataList[$title_url] = $titleData;
138
						} else {
139
					//		log_message('error', "{$this->site}/Custom | Invalid amount of nodes (TITLE: {$nodes_title->length} | CHAPTER: {$nodes_chapter->length}) | LATEST: {$nodes_latest->length})");
140
						}
141
					}
142
				} else {
143
					log_message('error', '{$this->site} | Following list is empty?');
144
				}
145
			}
146
		}
147
		return $titleDataList;*/
148
	}
149
	public function doCustomCheck(string $oldChapterString, string $newChapterString) {}
150
}
151