<commit_before>-module(z_github).
-compile(export_all).

-define(Timer, 100).

waitfor_gone(Ident) ->
	case whereis(Ident) of
		undefined -> ok;
		_ -> timer:sleep(100), waitfor_gone(Ident)
	end.

get_commands() -> [].
initialise(T) ->
	case whereis(?MODULE) of
		undefined -> ok;
		Pid -> Pid ! stop, waitfor_gone(?MODULE)
	end,
	case file:consult("github_announce.crl") of
		{ok, [Secret,Channels]} -> ok;
		_ ->
			Secret = '*',
			Channels = [{'*', '*', "#bot32-test"}]
	end,
	spawn(?MODULE, init, [Channels, Secret]),
	T.

deinitialise(T) ->
	case whereis(?MODULE) of
		undefined -> ok;
		Pid -> Pid ! stop
	end,
	T.

init(Channels, Secret) ->
	case gen_tcp:listen(8080, [binary, {packet, http}, {active, false}, {reuseaddr, true}]) of
		{ok, SvrSock} ->
			logging:log(info, "GITHUB", "Starting loop."),
			register(?MODULE, self()),
			loop(SvrSock, Channels, Secret),
			gen_tcp:close(SvrSock),
			logging:log(info, "GITHUB", "Ending loop.");
		{error, Reason} ->
			logging:log(error, "GITHUB", "Failed to open listen socket: ~p", [Reason])
	end.

loop(SvrSock, Channels, Secret) ->
	case receive
		stop -> stop
	after ?Timer ->
		case gen_tcp:accept(SvrSock, ?Timer) of
			{ok, Socket} -> handle_sock(Socket, Channels, Secret), ok;
			{error, timeout} -> ok;
			{error, X} -> {error, X}
		end
	end of
		ok -> loop(SvrSock, Channels, Secret);
		stop -> ok;
		{error, E} -> logging:log(error, "GITHUB", "error: ~p", [E]);
		E -> logging:log(error, "GITHUB", "Unknown status ~p", [E])
	end.

handle_sock(Socket, Channels, Secret) ->
	case gen_tcp:recv(Socket, 0, 2000) of
		{ok, {http_request, 'POST', A, B}} ->
			inet:setopts(Socket, [{packet, httph}]),
			Dict = read_headers(Socket),
			case orddict:find("X-Hub-Signature", Dict) of
				{ok, Signature} ->
					case case case orddict:find('Content-Length', Dict) of
						{ok, Value} ->
							inet:setopts(Socket, [{packet, raw}]),
							read_content(Socket, list_to_integer(Value), Signature, Secret);
						error -> <<"">>
					end of
						sigerr -> error;
						<<"">> -> ok;
						{error, T} -> logging:log(error, "GITHUB", "Error: ~p", [T]);
						Content -> decode_content(Content, Channels), ok
					end of
						ok ->
							gen_tcp:send(Socket, "HTTP/1.1 204 No Content\r\n\r\n");
						error ->
							common:debug("GITHUB", "HTTP request with incorrect signature ~p ~p ~p", [A, B, Dict]),
							gen_tcp:send(Socket, "HTTP/1.1 403 Forbidden\r\n\r\n")
					end;
				error -> 
					common:debug("GITHUB", "HTTP request with no signature ~p ~p ~p", [A, B, Dict]),
					gen_tcp:send(Socket, "HTTP/1.1 403 Forbidden\r\n\r\n")
			end,
			gen_tcp:close(Socket);
		{ok, T} ->
			common:debug("GITHUB", "HTTP request ~p", [T]),
			gen_tcp:send(Socket, "HTTP/1.1 204 No Content\r\n\r\n"),
			gen_tcp:close(Socket);
		{error, T} ->
			common:debug("GITHUB", "HTTP error: ~p", [T])
	end.

read_headers(Socket) -> read_headers(Socket, orddict:new()).
read_headers(Socket, Dict) ->
	case gen_tcp:recv(Socket, 0, 2000) of<commit_msg>These should probably be logging:log, not common:debug<commit_after>-module(z_github).
-compile(export_all).

-define(Timer, 100).

waitfor_gone(Ident) ->
	case whereis(Ident) of
		undefined -> ok;
		_ -> timer:sleep(100), waitfor_gone(Ident)
	end.

get_commands() -> [].
initialise(T) ->
	case whereis(?MODULE) of
		undefined -> ok;
		Pid -> Pid ! stop, waitfor_gone(?MODULE)
	end,
	case file:consult("github_announce.crl") of
		{ok, [Secret,Channels]} -> ok;
		_ ->
			Secret = '*',
			Channels = [{'*', '*', "#bot32-test"}]
	end,
	spawn(?MODULE, init, [Channels, Secret]),
	T.

deinitialise(T) ->
	case whereis(?MODULE) of
		undefined -> ok;
		Pid -> Pid ! stop
	end,
	T.

init(Channels, Secret) ->
	case gen_tcp:listen(8080, [binary, {packet, http}, {active, false}, {reuseaddr, true}]) of
		{ok, SvrSock} ->
			logging:log(info, "GITHUB", "Starting loop."),
			register(?MODULE, self()),
			loop(SvrSock, Channels, Secret),
			gen_tcp:close(SvrSock),
			logging:log(info, "GITHUB", "Ending loop.");
		{error, Reason} ->
			logging:log(error, "GITHUB", "Failed to open listen socket: ~p", [Reason])
	end.

loop(SvrSock, Channels, Secret) ->
	case receive
		stop -> stop
	after ?Timer ->
		case gen_tcp:accept(SvrSock, ?Timer) of
			{ok, Socket} -> handle_sock(Socket, Channels, Secret), ok;
			{error, timeout} -> ok;
			{error, X} -> {error, X}
		end
	end of
		ok -> loop(SvrSock, Channels, Secret);
		stop -> ok;
		{error, E} -> logging:log(error, "GITHUB", "error: ~p", [E]);
		E -> logging:log(error, "GITHUB", "Unknown status ~p", [E])
	end.

handle_sock(Socket, Channels, Secret) ->
	case gen_tcp:recv(Socket, 0, 2000) of
		{ok, {http_request, 'POST', A, B}} ->
			inet:setopts(Socket, [{packet, httph}]),
			Dict = read_headers(Socket),
			case orddict:find("X-Hub-Signature", Dict) of
				{ok, Signature} ->
					case case case orddict:find('Content-Length', Dict) of
						{ok, Value} ->
							inet:setopts(Socket, [{packet, raw}]),
							read_content(Socket, list_to_integer(Value), Signature, Secret);
						error -> <<"">>
					end of
						sigerr -> error;
						<<"">> -> ok;
						{error, T} -> logging:log(error, "GITHUB", "Error: ~p", [T]);
						Content -> decode_content(Content, Channels), ok
					end of
						ok ->
							gen_tcp:send(Socket, "HTTP/1.1 204 No Content\r\n\r\n");
						error ->
							logging:log(info, "GITHUB", "HTTP request with incorrect signature ~p ~p ~p", [A, B, Dict]),
							gen_tcp:send(Socket, "HTTP/1.1 403 Forbidden\r\n\r\n")
					end;
				error -> 
					logging:log(info, "GITHUB", "HTTP request with no signature ~p ~p ~p", [A, B, Dict]),
					gen_tcp:send(Socket, "HTTP/1.1 403 Forbidden\r\n\r\n")
			end,
			gen_tcp:close(Socket);
		{ok, T} ->
			logging:log(info, "GITHUB", "HTTP request ~p", [T]),
			gen_tcp:send(Socket, "HTTP/1.1 204 No Content\r\n\r\n"),
			gen_tcp:close(Socket);
		{error, T} ->
			logging:log(info, "GITHUB", "HTTP error: ~p", [T])
	end.

read_headers(Socket) -> read_headers(Socket, orddict:new()).
read_headers(Socket, Dict) ->
	case gen_tcp:recv(Socket, 0, 2000) of
{'fraction_non_alphanumeric': 0.1933190011575988, 'fraction_numerical': 0.013891185711923267, 'mean_word_length': 3.5303370786516854, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 93, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2072889', 'n_tokens_mistral': 2740, 'n_tokens_neox': 2321, 'n_words': 555}