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
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
#!/bin/sh
#danbooru-upload, a danbooru command line uploader, v0.1
#dingo, 20090314
#made for sankakucomplex, but might work with other danbooru sites
#based from danbooru api 1.13.0
#http://danbooru.donmai.us/help/api

### USER editable options ###
uploaderhome="$HOME/.danbooru"
config="$uploaderhome/danbooru-upload"
logfile="$uploaderhome/log.danbooru-upload"
### USER editable options END ###

site=
tags=
files=
rating=
sauce=
is_rating_locked=
is_note_locked=
version="Danbooru Shell Uploader/0.1"
useragent="$version ($(curl -V | head -1))"

usage()
{
cat << EOF
$version
syntax: $0 OPTIONS
Send files or source urls to a danbooru site with specified site.
Config file is set to: $config
OPTIONS
  -l site_name	Log in to site_name (to create cookies) Use first.
  -n site_name
		Site name in config file. Required
  -t "tags..."
		Tags, space-delimited.  Group with "". Required
  -f "files..."
		Files or URLs.  You can use wildcards- must use
		quotes ("").  Space-delimited.  Required.
		If you specify a URL, the URL is used as Source
		and no file is sent.
  -F		Read files from stdin
  -1 file
		Read one file.  String will be treated as one file.
		Helps if filename has spaces.
  -r [ safe | questionable | explicit ]
		Rating for the posts
  -s source	Source name
  -p id		The ID of the parent post
  -m md5	Supply an MD5 if you want Danbooru to verify the
		file after uploading. If the MD5 doesn't match,
		the post is destroyed. Can only be used with -1
  -R		Lock rating
  -N		Lock notes
  -h		Help and config file help

EOF
}

hlp(){
usage
cat << EOF
CONFIG FILE
	The config file is in a .ini-type format.  Create this file first.
	Config location is $uploaderhome/danbooru-upload
	[site_name]
	baseurl=http://www.example.com/danbooru
	username=exampleuser
	password=mypass

	[sc]
	baseurl=http://chan.sankakucomplex.com

	[my_danbooru]
	baseurl=http://example.net/danbooru
	username=me

	Do not use spaces for site names. For each [site_name], only
	baseurl is required.  You may exclude username or password,
	then the script will ask you for it when you log in.

EXAMPLES
	-Login command
	danbooru-upload -l sc

	-Typical single file upload
	danbooru-upload -n site_name -t "shitapai shimapan blue_eyes tagme" -f 001.jpg
	danbooru-upload -n site_name -t "shitapai shimapan blue_eyes tagme" -1 "filename with space.jpg"

	-HTTP source
	danbooru-upload -n sc -t "shiina megurine_luka_(toeto)" -f "http://image.blog.livedoor.jp/f_2nd2005/imgs/5/3/53cdb1da.jpg" -r safe

	-Providing wildcards, filenames with spaces will work.
	danbooru-upload -n site_name -t "strike_witches" -f "*"

	-Using pipes
	ls *jpg | danbooru-upload -n "my_danbooru" -t "test upload" -F

EOF
}

sendoff (){
	#variables should already exist by the time fcn is called
	fname=$1
	cookies="$uploaderhome/$site.cookies"
	[ "$onefile" -a ! -z "$md5" ] && curl_md5="-F md5=$md5"
	#http send
	if [ "$2" == "url" ]; then
		echo "$fname:"
		#curl -s -s -A "$useragent" -d "$data" $baseurl/post/create.xml | grep response
		curl -s -S -b "$cookies" -c "$cookies" -A "$useragent" -F "post[tags]=$tags" -F "post[rating]=$rating" -F "post[parent_id]=$parent_id" -F "post[is_rating_locked]=$is_rating_locked" -F "post[is_note_locked]=$is_note_locked" -F "post[parent_id]=$parent_id" $curl_md5 -F "post[source]=$fname" $baseurl/post/create.xml 2>> $logfile | egrep "response|title"
	#file send
	else
		echo "$fname:"
		curl -s -S -b "$cookies" -c "$cookies" -A "$useragent" -F "post[tags]=$tags" -F "post[rating]=$rating" -F "post[parent_id]=$parent_id" -F "post[is_rating_locked]=$is_rating_locked" -F "post[is_note_locked]=$is_note_locked" -F "post[parent_id]=$parent_id" $curl_md5 -F "post[source]=$sauce" -F "post[file]=@$fname" $baseurl/post/create.xml 2>> $logfile | egrep "response|title"
		#echo "exit: $?"
	fi
}

login(){
	#site=$1
	cookies="$uploaderhome/$site.cookies"
	if [ "$username" ]; then
		if [ -z "$password" ]; then
			echo "Username for [$site]: $username"
			stty -echo
			read -p "Password for [$site]: " password; echo
			stty echo
		fi
	else
		read -p "Username for [$site]: " username
		stty -echo
		read -p "Password for [$site]: " password; echo
		stty echo
	fi

	curl -s -b "$cookies" -c "$cookies" -A "$useragent" -d "user[name]=$username&user[password]=$password" $baseurl/user/authenticate.xml 2>> $logfile
	#echo $?
}

if [ ! -f $config ]; then
	echo "No config file found! Please create one!"
	hlp
	exit 1
fi

# http://www.unix.com/shell-programming-scripting/39734-how-parse-config-variables-external-file-shell-script.html
# Function: get_config_list config_file
# Purpose : Print the list of configs from config file
get_config_list()
{
   typeset config_file=$1

   awk -F '[][]' '
      NF==3 && $0 ~ /^\[.*\]/ { print $2 }
   ' ${config_file}
}

# Function : set_config_vars config_file config [var_prefix]
# Purpose  : Set variables (optionaly prefixed by var_prefix) from config in config file
set_config_vars()
{
   typeset config_file=$1
   typeset config=$2
   typeset var_prefix=$3
   typeset config_vars

   config_vars=$( 
        awk -F= -v Config="${config}" -v Prefix="${var_prefix}" '
        BEGIN { 
           Config = toupper(Config);
           patternConfig = "\\[" Config "]";
        }
        toupper($0)  ~ patternConfig,(/\[/ && toupper($0) !~ patternConfig)  { 
           if (/\[/ || NF <2) next;
           sub(/^[[:space:]]*/, "");
           sub(/[[:space:]]*=[[:space:]]/, "=");
           print Prefix $0;
        } ' ${config_file} )

   eval "${config_vars}"
}

while getopts "n:t:f:1:Fr:s:RNp:hl:" OPTION
do
	case $OPTION in
		h)	hlp
			exit
			;;
		l)	site=$OPTARG
			login=1
			;;
		n)	site=$OPTARG
			;;
		t)	tags=$OPTARG
			;;
		f)	files="$OPTARG"
			;;
		F)	#set for-in separator to eol
			IFS=`echo -en "\n\b"`
			files="`cat /dev/stdin`"
			;;
		1)	IFS=`echo -en "\n\b"`
			onefile=1
			files="$OPTARG"
			;;
		r)	rating=$OPTARG
			;;
		s)	sauce=$OPTARG
			;;
		R)	is_rating_locked="true"
			;;
		N)	is_note_locked="true"
			;;
		p)	parent_id=$OPTARG
			;;
		m)	md5=$OPTARG
			;;
	esac
done

#magic
set_config_vars $config $site
if [ -z "$baseurl" ]; then
	echo "No baseurl line defined for '$site' in config file"
	exit 1
fi
if [ ! -z "$login" ]; then
	login
	exit
fi
if [[ -z $site ]] || [[ -z $tags ]] || [[ -z $files ]]; then
	usage
	exit 1
fi
#salt="choujin-steiner--$password--"
#if [ ! -z "$passhash" ]; then
#	sha1pass=$passhash
#else
#	sha1pass=`echo $salt | sha1sum | awk '{print $1}'`
#fi

echo "$version"
echo "Uploading to site '$site' with tags '$tags':"
#echo "salt: $sha1pass"

#main loop
#file expansion happens here
for file in $files; do
	httpchk=${file:0:7}
	ftpchk=${file:0:6}
	#check if url
	if [ "$httpchk" == "http://" -o "$ftpchk" == "ftp://" ]; then
		sendoff "$file" url
	else
		#if directory do nothing. do not recurse
		if [ -d "$file" ]; then
			nothing=
		#check if file exist
		elif [ -f "$file" ]; then
			sendoff "$file"
		#else file does not exist
		else
			echo "Cannot find $file"
		fi
	fi
done