View · Index

Weblog Page

Showing 621 - 630 of 694 Postings (summary)

Learning Content Tool

Created by Alvaro Rodriguez, last modified by josue ruiz 21 Dec 2012, at 12:22 AM

Learning-Content Tool

Description


User specs
The Learning-Content Package is a simple content creation tool based on xowiki. This package lets you easily create, edit and organize content for a course, taking advantage of xowiki's easy inline edition and revision history.  The package provides a generic template generated automatically with the pages and the categories.
During the edition of the pages there is an interface that allows the addition of terms and definitions to a glossary, linking the words from the content. It comes with an interface that allows linking of certain resources from the course, such as linking evaluations, assessments and forums to the content pages.
There is a new admin section for the content which includes a page to manage the categories in the content tree, an option to show/hide a specific title for the course on every page, user tracking by page or user, and one-click automatic copy of the content to other classes/communities.

Development History


2007

The Content package was first developed by Byron Linares (Galileo University) as a portlet using xowiki as the main package, adding all the files and modifications needed in xowiki. The automatic template included was specific for the Galileo's theme.

Works on:
postgresql 8.2.x
xowiki 0.47
xotcl 0.47

Required:
ltree module for postgresql

2008-2009
The package was improved by Alvaro Rodriguez and Viaro Networks team to make it a real package as an extension of xowiki, it was updated to work with the latest version of xotcl-core, xowiki from the oacs-5-4 branch. It was completely ported to Oracle and it no longer requires the ltree module for postgresql.

How to Install


Works on:
Postgresql 8.2.x +
Oracle 9i +

Requires:
xowiki 0.106.1
xotcl-core 0.100
views 0.1d3
ajaxhelper 0.87d (needs upgrade to YUI 2.5.2+)

Installation process:
  1. Get the following packages from branch oacs-5-4: dotlrn-all, xowiki, xotcl-core, views
  2. Get the following packages from HEAD: learning-content, learning-content-portlet, dotlrn-learning-content, ajaxhelper
  3. Move to the content package folder and run the script.sh, this will patch all the files from other packages to integrate them with content new features
    1. To run the script:
      • /$path_to_content_patch/$  sh script.sh
  4. Install dotlrn, then install xowiki, xotcl-core, learn-content, learn-content-portlet, dotlrn-learn-content, ajaxhelper and views
  5. Restart the server
  6. Activate the applet in a course

Release Notes


Name: Content
Version: 0.1d  (October 2007)
Developed by: Byron Linares (Galileo University)
  • Provides a simple interface to create web pages and easily include and manipulate web assets such as flash, videos, images, etc.
  • Provides a web template, easy to manage, similar to a PPT template but with built in navigation (sequential navigation, tab based organization, sub tabs supported and per unit / module navigation).
  • Folder, subfolders, pages ordering.
  • Free of "standards" approaches, so professors with basic word knowledge can use it.
  • Auto scroll (focus navigation on the content area).
  • It provides portlets for .LRN

Name: Learn Content (Renamed because Content was a very generic name)
Version: 1.0b (January 2009)
Developed by: Alvaro Rodriguez (Viaro Networks)
  • The package is an OO extension of xowiki, leaves xowiki package unmodified
  • Glossary tool, a plugin for xinha to add words to the glossary during the content edition, an admin page to manage all words and definitions, dynamic popup with the word definition inside the content
  • Integration with other dotlrn resources, a new interface to link resources from the course to the content pages, this allows the content tool to be the reference of a course like SCORM
  • User tracking, reports about all the content pages and all the users views, visits by page and visits by user
  • Header for the content, show/hide a specific title for the course on top of each page of the content
  • An admin section of the content for teachers, the xowiki's inherited admin section is only for swa
  • Automatic copy of the content to other classes/communities inside dotlrn
  • Split up the automatic template in sections to be easily changed (by developers/designers)

Technical specs


The Learn-Content Package is an OO extension of xowiki. The package generic template was split into sections so that it can be easily modified (by a developer/designer).  A new plug-in for the Xinha richtext editor allows it to interact with the new glossary feature. To use this plug-in a parameter in the Xinha configuration must be set (which is automatically added in content).

Every page instantiated along with the package (index, glossary admin, templates, etc) is now in the prototypes section of content. If a site-wide administrator deletes a page it will be loaded again when requested. There is a new admin section that is independent of xowiki's admin section, this section is in a different directory so that different permissions can be set.

Calls to content callbacks have been added to other packages in the add forms to be able to link the resources from those packages to the content pages. The callbacks extend the form of a new object to receive the page_id to be linked to, and inserts the objects into the page once it has been created in the submit section of the form.

A new proc was created that automatically copies content to other classes/comunities using the export and import options of xowiki, complete with all the categories, the mapped objects, and the activities linked to the content.

Each callback is defined and implemented in the learn-content-callback-procs, in the following way:
ad_proc -public -callback "callback_name" -impl content
if a package needs a different implementation of a callback it should be done in the package callbacks procs in the following way:
ad_proc -public -callback "callback_name" -impl $package_key
This callbacks are used inside the page that has the form for creating/editing new in the following way:
callback -catch -impl content "callback_name" -params...

To add a new package to the activities available in content, the callbacks should be added to the file(s) where the objects are created, i.e. forum-new, task-add-edit, etc.
  1. A new parameter called page_instance_id needs to be added to the ad_page_contract
  2. The following callback should be added in a place where the form can be extended
    • callback -catch -impl content learning_content::extend_form -name $form_name -page_instance_id $page_instance_id
  3. The following callback should be added in the submit section of the form after the object has been created
    • callback -catch -impl content learning_content::insert_object -name $object_name -item_id $page_instance_id -activity_id $object_id
  4. The activity should be added to the activity-new and get-activities pages in the learning-content package, check out the existing activities sections to figure out the right way to include

The script added to the package to patch the rest of the packages was generated with diff between the packages from clean oacs-5-4 and modified oacs-5-4:
diff -crNB ~/oacs-5-4/packages/$package_name ~/custom-oacs-5-4/packages/$package_name


This work was done in collaboration with Innova - UNED.

Openacs git repo on Github

Created by Jim Lynch, last modified by Jim Lynch 13 Jul 2012, at 12:35 AM

description/intro paragraph (this might as well be inline)

(all the rest are menu items, which probably open into submenu which has content)

getting started with git for openacs

git for openacs users

git for openacs coders and contributors

openacs release management using git

managing the repos

Install OpenACS on Mac OS X 10.5 / 10.6 (Snow Leopard) Using Macports

Created by Malte Sussdorff, last modified by Gustaf Neumann 03 Nov 2011, at 02:26 PM

I worked off the work of Dave Bauer and used Macports.

Unfortunately, the default configuration of Mac OS X does not allow suitable amounts of shared memory to be created to run the database server. 

Therefore you should edit your /etc/sysctl.conf

On a MacBook Pro with 2GB of RAM, the author's sysctl.conf contains:

kern.sysv.shmmax=1610612736

kern.sysv.shmall=393216

kern.sysv.shmmin=1

kern.sysv.shmmni=32

kern.sysv.shmseg=8

kern.maxprocperuid=512

kern.maxproc=2048

Download and install MacPorts from http://www.macports.org/install.php and get the latest version (1.7.1 as of 2009-04-18)

Install PostgreSQL 8.4

sudo port -k install postgresql84
cd `port work postgresql84`/postgresql-8.4.7/contrib/ltree
make all
sudo make install
sudo port install postgresql84-server
This installs expat, gperf, libiconv, ncursesw, ncurses, gettext, m4, bison, zlib, libxml2, libxslt1, openssl, readline, postgresql82. The macports install then says
To create a database instance, after install do
sudo mkdir -p /opt/local/var/db/postgresql84/defaultdb
sudo chown postgres:postgres /opt/local/var/db/postgresql84/defaultdb
sudo su postgres -c '/opt/local/lib/postgresql84/bin/initdb -D /opt/local/var/db/postgresql84/defaultdb'

Then after initdb postgres says to start postgresql. Before that edit the config file to make it compatible with ACS

sudo emacs -nw /opt/local/var/db/postgresql84/defaultdb/postgresql.conf
Once you have emacs open, change the following config items:
autovacuum = on
add_missing_from = on
default_with_oids = on
regex_flavor = extended

Now start the PostgreSQL Server 

sudo su postgres -c  '/opt/local/lib/postgresql84/bin/postgres -D /opt/local/var/db/postgresql84/defaultdb' &

Install plpgsql as a language

/opt/local/lib/postgresql84/bin/createlang plpgsql template1 -U postgres

Last but not least, put postgresql under launchctl so you can start and stop it: 

sudo launchctl load -w /Library/LaunchDaemons/org.macports.postgresql84-server.plist 

To start it from then on just call

sudo launchctl start org.macports.postgresql84-server

To stop it:

sudo launchctl stop org.macports.postgresql84-server

Install AOLserver 4.5

sudo port install tcl +threads +headers

This will install Tcl with threads enabled, which is needed for AOLserver.

sudo port install aolserver
Now we have AOLserver installed into /opt/local/aolserver. You now need to configure the server to your needs. You might want to create another user (e.g. aolserver) to run the server. First get all the files:
    cd /usr/local/src
    mkdir aolserver 
    cd aolserver 
    TCLLIB=1.13
    XOTCL=1.6.7
    # Path for the AOLserver installation 
    NS=/opt/local/aolserver
    cvs -z3 -d:pserver:anonymous@aolserver.cvs.sourceforge.net:/cvsroot/aolserver co nssha1 
    cvs -z3 -d:pserver:anonymous@aolserver.cvs.sourceforge.net:/cvsroot/aolserver co nspostgres
    echo "Getting TDOM ..." 
    git clone git://github.com/tDOM/tdom.git
    echo "Getting TCL modules ..." 
    curl -L -O http://downloads.sourceforge.net/tcllib/tcllib-${TCLLIB}.tar.bz2 
    curl -L -O http://downloads.sourceforge.net/tcl/thread2.6.5.tar.gz 
    curl -L -O http://media.wu-wien.ac.at/download/xotcl-${XOTCL}.tar.gz

Now install nssha1

 
    cd nssha1
    sudo make install NSHOME=${NS} 
    cd ..

Now go for nspostgres

 
    cd nspostgres/

    # Edit the Makefile so it reads (adding the "-lnsdb")
    MODLIBS = -L$(PGLIB) -lpq -lnsdb
    
    sudo make install AOLSERVER=/opt/local/aolserver/ PGCONFIG=/opt/local/lib/postgresql84/bin/pg_config POSTGRES=/opt/local PGINC=/opt/local/include/postgresql84/ PGLIB=/opt/local/lib/postgresql84/ ACS=1
    cd ..

tDOM

 
    cd tDOM-0.8.2/unix
    ../configure    --mandir=/usr/local/share/man    --libdir=/opt/local/aolserver/lib    --with-tcl=/opt/local/lib   --with-aolserver=/opt/local/aolserver
    sudo make install 
    cd ../..

Thread

 
    tar xvfz thread2.6.5.tar.gz 
    cd thread2.6.5/unix 
    ../configure    --mandir=/usr/local/share/man    --libdir=/Library/Tcl    --with-tcl=/System/Library/Frameworks/Tcl.framework    --with-tclinclude=/System/Library/Frameworks/Tcl.framework/Headers    --with-aolserver=/opt/local/aolserver 
    sudo make install
    cd ../..

XOTcl

The private header files of Tcl are missing, therefore I got the source and recompiled Tcl:

  curl -L -O http://downloads.sourceforge.net/tcl/tcl8.5.9-src.tar.gz
  tar xfz tcl8.5.9-src.tar.gz
  cd tcl8.5.9/unix
  ./configure --enable-threads --prefix=/opt/local --disable-corefoundation 
  sudo make install
  cd ../..

  tar xvfz xotcl-1.6.7.tar.gz 
  cd xotcl-1.6.7
  NS=/opt/local/aolserver/ 
  ./configure --enable-threads --enable-symbols --prefix=${NS} --exec-prefix=${NS} --with-tcl=/opt/local/lib
  sudo make install-aol
  cd .. 

Now we finish off with tcllib

 
  tar xvfj tcllib-1.13.tar.bz2 
  cd tcllib-1.13
  ./configure --prefix=/opt/local/aolserver/ 
  sudo make install
Type in terminal before starting nsd
  ulimit -n 256
I would recommend to install the server in ~/Sites/yourserver if you don't intend to run multiple different servers with access rights on your machine. Checkout the OpenACS code and Edit ~/Sites/yourserver/etc/config.tcl and make the following changes
# Change the server root
set serverroot                "~/Sites/${server}"

# Make sure that OpenACS finds PostgreSQL. Add two lines to the $database if statement

if { $database eq "oracle" } {
    set db_password           "mysitepassword"
} else {
    set db_host               localhost
    set db_port               ""
    set db_user               $server
    ns_section "ns/db/driver/postgres"
    ns_param   pgbin              /opt/local/lib/postgresql84/bin/
}

# Change the AOLserver location
set homedir                   /opt/local/aolserver

Now you can start up your server. First try ist with /opt/local/aolserver/bin/nsd -t ~/Sites/yourserver/etc/config.tcl. If this works you might want to create a launchctl entry as you did above for postgresql

Edit /Library/LaunchDaemons/org.openacs.YOURSERVER.plist and enter the following

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>Label</key>
        <string>org.openacs.YOURSERVER</string>
        <key>OnDemand</key>
        <false/>
        <key>ProgramArguments</key>
        <array>
            <string>/Users/youruser/Sites/yourserver/etc/daemontools/run</string>
        </array>
        <key>ServiceDescription</key>
        <string>OpenACS Service</string>
        <key>UserName</key>
        <string>youruser</string>
        <key>GroupName</key>
        <string>staff</string>
    </dict>
</plist>

Now put yourserver under launchctl so you can start and stop it: 

sudo launchctl load -w /Library/LaunchDaemons/org.openacs.yourserver.plist 

To start it from then on just call

sudo launchctl start org.openacs.yourserver

To stop it:

sudo launchctl stop org.openacs.yourserver 

It is a good idea to schedule regular backups for your server(s). To do this create a shell script, e.g. backup.sh which executes your backups and then create a launchdaemon plist to run your backups nightly

Edit /Library/LaunchDaemons/org.openacs.backup.plist and enter the following

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>Label</key>
        <string>org.openacs.backup</string>
        <key>ProgramArguments</key>
        <array>
        <string>/Users/youruser/Sites/backup.sh</string>
        </array>
        <key>LowPriorityIO</key>
                <true/>
                <key>Nice</key>
                <integer>1</integer>
                <key>StartCalendarInterval</key>
                <dict>
                        <key>Hour</key>
                        <integer>3</integer>
                        <key>Minute</key>
                        <integer>15</integer>
                </dict>
    </dict>
</plist>

If you intend to run AOLserver on a continous basis remember that it is a great idea to make sure it responds properly. To do this you can run a keepalive service.

Edit /Library/LaunchDaemons/org.openacs.keepalive.plist and enter the following

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>Label</key>
        <string>org.openacs.keepalive.plist</string>
        <key>ProgramArguments</key>
        <array>
            <string>/Users/youruser/Sites/keepalive.sh</string>
	    <string>yourserver</string>
            <string>yourport</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
        <key>StartInterval</key>
        <integer>180</integer>
</dict>
</plist>

Your keepalive.sh could look like this

#!/bin/bash 
GREP=/usr/bin/grep
HEAD="/usr/bin/head -1"

INSTANCE="$1";
PORT="$2"

[ -z "$1" ] && exit
[ -z "$2" ] && exit

MAIL_ADDR=""
WGET_FILE=/tmp/.output-keepalive-${INSTANCE}
URL_TEST="http://127.0.0.1:${PORT}/SYSTEM/dbtest"
[ -f ${WGET_FILE} ] && rm -f ${WGET_FILE}  

_restartwebserver ()
{

/bin/launchctl start org.openacs.$INSTANCE
sleep 3
/bin/launchctl start org.openacs.$INSTANCE
}

_sendmail ()
{
echo "${1}" |mailx -s AolWebserver ${MAIL_ADDR}
}

while [ 1 -eq 1 ];
do
        [ -f ${WGET_FILE} ] && /bin/rm -f ${WGET_FILE}
        /usr/bin/curl -s -o $WGET_FILE --connect-timeout 3 --retry 3 "${URL_TEST}"

        if [ -f ${WGET_FILE} ] 
                then
                FIRST_LINE=`${HEAD} ${WGET_FILE} | ${GREP} -i "success"`
                [ -z "${FIRST_LINE}" ] && _restartwebserver && _sendmail "I just restarted the $INSTANCE webserver on `uname -n`" && echo "`date +'%D-%H:%M'` :: FAILURE" || echo "`date +'%D-%H:%M'` :: success $INSTANCE" >>/Users/malte/Sites/keepalive.log 
                else
                _restartwebserver && _sendmail "I just restarted the $INSTANCE webserver on `uname -n`"
#               _restartwebserver
                echo "`date +'%D-%H:%M'` :: FAILURE"
        fi
done

If you intend to run AOLserver on a continous basis remember that it is a great idea to restart your server once per night, otherwise the memory footprint will grow and grow and grow.

Edit /Library/LaunchDaemons/org.openacs.restart.plist and enter the following

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>Label</key>
        <string>org.openacs.restart</string>
        <key>OnDemand</key>
        <false/>
        <key>ProgramArguments</key>
        <array>
            <string>/Users/youruser/Sites/restart.sh</string>
        </array>
         <key>LowPriorityIO</key>
        <true/>
                <key>Nice</key>
                <integer>1</integer>
                <key>StartCalendarInterval</key>
                <dict>
                        <key>Hour</key>
                        <integer>4</integer>
                        <key>Minute</key>
                        <integer>15</integer>
                </dict>
</dict>
</plist>

Now put scripts under launchctl so they will run in the night: 

sudo launchctl load -w /Library/LaunchDaemons/org.openacs.backup.plist

sudo launchctl load -w /Library/LaunchDaemons/org.openacs.restart.plist

sudo launchctl load -w /Library/LaunchDaemons/org.openacs.keepalive.plist

Your restart.sh could look like this

  #!/bin/bash
  echo "cognovis"
  sudo launchctl stop org.openacs.yourserver
  sleep 10
  sudo launchctl start org.openacs.yourserver 

Commit graph

Created by Jeff Davis, last modified by Jeff Davis 04 Nov 2010, at 03:22 PM

commits.png
NameContent TypeLast ModifiedBy UserSize (Bytes)
commits.pngimage/png2010-11-04 15:22:29+01Jeff Davis4670500

Commits

Created by Jeff Davis, last modified by Jeff Davis 04 Nov 2010, at 03:20 PM

Commit graph

Automated Installs - Using install.xml

Created by Ryan Gallimore, last modified by Ryan Gallimore 10 Apr 2010, at 07:29 PM

To automatically install packages with specific parameters and mount points, create an install.xml file in your /path/to/service/ directory, according to:

 Automated Install Thread

Testing with TCLWebtest

Created by OpenACS community, last modified by Ryan Gallimore 10 Apr 2010, at 06:49 PM

Testing with TCLWebtest

by Simon Carstensen and Joel Aufrecht

Tclwebtest is primarily for testing user interface and acceptance testing.

API testing is only part of testing your package - it doesn't test the code in our adp/tcl pairs. For this, we can use TCLWebtest (see sourceforge). TCLWebtest provides a library of functions (see command reference) that make it easy to call a page through HTTP, examine the results, and drive forms. TCLwebtest's functions overlap slightly with acs-automated-testing; see the example provided for one approach on integrating them.

TCLWebtest must be installed for to work. Since automated testing uses it, it should be part of every OpenACS installation. Note that TCLwebtest is installed automatically by Malte's install script.

Forum Posts:

Command Reference:

  • http://tclwebtest.sourceforge.net/doc/api_public.html 

Articles:

  • Automated Testing Best Practices see: https://openacs.org/doc/automated-testing-best-practices.html
  • testing packages for release en:Package_Testing_Process_

Tools:

  • Webtest-Recorder Firefox extension (TwtR) see http://www.km.co.at/km/twtr This module is a plugin for Firefox. It is used to generate/edit a tclwebtest script which can be used later for regression testing without the need of a browser. There is a certain overlap of the application range between selenium and TwtR. This plugin was developed by Åsmund Realfsen for regression/load testing of the assessment module.

Here are some guidelines on how to write automated tests with TCLWebtest. It is a joy to work with automated testing once you get the hang of it. We will use the "myfirstpackage" as an example.

Create the directory that will contain the test script and edit the script file. The directory location and file name are standards which are recognized by the automated testing package:

[$OPENACS_SERVICE_NAME www]$ mkdir /var/lib/aolserver/$OPENACS_SERVICE_NAME/packages/myfirstpackage/tcl/test
[$OPENACS_SERVICE_NAME www]$ cd /var/lib/aolserver/$OPENACS_SERVICE_NAME/packages/myfirstpackage/tcl/test

[$OPENACS_SERVICE_NAME test]$ emacs myfirstpackages-procs.tcl

Write the tests. This is obviously the big step :) The script should first call ad_library like any normal -procs.tcl file:

ad_library {
    ...
}

To create a test case you call aa_register_case test_case_name.. Once you've created the test case you start writing the needed logic. We'll use the tutorial package, "myfirstpackage," as an example. Let's say you just wrote an API for adding and deleting notes in the notes packages and wanted to test that. You'd probably want to write a test that first creates a note, then verifies that it was inserted, then perhaps deletes it again, and finally verifies that it is gone.

Naturally this means you'll be adding a lot of bogus data to the database, which you're not really interested in having there. To avoid this I usually do two things. I always put all my test code inside a call to aa_run_with_teardown which basically means that all the inserts, deletes, and updates will be rolled back once the test has been executed. A very useful feature. Instead of inserting bogus data like: set name "Simon", I tend to generate a random script in order avoid inserting a value that's already in the database:

set name [ad_generate_random_string]

Here's how the test case looks so far:

aa_register_case mfp_basic_test {
    My test
} {
    aa_run_with_teardown \
       -rollback \
       -test_code  {

       }
}

Now look at the actual test code. That's the code that goes inside -test_code {}. We want to implement test case API-001, "Given an object id from API-001, invoke mfp::note::get. Proc should return the specific word in the title."

      set name [ad_generate_random_string]
      set new_id [mfp::note::add -title $name]
      aa_true "Note add succeeded" [exists_and_not_null new_id]

To test our simple case, we must load the test file into the system (just as with the /tcl file in the basic tutorial, since the file didn't exist when the system started, the system doesn't know about it.) To make this file take effect, go to the APM and choose "Reload changed" for "MyFirstPackage". Since we'll be changing it frequently, select "watch this file" on the next page. This will cause the system to check this file every time any page is requested, which is bad for production systems but convenient for developing. We can also add some aa_register_case flags to make it easier to run the test. The -procs flag, which indicates which procs are tested by this test case, makes it easier to find procs in your package that aren't tested at all. The -cats flag, setting categories, makes it easier to control which tests to run. The smoke test setting means that this is a basic test case that can and should be run any time you are doing any test. (a definition of "smoke test")

Once the file is loaded, go to ACS Automated Testing and click on myfirstpackage. You should see your test case. Run it and examine the results.

Example

Now we can add the rest of the API tests, including a test with deliberately bad data. The complete test looks like:

ad_library {
    Test cases for my first package.
}

aa_register_case \
    -cats {smoke api} \
    -procs {mfp::note::add mfp::note::get mfp::note::delete} \
    mfp_basic_test \
    {
        A simple test that adds, retrieves, and deletes a record.
    } {
        aa_run_with_teardown \
            -rollback \
            -test_code  {
                set name [ad_generate_random_string]
                set new_id [mfp::note::add -title $name]
                aa_true "Note add succeeded" [exists_and_not_null new_id]
                
                mfp::note::get -item_id $new_id -array note_array
                aa_true "Note contains correct title" [string equal $note_array(title) $name]
                
                mfp::note::delete -item_id $new_id
                
                set get_again [catch {mfp::note::get -item_id $new_id -array note_array}]
                aa_false "After deleting a note, retrieving it fails" [expr $get_again == 0]
            }
    }

aa_register_case \
    -cats {api} \
    -procs {mfp::note::add mfp::note::get mfp::note::delete} \
    mfp_bad_data_test \
    {
        A simple test that adds, retrieves, and deletes a record, using some tricky data.
    } {
        aa_run_with_teardown \
            -rollback \
            -test_code  {
                set name {-Bad [BAD] \077 { $Bad}} 
                append name [ad_generate_random_string]
                set new_id [mfp::note::add -title $name]
                aa_true "Note add succeeded" [exists_and_not_null new_id]
                
                mfp::note::get -item_id $new_id -array note_array
                aa_true "Note contains correct title" [string equal $note_array(title) $name]
                aa_log "Title is $name"
                mfp::note::delete -item_id $new_id
                
                set get_again [catch {mfp::note::get -item_id $new_id -array note_array}]
                aa_false "After deleting a note, retrieving it fails" [expr $get_again == 0]
            }
    }


aa_register_case \
    -cats {web smoke} \
    -libraries tclwebtest \
    mfp_web_basic_test \
    {
        A simple tclwebtest test case for the tutorial demo package.
        
        @author Peter Marklund
    } {
        # we need to get a user_id here so that it's available throughout
        # this proc
        set user_id [db_nextval acs_object_id_seq]

        set note_title [ad_generate_random_string]

        # NOTE: Never use the aa_run_with_teardown with the rollback switch
        # when running Tclwebtest tests since this will put the test code in
        # a transaction and changes won't be visible across HTTP requests.
        
        aa_run_with_teardown -test_code {
            
            #-------------------------------------------------------------
            # Login
            #-------------------------------------------------------------
            
            # Make a site-wide admin user for this test
            # We use an admin to avoid permission issues
            array set user_info [twt::user::create -admin -user_id $user_id]
            
            # Login the user
            twt::user::login $user_info(email) $user_info(password)
            
            #-------------------------------------------------------------
            # New Note
            #-------------------------------------------------------------
            
            # Request note-edit page
            set package_uri [apm_package_url_from_key myfirstpackage]
            set edit_uri "${package_uri}note-edit"
            aa_log "[twt::server_url]$edit_uri"
            twt::do_request "[twt::server_url]$edit_uri"
            
            # Submit a new note

            tclwebtest::form find ~n note
            tclwebtest::field find ~n title
            tclwebtest::field fill $note_title
            tclwebtest::form submit
            
            #-------------------------------------------------------------
            # Retrieve note
            #-------------------------------------------------------------
            
            # Request index page and verify that note is in listing
            tclwebtest::do_request $package_uri                 
            aa_true "New note with title \"$note_title\" is found in index page" \
                [string match "*${note_title}*" [tclwebtest::response body]]
            
            #-------------------------------------------------------------
            # Delete Note
            #-------------------------------------------------------------
            # Delete all notes

            # Three options to delete the note
            # 1) go directly to the database to get the id
            # 2) require an API function that takes name and returns ID
            # 3) screen-scrape for the ID
            # all options are problematic.  We'll do #1 in this example:

            set note_id [db_string get_note_id_from_name " 
                select item_id 
                  from cr_items 
                 where name = :note_title  
                   and content_type = 'mfp_note'
            " -default 0]

            aa_log "Deleting note with id $note_id"

            set delete_uri "${package_uri}note-delete?item_id=${note_id}"
            twt::do_request $delete_uri
            
            # Request index page and verify that note is in listing
            tclwebtest::do_request $package_uri                 
            aa_true "Note with title \"$note_title\" is not found in index page after deletion." \
                ![string match "*${note_title}*" [tclwebtest::response body]]
            
        } -teardown_code {
            
            twt::user::delete -user_id $user_id
        }
    }


.LRN Meetings

Created by Alvaro Rodriguez, last modified by Alvaro Rodriguez 10 Mar 2010, at 04:41 AM

Next Meeting: 2010-03-10 18:00 CET/CEST Convert to your local time

Agenda

  • .LRN 2.6 Release

Previous Meetings


2008

Community Metrics in OpenACS

Created by Michael Steigman, last modified by Michael Steigman 09 Dec 2009, at 06:09 PM

What can we provide now?


* WIKI

new pages this week
average: new pages per month
page edits this week
average: page edits per month
average: editors per page

* FORUMS

new threads this week
posts this week
average: new threads per month
average: posts per month
average: forum notification subscriptions per month
ratio: posts per thread (monthly?)

example queries:

hub=# select to_char(r.publish_date, 'YYYY-MM') as month, count(*) from cr_items i join cr_revisions r on (i.item_id = r.item_id) where parent_id = '2239905' group by month order by month desc;
  month  | count
---------+-------
 2009-10 |   123
 2009-09 |   394
 2009-08 |   410
 2009-07 |   671
 2009-06 |   158
 2009-05 |     4
 2009-03 |     8
 2009-01 |     4
 2008-12 |    56
(9 rows)

hub=# select to_char(o.creation_date, 'YYYY-MM') as month, count(*) from cr_items i join acs_objects o on (i.item_id = o.object_id) where parent_id = '2239905' group by month order by month desc;
  month  | count
---------+-------
 2009-10 |     2
 2009-09 |    31
 2009-08 |    38
 2009-07 |    71
 2009-06 |    39
 2009-05 |     2
 2009-03 |     4
 2009-01 |     1
 2008-12 |    12
(9 rows)

hub=# select max(count) from (select count(distinct creation_user) as count from cr_items i join cr_revisions r on (i.item_id = r.item_id) join acs_object\
s o on (o.context_id = r.item_id) where parent_id = '2239905' group by i.item_id) a;
 max
-----
   7
(1 row)

hub=# select avg(count) from (select count(distinct creation_user) as count from cr_items i join cr_revisions r on (i.item_id = r.item_id) join acs_object\
s o on (o.context_id = r.item_id) where parent_id = '2239905' group by i.item_id) a;
        avg
--------------------
 1.4900000000000000
(1 row)

hub=# select count(distinct creation_user), i.item_id from cr_items i join cr_revisions r on (i.item_id = r.item_id) join acs_objects o on (o.context_id =\
 r.item_id) where parent_id = '2239905' group by i.item_id;
 count | item_id
-------+---------
     2 | 2239907
     1 | 2240099
     1 | 2240101
     2 | 2240276
     1 | 2240751
     1 | 2240763
     1 | 2240769
     7 | 2240772
     1 | 2248445
     1 | 2249069
     1 | 2249119
     1 | 2249149
...
     2 | 2714595
     1 | 2716420
     1 | 2721530
     1 | 2722191
     2 | 2724344
     1 | 2731842
     1 | 2752093
(200 rows)

What could we provide in the future?


average: # new/departed group members per day/month/year
average: visit length of group members
2 day answer rate for new threads
average: uploads/downloads per month
average: first answer time for threads
ratio: page view per post (lurk)
etc.

Site Wide File Upload

Created by Dave Bauer, last modified by Dave Bauer 02 Nov 2009, at 09:00 PM

Spec for File Management Overhaul on Hub

Michael Steigman (09/25/09) Updated 11/2/2009

User interface mockups

Big Picture

File management in OpenACS is a complicated affair at the moment. There are
several ways to upload and link to files and this has led to duplicate files, broken links
throughout content blocks and “embedded” files in rich text that are difficult to manage
(among many other issues). We are aiming to unify the file upload, linking and
management model and UI across the site, in order to make it simple to upload, update,
share, reference and delete files.

Organization of Files

To help users in a community or on a site collaborate, weʼd like to allow them to
organize and view files in ways that are intuitive. Taking from OS X, Google, Zoho, Windows et.
al., we envision a series of organizational areas in the files UI corresponding to different
filtering criteria.
Places - within a community, default “places” will include all applications and any other
subfolders the admin wishes to include. All users will see these places.
Views - the views area will include some basic views which should cover a lot of
scenarios (search for in OS Xʼs finder) and will expand with custom views created and
saved on the advanced tab.
Favorites (or bookmarks?) - this organizational area will display folders and files in the
personal file area which the user has marked as interesting anywhere on the site.
Shared - implied by the title, this area shows up in the personal file space and shows
files shared by and to you.

Upload and Linking Mechanisms

We want to allow users to link to/attach/upload files to any type of content and present a
consistent UI when doing this. The easiest way to do this would be to provide the same
interface users normally browse by, as OS X does. The WYSIWYG editor will have to
replicate this environment in a plugin setting. Apps that donʼt use the richtext widget
should be able to “include” a version of the browsing interface that allows for single (and
multiple?) file selection.
Much like hard links in Unix, we envision multiple links to each files. The links should be
viewable at the fileʼs canonical location (visible in the mockups). When no more links to
a file exist, the file can be deleted (think callbacks on link removal). Storing a checksum
for the file upon upload so that we can determine if it already exists within the
community would be beneficial.

Metadata Requirements

We need to be able to map from link to destination file. Within this link, we need to
capture some information - the object weʼre linking from being the primary bit of
information. If this link were to be an instance of a dedicated object type, it could also be
permissioned (i.e., a proxy). It could also point to a particular revision, which would
enable a learning module to point at a stable revision and prevent teaching material
from moving beneath a module author. These do not need to be part of the initial
implementation but should be considered.

Navigation and Page Requirements

We should provide an generic overview page (detailed in the mockups) that describes
the files attached to a piece of content. We need to be able to generate navigation for
content such as wiki pages or forum posts that include a link to the overview page if files
are attached. We also need a single, permanent page to display information about a file (File View in the
mockups).

Shared Folders

Referece Google Docs Shared Folders Feature http://docs.google.com/support/bin/answer.py?hl=en&answer=158074
Reference Zoho Document Management http://www.zoho.com/online-document-management/share-documents-collaborate.html

Use Cases

Upload File From Subsite/Group Files tab

User clicks "Add File" link or button from "Subsite->Files" page.
User sees upload dialog and chooses a file from their computer to upload.
File is added to subsite default folder.
Creation_user is the uploading user.
Parent_id is the default folder for the subsite.
Permissions are inherited from context_id,  all members of subsite can view this file.
Context_id is the default folder for the subsite.

Upload file as attachment to Forums Message (or wiki page, etc.)

(note forums post workflow is not addressed)
User chooses to attach a file to a forum message.
User sees upload dialog and chooses a file from their computer to upload.
File is added to subsite default folder.
Creation_user is the uploading user.
Parent_id is the related object, ie: forum_message
Permissions are inherited from context_id, all members who can see the forum post can see the attached file.
Context_id is the parent_id.

Attach existing file from subsite folder as attachment to Forums Message (or wiki page, etc.)

User chooses to attach a file to a forum message.
User sees file chooser dialog (embedded filter view of subsite files).
User chooses existing file.
Acs_data_link created between forums_message and the uploaded file.

Upload file to personal folder

User browsers to their "workspace" (blah) and chooses Files.
This shows the My Files view.
User chooses Add File.
File is added to user default folder (child of user object).
Parent_id is the user default folder.
Context_id is the parent_id.
Permissions are inherited from the context_id.
Noone else can see or manage these files except the user.

Attach Existing file from personal folder to a forums message etc.

User chooses to attach file to a forums message.
User sees file chooser dialog (embedded filter view of subsite files).
Somehow the user chooses to list My Files and sees a list of all files this user has created.
Use chooses file from personal folder.
User sees message that they will share this file with the group/subsite/community with a checkbox to acknowlege.
A cr_symlink is created (this is the manifestation of "share" in this case.) in the subsite default folder.
Acs_data_link created between symlink and the forums message.
Permissions, parent_id, context_id of original file do not change!
Parent_id of symlink is default folder.
Context_id of symlink is parent_id.
Permissions are inherited from context_id, all members of the subsite can view the symlink (which resolves to the file) as long as it is being shared (the symlink exists.)


View subsite files

User sees a list of files in the subsite folder or any subfolders, that they have permission to see (by default all of them.)
Shows filename/title, description, updated date/time, tags, creation user???
User sees list of Places (packages in the subsite.) Each place filters files that have acs_data_link to objects owned by that package.
User can search filenames(titles/descriptions/tags) using the Search Within feature. Just like google docs. Does not search file contents??
Clicking on a file name opens it but there should be an obvious place to view file information (permissions, revisions, links)
Clicking on a folder shows files/folders in that folder.
User can sort by name or date (asc/desc options, perhaps arrow next to name/date sort option?)
What do we do with pagination? How does search/sort affect pagination?

Experimental!! Sharing a Folder

User creates a folder or chooses an existing folder to share.
Symlink is created in group or target users folders to the shared folder depending on sharing level.
Permissions are granted on the ORIGINAL folder based on the sharing settings. NOTE: how do we do this without screwing something up? That is the sharers are not allowed to DELETE or ADMIN the original folder. But we want to simplify dealing with the items IN that folder.

Next Page
previous December 2025
Sun Mon Tue Wed Thu Fri Sat
30 1 2 3 4 5 6
7 8 9 10 11 12 13
(1) 14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31 1 2 3

Popular tags

17 , 5.10 , 5.10.0 , 5.10.1 , 5.9.0 , 5.9.1 , ad_form , ADP , ajax , aolserver , asynchronous , bgdelivery , bootstrap , bugtracker , CentOS , COMET , compatibility , conference , CSP , CSRF , cvs , debian , docker , docker-compose , emacs , engineering-standards , exec , fedora , FreeBSD , guidelines
No registered users in community xowiki
in last 30 minutes
Contributors

OpenACS.org