~skiqqy/bin

bin/walls -rwxr-xr-x 4.4 KiB
c0954778Stephen Cochrane Prog on deploy 2 days ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
#!/bin/bash
# Author: https://github.com/skiqqy
# This script will fetch pictures from a thread from 4chan and test them for wallpapers.

# Our variables
VERSION="v1.0"
declare -A threads # Hashmap of title to thread id
titles=() # Array containing titles from the catalog

usage ()
{
	cat << EOF
walls $VERSION ~ The easy way to browse 4chan wallpapers.

Usage: walls [options]

options
-------

-h                 Shows this message.
-b <board>         Specify the board.
-t <n>             Only fetch the top n threads.
-a                 Fetch all threads.
-u                 Test wallpapers using setwp (found here https://github.com/skiqqy/bin/blob/master/setwp).
-o <number>        Open the first n wallpapers in your browser.
-s <thread>        Specify a thread to use.

Written by skiqqy.
EOF
}

# Fetch links to pictures from a thread.
# Usage: thread_pics <board> <thread_nr>
# TODO: Improve thise regex, grep was being wierd with \w etc, hence the scuffed version below.
thread_pics ()
{
	res=$(curl -s https://boards.4chan.org/"$1"/thread/"$2" | \
		grep -o -E "href=\"[/\.a-zA-Z0-9]*\.(jpg|png)\"" | uniq)
	for l in $res
	do
		url=$(echo "$l" | cut -d= -f 2)
		url="https:${url//\"}"
		echo "$url"
	done
}

# Get the title of a thread from a board
# Usage: thread_title <board> <thread>
# Prints: <Thread Title>:
# TODO: Improve thise regex, grep was being wierd with \w etc, hence the scuffed version below.
thread_title ()
{
	res=$(curl -s https://boards.4chan.org/"$1"/thread/"$2" | \
		grep -o -E "<span class=\"subject\">[/\\\.a-zA-Z0-9\ ]*</span>" | head -1)
	res=$(echo "$res" | cut -d ">" -f 2 | cut -d "<" -f 1)
	[ -n "$res" ] && echo "$res:$2"
}

# Fetch threads from a board
# Usage: board_threads <board>
board_threads ()
{
	curl -s https://a.4cdn.org/"$1"/catalog.json | jq '.[].threads[].no'
}

print_tui ()
{
	clear # Clear the screen so that the printing looks nice
	echo "To exit type 'EXIT'"
	echo -e "-------------------\n"

	i=0
	for title in "${titles[@]}"
	do
		echo "$i. $title"
		((i++))
	done
	echo
}

# Print the list of threads with thier title, ask the user which thread they want, and return the result
get_thread ()
{
	read -r -p "Index: " index
	if [[ "$index" =~ ^(exit)|(EXIT)$ ]]
	then
		return 1
	fi
	# We check that the input is a number and it is in the correct range, else we exit.
	if [[ ! "$index" =~ ^[0-9]+$ ]] || [ "$index" -lt 0 ] || [ "$index" -ge "$cnt" ] # Short circuiting
	then
		return 2
	fi

	index=${titles[$index]}
	echo "${threads[$index]}"
}

# Iterate over the links found in $links
use_links ()
{
	# Safety stuff I dont nuke my ram by opening alot of links.
	if [ -n "$open" ]
	then
		tmp=( $links ) # I want splitting
		n=$((${#tmp[@]} - 1))

		if [ "$open" -gt "$n" ]
		then
			open="$n"
		fi

		read -r -p "[WARNING] This will open $open link(s), proceed Y/N? " input
		[[ ! $input =~ ^y|Y(es)?$ ]] && exit
	fi

	i=0
	for link in $links
	do
		if [ -n "$open" ]
		then
			[ "$i" -eq "$open" ] && exit
			echo "Opening $link"
			xdg-open "$link"
			((i++))
		elif [ -n "$apply" ]
		then
			setwp "$link"
		else
			echo "$link" # This is just for debugging.
		fi
	done
}

# Spawn the tui
tui ()
{
	print_tui

	thread=$(get_thread)
	case $? in
		1)
			echo "Goodbye!"
			exit
			;;
		2)
			if [ "$cnt" -eq 1 ]
			then
				range="{0}"
			else
				range="[0 , $((cnt-1))]"
			fi
			echo "Invalid input, expecting an integer in the set $range."
			exit 2
		;;
	esac

	links=$(thread_pics "$board" "$thread")
	use_links
}

# Entry point
main ()
{
	# Vars
	board=wg
	top=3 # Fetch top 3 by default.
	cnt=0
	open=
	apply=
	thread=

	while getopts "hb:t:auo:s:" opt
	do
		case $opt in
			h)
				usage
				exit 0
				;;
			b)
				board="$OPTARG"
				;;
			t)
				top="$OPTARG"
				;;
			a)
				top=
				;;
			u)
				apply=1
				;;
			o)
				open="$OPTARG"
				;;
			s)
				thread="$OPTARG"
				;;
			*)
				usage
				exit 1
				;;
		esac
	done

	if [ -z "$thread" ]
	then
		# First we map thread titles to thier respective threads for later use.
		res=$(board_threads "$board")

		for r in $res
		do
			if [ -n "$top" ] && [ "$cnt" -ge "$top" ]
			then
				break # We have fetched the top n, hence exit
			fi
			res=$(thread_title "$board" "$r")
			title=$(echo "$res" | cut -d ":" -f 1)
			thread=$(echo "$res" | cut -d ":" -f 2)
			if [ -z "$thread" ] || [ -z "$title" ]
			then
				continue
			fi
			titles+=( "$title" )
			threads[$title]="$thread"
			((cnt++))
		done

		for ((;;))
		do
			tui
		done
	else
		links=$(thread_pics "$board" "$thread")
		use_links
	fi
}

main "$@"