Handle HAVE_ALL and HAVE_NONE. Cleanup the BITFIELD message.
[etorrent.git] / lib / etorrent-1.0 / src / etorrent_dirwatcher.erl
blob55fbfcbff22116a10d96fb133e643f851417d3a8
1 %%%-------------------------------------------------------------------
2 %%% File : dirwatcher.erl
3 %%% Author : Jesper Louis Andersen <jlouis@succubus>
4 %%% License : See COPYING
5 %%% Description : Watch a directory for the presence of torrent files.
6 %%% Send commands when files are added and removed.
7 %%%
8 %%% Created : 24 Jan 2007 by Jesper Louis Andersen <jlouis@succubus>
9 %%%-------------------------------------------------------------------
10 -module(etorrent_dirwatcher).
11 -author("Jesper Louis Andersen <jesper.louis.andersen@gmail.com>").
12 -behaviour(gen_server).
14 -vsn("1").
15 %% API
16 -export([start_link/0, dir_watched/0]).
18 %% gen_server callbacks
19 -export([init/1, handle_call/3, handle_cast/2, handle_info/2,
20 terminate/2, code_change/3]).
22 -record(state, {dir = none}).
23 -define(WATCH_WAIT_TIME, timer:seconds(20)).
24 -define(SERVER, ?MODULE).
26 %%====================================================================
27 %% API
28 %%====================================================================
29 %%--------------------------------------------------------------------
30 %% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
31 %% Description: Starts the server
32 %%--------------------------------------------------------------------
33 start_link() ->
34 gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
36 dir_watched() ->
37 gen_server:call(dirwatcher, dir_watched).
39 %%====================================================================
40 %% gen_server callbacks
41 %%====================================================================
42 init([]) ->
43 {ok, Dir} = application:get_env(etorrent, dir),
44 _Tid = ets:new(etorrent_dirwatcher, [named_table, protected]),
45 {ok, #state{dir = Dir}, 0}.
47 handle_call(dir_watched, _Who, S) ->
48 {reply, S#state.dir, S, ?WATCH_WAIT_TIME};
49 handle_call(_Request, _From, State) ->
50 Reply = ok,
51 {reply, Reply, State, ?WATCH_WAIT_TIME}.
53 handle_cast(_Request, S) ->
54 {noreply, S, ?WATCH_WAIT_TIME}.
56 handle_info(timeout, S) ->
57 watch_directories(S),
58 {noreply, S, ?WATCH_WAIT_TIME};
59 handle_info(_Info, State) ->
60 {noreply, State, ?WATCH_WAIT_TIME}.
62 terminate(_Reason, _State) ->
63 ok.
65 code_change(_OldVsn, State, _Extra) ->
66 {ok, State}.
68 %%--------------------------------------------------------------------
69 %%% Internal functions
70 %%--------------------------------------------------------------------
72 %% Operations
73 watch_directories(S) ->
74 reset_marks(ets:first(etorrent_dirwatcher)),
75 lists:foreach(fun process_file/1,
76 filelib:wildcard("*.torrent", S#state.dir)),
78 ets:safe_fixtable(etorrent_dirwatcher, true),
79 try
80 start_stop(ets:first(etorrent_dirwatcher))
81 after
82 ets:safe_fixtable(etorrent_dirwatcher, false)
83 end,
84 ok.
86 process_file(F) ->
87 case ets:lookup(etorrent_dirwatcher, F) of
88 [] ->
89 ets:insert(etorrent_dirwatcher, {F, new});
90 [_] ->
91 ets:insert(etorrent_dirwatcher, {F, marked})
92 end.
94 reset_marks('$end_of_table') -> ok;
95 reset_marks(Key) ->
96 ets:insert(etorrent_dirwatcher, {Key, unmarked}),
97 reset_marks(ets:next(etorrent_dirwatcher, Key)).
99 start_stop('$end_of_table') -> ok;
100 start_stop(Key) ->
101 [{Key, S}] = ets:lookup(etorrent_dirwatcher, Key),
102 case S of
103 new -> etorrent_mgr:start(Key);
104 marked -> ok;
105 unmarked -> etorrent_mgr:stop(Key),
106 ets:delete(etorrent_dirwatcher, Key)
107 end,
108 start_stop(ets:next(etorrent_dirwatcher, Key)).