# -*- coding: utf-8 -*-
"""
    MoinMoin - RecommendPage Action Macro

    PURPOSE:
        This macro is used to recommend a page to an other wiki user.

    Syntax:
        http://localhost:8080/WikiName?action=RecommendPage

    PROCEDURE:
       You get two lists, one with groups and one with users of those where you can
       send the recommendation.
       This is then stored on a page named WikiName/RecommendedPage as an wiki
       itemlist with the link and the first five lines in plain text.
       At the end your user SIG is written.
       A new entry is always written on top of the page.
       The persons are informed by an email notification about the changes.
       If you don't select anything the recommendation is done to your name.
       Please remove the version number from the filename.

    MODIFICATION HISTORY:
        @copyright: 2005 by MoinMoin:ReimarBauer
                    2009 by Anita Ludermann [anita(at)ludermann(dot)de]
       2005-04-21 : Version 1.3.4-3
                    output changed into calling ShortText()
                    e.g.  * ["RulesForUnzip"] [[ShortText(RulesForUnzip)]] ... @SIG@
                    it is also checked by now if acls are enabled in the config
       2005-09-02 : Version 1.3.5-4
                    from SubscribeTo by Raphael Bossek learned to add an
                    subscription for the email notification for a user before
                    the new recommendation is written to the file.
                    This means the user gots informed by an email.
       2005-09-05 : Version 1.3.5-5
                    isSubscribedTo from user replaced because it could not
                    destinguish between subpage and page. My implementation
                    does not understand regular expressions at the moment so
                    this gives by using regular expressions one extraline
                    in the config.
       2005-09-07 : Version 1.3.5-6
                    text box changed to a selection menu for the user names (sorted by name)
       2005-09-08 : Version 1.3.5-7
                    bug fix: spaces in html are different in browsers 
                             in some browser no selction did not give the user name
       2005-10-31 : Version 1.3.5-8
                    multiple selection added
                    no acl rights are set on a new recomendation page acls on
                    an existing recommendation page not overwritten
                    non admin users could use this function too.
                    code changed by a version request to be useable
                    with 1.5.0, too
       2006-02-03 : Version  1.5.1-9 1.3 compatible code removed
                    bug with wrong counted bad user fixed
       2008-01-11 : Version 1.6.0-10 refactored for 1.6
       2009-04-01 : Extended for groups by Anita Ludermann

""" 
# Import the required modules
from MoinMoin import wikidicts, wikiutil, user
from MoinMoin.Page import Page
from MoinMoin.PageEditor import PageEditor

def RecommendPage(request, pagename, username):
    '''
    Function: to produce the recommended pages
    @param request: the request object
    @param pagename: name of the page which should be recommended
    @param username: name of the user who gets the recommend
    '''
    err = None
    name = "%(username)s/RecommendPage" % {"username": username}
    page = PageEditor(request, name)
    # If the current user may write on this page, he can recommend it
    if request.user.may.write(name):
        if user.getUserId(request, username) is not None:
            uid = user.getUserId(request, username)
            recom_user = user.User (request, id=uid)

            subscription_list = recom_user.getSubscriptionList()
            isSubscribedTo = 0
            for test in subscription_list:
                if test == name:
                    isSubsribedTo = 1

            if isSubscribedTo == 0:
                recom_user.subscribe(name)
                recom_user.save()
                
        newtext = u" * %(pagename)s]] <<ShortText(%(pagename)s)>> ...\n %(username)s\n" % {
                 "pagename": pagename,
                 "username": "@SIG@"}
        # If the page does not exist yet, the user may make it.
        if not page.exists():
            PageEditor.saveText(page, newtext, 0)
        # If it already exists:
        else:
            body = page.get_data()
            meta = page.get_meta()
            text_meta = ''
            for command, attrib in meta:
                text_meta = '#%s %s\n%s' % (command, attrib, text_meta)

            text = "%s\n%s\n%s\n" % (text_meta, newtext, body)
            PageEditor.saveText(page, text, 0)
    # The user is not allowed to write on this page:
    else:
        err = "Can not write"
        return err
    
def select_users(request, pagename, selected_groups, selected_users):
    '''
    Function: to get a list of all users who get the RecommendPage without doublication 
    @param request: the request object
    @param pagename: name of the page which should be recommended
    @param selected_groups: all selected groups
    @param selected_users: all individually selected users
    '''
    # Search for all users in all selected groups
    for groupnames in selected_groups:
        user_group = wikidicts.Group(request, groupnames)
    
    # Saving users in list "selected_users"                   
    for name, valid in user_group.items():
        # Every user gets only ONE recommend
        uid = user.getUserId(request, name)
        user_object = user.User(request, uid)
        if user_object.exists():
            if valid and not name in selected_users:
                selected_users.append(name)
    selected_users = [name for name in selected_users if name != u'']
    return selected_users
                    
def execute(pagename, request):
    '''
    action dispatcher.
    @param request: the request object
    @param pagename: name of the page which should be recommended
    '''
    _ = request.getText
    actname = __name__.split('.')[-1]
    # Is the user registered and may read the page?
    if request.user.valid and request.user.may.read(pagename):
        thispage = Page(request, pagename)
        if request.form.has_key('button') and request.form.has_key('ticket'):
            if not wikiutil.checkTicket(request, request.form['ticket'][0]):

                return thispage.send_page(msg=_('Please use the interactive user interface to recommend pages!'))

            # The selected users are shown
            selected_groups = request.form.get('groupname', [u''])
            good = []
                     
            selected_users = []
            selected_users = request.form.get('username', [u''])
            good = []

            if selected_users[0] != u'':
                for username in selected_users:RecentChanges
                    i = 0
                    if len(username.strip()) == 0:
                        username = request.user.name
                        selected_users[i] = username
                        i += 1
            elif selected_groups[0] == u'' and selected_users[0] == u'':
                selected_users = [request.user.name]
            
            # Members of each group will be stored and reviewed on duplication
            if selected_groups[0] != u'':
                addressees = select_users(request, pagename, selected_groups, selected_users)
            else:
                addressees = selected_users
                    
            for username in addressees:
                uid = user.getUserId(request, username)
                user_object = user.User(request, uid)
                if user_object.may.read(pagename):
                    err = RecommendPage(request, pagename, username)
                    if err is None:
                        good.append(username)

            # "Good List" -> page is sent to this users
            msg = "recommended to read %(pagename)s to %(this_user)s" % {
                  "pagename": pagename,
                  "this_user": ' '.join(good)}

            request.theme.add_msg(msg, "info")
            thispage.send_page()
            return         
               
        # All groups are shown
        isgroup = request.cfg.cache.page_group_regexact.search
        groupname = request.rootpage.getPageList(user='', filter=isgroup)
        html_group = []

        for group in groupname:
            html_group.append("<OPTION>%(name)s</OPTION>" % {"name": group})
        # The list with groups depents on the group's strength
        html_group.sort()
        n = min([3, len(html_group)])
        
        # All users are shwon
        users = user.getUserList(request)
        html_user = []
        for uid in users:
            name = user.User(request, id=uid).name
            uid = user.getUserId(request, name)
            user_object = user.User(request, uid)
            if user_object.may.read(pagename):
                html_user.append("<OPTION>%(name)s</OPTION>" % {"name": name})

        # The list with users depents on the user's strength
        html_user.sort()
        n = min([3, len(html_user)])

        formhtml = '''

<table class="dialog">
<tr><td><form method="post" >
<strong>%(querytext)s</strong>
<BR>
</td></tr><tr><td>
<select name="groupname" size="%(len)s" multiple>has_key
%(option_group)s
</select>
</td><td>
<select name="username" size="%(len)s" multiple>
%(option_user)s
</select>
</td><td>
<input type="hidden" name="action" value="%(actname)s">
<input type="submit" name="button" value="%(button)s"></td></tr>
<tr><td><BR>
(no selection recommends to: %(user)s)
<input type="hidden" name="ticket" value="%(ticket)s">
<p></td></tr></table>
</form>''' % {
    # The Variables are determined
    'querytext': 'Recommend page to',
    'actname': 'RecommendPage',
    'ticket': wikiutil.createTicket(request),
    'option_group': ' '.join(html_group),
    'option_user': ' '.join(html_user),
    'user': request.user.name,
    'len': n,
    'button': 'Recommend'}
        # Page is sent
        request.theme.add_msg(formhtml, "info")
        thispage.send_page()
        return
    