From ab13a717fe4e443c233694c69573deb11dbdf453 Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Thu, 14 Oct 2010 17:37:18 +0200 Subject: changed user database from dict to mnesia (modules: cldb) --- client/client.erl | 36 ++++++++++++++++++++++++++++------ server/cldb.erl | 48 ++++++++++++++++++++++++++------------------- server/client.erl | 17 +++++++++++----- server/dispatcher.erl | 54 +++++++++++++++++++++++++++------------------------ 4 files changed, 99 insertions(+), 56 deletions(-) diff --git a/client/client.erl b/client/client.erl index 0e2fada..f500fe1 100644 --- a/client/client.erl +++ b/client/client.erl @@ -1,5 +1,5 @@ -module(client). --export([register/3, login/3, list/0, handle/2, getVotes/0, vote/2, devote/2]). +-export([register/2, register/3, login/3, list/0, handle/2, getVotes/0, vote/2, devote/2]). checkLogin(Value) -> %% check if user meets the requirements to be locked in or not by @@ -17,13 +17,34 @@ buildNode(Server) -> rpc(Server, Function, Params) -> rpc:call(buildNode(Server), client, Function, Params). -register(Server, Name, Password) -> - rpc(Server, register, [self(), {Name, Password}]), +wait_for_reply() -> receive {_, Msg} -> - Msg + Msg; + Why -> Why + after 3000 -> + {error, timeout} + end. + +register(Name, Password) -> + try checkLogin(true) of + _ -> + server:rpc(cli, {register, Name, Password}) + catch + {error, login_state} -> + {error, not_logged_in} end. +register(Server, Name, Password) -> + try checkLogin(false) of + _ -> + rpc(Server, register, [self(), {Name, Password}]) + catch + {error, login_state} -> + {error, logged_in} + end, + wait_for_reply(). + login(Server, Name, Password) -> code:purge(server), code:load_abs("../common/server"), @@ -33,12 +54,14 @@ login(Server, Name, Password) -> rpc(Server, login, [self(), {node(), Name, Password}]), receive {ok, {ok, {logged_in, Pid}}} -> - register(cli, Pid), + erlang:register(cli, Pid), {ok, logged_in}; {_, Msg} -> Msg; Msg -> Msg + after 3000 -> + {error, timeout} end catch {error, login_state} -> @@ -71,7 +94,8 @@ handle({vote, Artist, Title}, Server) -> send_to_server({vote, Artist, Title}, Server); handle({devote, Artist, Title}, Server) -> send_to_server({devote, Artist, Title}, Server); - +handle({register, Name, Password}, Server) -> + send_to_server({register, Name, Password}, Server); handle({change_state, NewState}, _) -> {{ok}, NewState}; diff --git a/server/cldb.erl b/server/cldb.erl index 982aafc..0602b7d 100644 --- a/server/cldb.erl +++ b/server/cldb.erl @@ -1,7 +1,7 @@ % The clientdatabase -module(cldb). --export([init/0, ask/2, login/2, decVote/2, incVote/2, register/3, check_rights/2]). +-export([init/0, ask/2, login/2, decVote/1, incVote/1, register/3, check_rights/1]). -record(user, {name, passwd, votes, rights}). init() -> @@ -9,45 +9,53 @@ init() -> mnesia:start(), mnesia:create_table(user, [{attributes, record_info(fields, user)}]), io:format("Userdb up and running \n"). - + ask(User, Pwd) -> F = fun() -> - mnesia:match_object({user, User, Pwd, '_'}) + mnesia:match_object({user, User, Pwd, '_', '_'}) end, mnesia:transaction(F). - - - + login(User, Pwd) -> - {_, Reason} = ask(User, Pwd), - Reason. + case ask(User, Pwd) of + {atomic, [UserRow|_]} -> {ok, UserRow}; + _-> {error} + end. register(User, Pwd, Root) -> - F = fun() -> - mnesia:write(#user{name = User, passwd = Pwd, votes = 5, rights = Root}) - end, - {_, Reason} = mnesia:transaction(F), - Reason. + case ask(User, '_') of + {atomic, []} -> + F = fun() -> + mnesia:write(#user{name = User, passwd = Pwd, votes = 5, rights = Root}) + end, + case mnesia:transaction(F) of + {atomic, ok} -> + {ok, user_created}; + {atomic, Why} -> + {error, Why} + end; + _ -> + {error, duplicated_user} + end. -decVote(User, Pwd) -> +decVote(User) -> F = fun() -> - [Head|_] = ask(User, Pwd), + [Head|_] = ask(User, '_'), Votes = Head#user.votes - 1, New = Head#user{votes = Votes}, mnesia:write(New) end, mnesia:transaction(F). -incVote(User, Pwd) -> +incVote(User) -> F = fun() -> - [Head|_] = ask(User, Pwd), + [Head|_] = ask(User, '_'), Votes = Head#user.votes + 1, New = Head#user{votes = Votes}, mnesia:write(New) end, mnesia:transaction(F). -check_rights(User, Name) -> - {_, _, Rights} = ask(User, Name), +check_rights(User) -> + {_, _, Rights} = ask(User, '_'), Rights. - diff --git a/server/client.erl b/server/client.erl index cb6504e..d12c891 100644 --- a/server/client.erl +++ b/server/client.erl @@ -1,11 +1,11 @@ -module(client). --export([start/1, loop/1, register/2, login/2]). +-export([start/2, loop/2, register/2, login/2]). -start(Node) -> +start(Node, User) -> process_flag(trap_exit, true), Client = server:start_on_node(Node, client, undef), link(Client), - Server = spawn_link(client, loop, [Client]), + Server = spawn_link(client, loop, [Client, User]), case server:rpc(Client, {change_state, Server}) of {ok} -> @@ -25,9 +25,16 @@ execute(Client, F) -> Client ! {error, Why} end. -loop(Client) -> +loop(Client, User) -> %% mainloop for client modul in server receive + {register, Name, Password} -> + case User of + {user, _, _, _, admin} -> + execute(Client, fun() -> cldb:register(Name, Password, none) end); + _ -> Client ! {error, {no_rights}} + end; + list -> execute(Client, fun() -> media:all() end); @@ -43,7 +50,7 @@ loop(Client) -> Cmd -> Client ! {error, {unknown_command, Cmd}} end, - loop(Client). + loop(Client, User). register(Client, {Name, Password}) -> dis ! {Client, {register, {Name, Password}}}. diff --git a/server/dispatcher.erl b/server/dispatcher.erl index e5e0572..3806ef7 100644 --- a/server/dispatcher.erl +++ b/server/dispatcher.erl @@ -1,5 +1,10 @@ -module(dispatcher). --export([start/0, init/0, handle/2]). +-export([start/0, handle/2, checkUserExists/1]). + +checkUserExists([_|_]) -> + false; +checkUserExists(_) -> + true. start() -> %% load server module from common directory, @@ -7,6 +12,8 @@ start() -> code:purge(server), code:load_abs("../common/server"), + cldb:init(), + %% spawn media backend in seperat process try spawn(media, init, []) of _ -> @@ -20,9 +27,10 @@ start() -> %% start server (registered as dis) %% server-module will call handle if message arrives and init to %% initialize the status - try server:start(dis, dispatcher) of + UserExists = checkUserExists(cldb:ask('_', '_')), + try server:start(dis, dispatcher, UserExists) of true -> - io:format("Server started!~n"), + io:format("Server started: ~w!~n", [UserExists]), true catch _ -> @@ -30,34 +38,30 @@ start() -> exit(1) end. -init() -> - dict:new(). +handle({register, {User, Password}}, true) -> + io:format("User created: ~s~n", [User]), + cldb:register(User, Password, admin), + {{ok, user_created}, false}; -handle({register, {User, Password}}, Dict) -> - case dict:find(User, Dict) of - {ok, _}-> - {{error, duplicated_user}, Dict}; - _ -> - io:format("User created: ~s~n", [User]), - {{ok, user_created}, dict:store(User, Password, Dict)} - end; +handle({register, _}, false) -> + {{error, no_rights}, false}; -handle({login, {Node, User, Password}}, Dict) -> - case dict:find(User, Dict) of - {ok, Password} -> - case client:start(Node) of +handle({login, {Node, User, Password}}, State) -> + case cldb:login(User, Password) of + {ok, UserRow} -> + case client:start(Node, UserRow) of {ok, Pid} -> - {{ok, {logged_in, Pid}}, Dict}; + {{ok, {logged_in, Pid}}, State}; Why -> - {{error, {unable_to_login, Why}}, Dict} + {{error, {unable_to_login, Why}}, State} end; - _ -> - {{error, user_or_password_invalid}, Dict} + Why -> + {{error, {user_or_password_invalid, Why}}, State} end; -handle({'EXIT', _, _}, Dict) -> - Dict; +handle({'EXIT', _, _}, State) -> + State; -handle(Cmd, Dict) -> +handle(Cmd, State) -> %% standard command, to find transmission errors - {{error, {unknown_command, Cmd}}, Dict}. + {{error, {unknown_command, Cmd}}, State}. -- cgit v1.2.3 From 4741ca84bd516bcf5b65854e2661f7842599c4fc Mon Sep 17 00:00:00 2001 From: Michael Wittig Date: Thu, 14 Oct 2010 17:38:35 +0200 Subject: added getting votes after songs --- server/media.erl | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/server/media.erl b/server/media.erl index 5eea592..83e7513 100644 --- a/server/media.erl +++ b/server/media.erl @@ -112,11 +112,20 @@ play(Artist, Title) -> io:format("playing: ~s, Artist: ~s~n", [Title, Artist]), receive - {Port, {exit_status, 0}} -> start_playing(); + {Port, {exit_status, 0}} -> give_votes(cldb:ask("_","_")), start_playing(); {Port, {exit_status, S}} -> throw({commandfailed, S}) end. +% after a song every client gets on more vote +give_votes([Head|Rest]) -> + User = Head#user.name, + Pwd = Head#user.passwd, + cldb:incVote(User, Pwd), + giveVotes(Rest); +give_Votes([]) -> ok. + + % Of course we need a query to find out what the highest voted track is. % We accomplish this by requesting all the records from the database and then iterate over them, just taking a look at the vote % variable, so it is like a list of integers. In case no tracks were voted for we just take the first track we found and play it. Of course this song is locked afterwards so a different one will be chosen. -- cgit v1.2.3 From f2164544210f511664ed7186107789ec55ec3edf Mon Sep 17 00:00:00 2001 From: Michael Wittig Date: Thu, 14 Oct 2010 17:49:42 +0200 Subject: finally finished, need to be read again --- server/cldb.erl | 8 ++++++++ server/media.erl | 11 +---------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/server/cldb.erl b/server/cldb.erl index 0602b7d..d514ff9 100644 --- a/server/cldb.erl +++ b/server/cldb.erl @@ -59,3 +59,11 @@ incVote(User) -> check_rights(User) -> {_, _, Rights} = ask(User, '_'), Rights. + +% after a song every client gets on more vote +give_votes([Head|Rest]) -> + User = Head#user.name, + incVote(User), + give_votes(Rest); +give_votes([]) -> ok. + diff --git a/server/media.erl b/server/media.erl index 83e7513..80a3fea 100644 --- a/server/media.erl +++ b/server/media.erl @@ -112,20 +112,11 @@ play(Artist, Title) -> io:format("playing: ~s, Artist: ~s~n", [Title, Artist]), receive - {Port, {exit_status, 0}} -> give_votes(cldb:ask("_","_")), start_playing(); + {Port, {exit_status, 0}} -> cldb:give_votes(cldb:ask("_","_")), start_playing(); {Port, {exit_status, S}} -> throw({commandfailed, S}) end. -% after a song every client gets on more vote -give_votes([Head|Rest]) -> - User = Head#user.name, - Pwd = Head#user.passwd, - cldb:incVote(User, Pwd), - giveVotes(Rest); -give_Votes([]) -> ok. - - % Of course we need a query to find out what the highest voted track is. % We accomplish this by requesting all the records from the database and then iterate over them, just taking a look at the vote % variable, so it is like a list of integers. In case no tracks were voted for we just take the first track we found and play it. Of course this song is locked afterwards so a different one will be chosen. -- cgit v1.2.3