[Fusionforge-commits] r7521 - in trunk/gforge: . debian plugins plugins/globalsearch plugins/globalsearch/bin plugins/globalsearch/common plugins/globalsearch/lib plugins/globalsearch/www

Roland Mas lolando at libremir.placard.fr.eu.org
Wed Apr 29 11:42:03 CEST 2009


Author: lolando
Date: 2009-04-29 11:42:02 +0200 (Wed, 29 Apr 2009)
New Revision: 7521

Added:
   trunk/gforge/debian/gforge-plugin-globalsearch.cron.d
   trunk/gforge/debian/gforge-plugin-globalsearch.dirs
   trunk/gforge/debian/gforge-plugin-globalsearch.postinst
   trunk/gforge/debian/gforge-plugin-globalsearch.prerm
   trunk/gforge/plugins/globalsearch/
   trunk/gforge/plugins/globalsearch/README
   trunk/gforge/plugins/globalsearch/TODO
   trunk/gforge/plugins/globalsearch/bin/
   trunk/gforge/plugins/globalsearch/bin/db-delete.pl
   trunk/gforge/plugins/globalsearch/bin/db-upgrade.pl
   trunk/gforge/plugins/globalsearch/bin/get_assoc_sites_projects.pl
   trunk/gforge/plugins/globalsearch/common/
   trunk/gforge/plugins/globalsearch/common/GlobalsearchPlugin.class.php
   trunk/gforge/plugins/globalsearch/common/globalsearch-init.php
   trunk/gforge/plugins/globalsearch/common/globalsearch_edit_utils.php
   trunk/gforge/plugins/globalsearch/common/globalsearch_stats_boxes.php
   trunk/gforge/plugins/globalsearch/lib/
   trunk/gforge/plugins/globalsearch/lib/globalsearch-init.sql
   trunk/gforge/plugins/globalsearch/www/
   trunk/gforge/plugins/globalsearch/www/edit_assoc_sites.php
   trunk/gforge/plugins/globalsearch/www/index.php
Modified:
   trunk/gforge/ChangeLog
   trunk/gforge/debian/changelog
   trunk/gforge/debian/control
   trunk/gforge/debian/rules
Log:
Integrating globalsearch plugin as used by (and maintained for) Adullact

Modified: trunk/gforge/ChangeLog
===================================================================
--- trunk/gforge/ChangeLog	2009-04-29 09:01:37 UTC (rev 7520)
+++ trunk/gforge/ChangeLog	2009-04-29 09:42:02 UTC (rev 7521)
@@ -294,6 +294,41 @@
 
 	* gforge/www/themes/gforge/images/icon.png: New file.
 
+	* plugins/globalsearch: Unearthed plugin, dusted it a bit, and
+	ported it to the current Gforge codebase.
+
+	* plugins/globalsearch/lib/globalsearch-init.sql: Updated foreign
+	key constraints to current (8.2+) PostgreSQL.
+
+	* plugins/globalsearch/bin/db-delete.pl: Use functions defined in
+	sqlhelper.pm.
+
+	* plugins/globalsearch/common/GlobalsearchPlugin.class.php:
+	Renamed from globalsearch-plugin.class to stick with current
+	conventions.
+	* plugins/globalsearch/common/globalsearch-init.php: Update
+	accordingly.
+
+	* plugins/globalsearch/www/index.php: Gettextized file.
+	* plugins/globalsearch/www/globalsearch_stats_boxes.php: Ditto.
+
+	* plugins/globalsearch/www/index.php: Use functions to get
+	parameters from request.  Sanitise these parameters, and act
+	accordingly.
+
+	* plugins/globalsearch/common/globalsearch_edit_utils.php: Renamed
+	from www/admin_table_assoc_site.php, which shouldn't be accessible
+	from the web.
+	* plugins/globalsearch/www/edit_assoc_sites.php: Adapt accordingly.
+
+	* plugins/globalsearch/common/globalsearch_stats_boxes.php: Moved
+	here from www/ since this file shouldn't be available through the
+	web.
+	* plugins/globalsearch/www/index.php: Adapt accordingly.
+
+	* plugins/globalsearch/common/globalsearch_edit_utils.php: Large
+	rewrite for robustness.
+	
 2007-11-21  Roland Mas  <lolando at debian.org>
 
 	* deb-specific/stats_projects_logparse.pl: Parse IPv6 addresses as

Modified: trunk/gforge/debian/changelog
===================================================================
--- trunk/gforge/debian/changelog	2009-04-29 09:01:37 UTC (rev 7520)
+++ trunk/gforge/debian/changelog	2009-04-29 09:42:02 UTC (rev 7521)
@@ -3,8 +3,10 @@
   * Fixed blackhole syntax for gforge-mta-exim4 so as not to require
     file_transport.
   * New extratabs plugin from Adullact.
+  * New globalsearch plugin allowing to publish lists of projects for
+    other forges and to search for projects in remote forges.
   
- -- Roland Mas <lolando at debian.org>  Wed, 29 Apr 2009 10:30:11 +0200
+ -- Roland Mas <lolando at debian.org>  Wed, 29 Apr 2009 11:10:10 +0200
   
 gforge (4.8~rc1-1+1) experimental; urgency=low
 

Modified: trunk/gforge/debian/control
===================================================================
--- trunk/gforge/debian/control	2009-04-29 09:01:37 UTC (rev 7520)
+++ trunk/gforge/debian/control	2009-04-29 09:42:02 UTC (rev 7521)
@@ -253,3 +253,17 @@
  .
  This plugin allows each project to define extra tabs with arbitrary
  titles and links.
+
+Package: gforge-plugin-globalsearch
+Architecture: all
+Depends: gforge-common, gforge-db-postgresql | gforge-db, gforge-web-apache2 | gforge-web, libxml-rss-perl, libgetopt-mixed-perl, libdbi-perl, libwww-perl, libcrypt-ssleay-perl, libunicode-string-perl
+Description: collaborative development tool - Global search plugin
+ GForge provides many tools to aid collaboration in a
+ development project, such as bug-tracking, task management,
+ mailing-lists, SCM repository, forums, support request helper,
+ web/FTP hosting, release management, etc. All these services are
+ integrated into one web site and managed through a web interface.
+ .
+ This plugin contains a cross-Gforge search engine.  You can declare a
+ list of other Gforge sites, and search for projects hosted on these
+ forges from your own.

Added: trunk/gforge/debian/gforge-plugin-globalsearch.cron.d
===================================================================
--- trunk/gforge/debian/gforge-plugin-globalsearch.cron.d	                        (rev 0)
+++ trunk/gforge/debian/gforge-plugin-globalsearch.cron.d	2009-04-29 09:42:02 UTC (rev 7521)
@@ -0,0 +1 @@
+30 3 * * * gforge [ -x /usr/lib/gforge/plugins/globalsearch/bin/get_assoc_sites_projects.pl ] && /usr/lib/gforge/plugins/globalsearch/bin/get_assoc_sites_projects.pl > /dev/null 2>&1

Added: trunk/gforge/debian/gforge-plugin-globalsearch.dirs
===================================================================
--- trunk/gforge/debian/gforge-plugin-globalsearch.dirs	                        (rev 0)
+++ trunk/gforge/debian/gforge-plugin-globalsearch.dirs	2009-04-29 09:42:02 UTC (rev 7521)
@@ -0,0 +1,4 @@
+usr/lib/gforge/plugins/globalsearch/bin
+usr/lib/gforge/plugins/globalsearch/lib
+usr/share/gforge/www/plugins/globalsearch
+usr/share/gforge/plugins/globalsearch/common

Added: trunk/gforge/debian/gforge-plugin-globalsearch.postinst
===================================================================
--- trunk/gforge/debian/gforge-plugin-globalsearch.postinst	                        (rev 0)
+++ trunk/gforge/debian/gforge-plugin-globalsearch.postinst	2009-04-29 09:42:02 UTC (rev 7521)
@@ -0,0 +1,47 @@
+#! /bin/sh
+# postinst script for gforge-plugin-globalsearch
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+#        * <postinst> `configure' <most-recently-configured-version>
+#        * <old-postinst> `abort-upgrade' <new version>
+#        * <conflictor's-postinst> `abort-remove' `in-favour' <package>
+#          <new-version>
+#        * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
+#          <failed-install-package> <version> `removing'
+#          <conflicting-package> <version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+#
+# quoting from the policy:
+#     Any necessary prompting should almost always be confined to the
+#     post-installation script, and should be protected with a conditional
+#     so that unnecessary prompting doesn't happen if a package's
+#     installation fails and the `postinst' is called with `abort-upgrade',
+#     `abort-remove' or `abort-deconfigure'.
+
+case "$1" in
+    configure)
+        /usr/lib/gforge/plugins/globalsearch/bin/db-upgrade.pl
+        /usr/lib/gforge/bin/register-plugin globalsearch "Global Search"
+    ;;
+
+    abort-upgrade|abort-remove|abort-deconfigure)
+
+    ;;
+
+    *)
+        echo "postinst called with unknown argument \`$1'" >&2
+        exit 1
+    ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
\ No newline at end of file

Added: trunk/gforge/debian/gforge-plugin-globalsearch.prerm
===================================================================
--- trunk/gforge/debian/gforge-plugin-globalsearch.prerm	                        (rev 0)
+++ trunk/gforge/debian/gforge-plugin-globalsearch.prerm	2009-04-29 09:42:02 UTC (rev 7521)
@@ -0,0 +1,38 @@
+#! /bin/sh
+# prerm script for gforge-plugin-globalsearch
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+#        * <prerm> `remove'
+#        * <old-prerm> `upgrade' <new-version>
+#        * <new-prerm> `failed-upgrade' <old-version>
+#        * <conflictor's-prerm> `remove' `in-favour' <package> <new-version>
+#        * <deconfigured's-prerm> `deconfigure' `in-favour'
+#          <package-being-installed> <version> `removing'
+#          <conflicting-package> <version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+    remove|deconfigure)
+        /usr/lib/gforge/bin/unregister-plugin globalsearch
+        /usr/lib/gforge/plugins/globalsearch/bin/db-delete.pl
+        ;;
+    upgrade|failed-upgrade)
+        ;;
+    *)
+        echo "prerm called with unknown argument \`$1'" >&2
+        exit 1
+    ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0

Modified: trunk/gforge/debian/rules
===================================================================
--- trunk/gforge/debian/rules	2009-04-29 09:01:37 UTC (rev 7520)
+++ trunk/gforge/debian/rules	2009-04-29 09:42:02 UTC (rev 7521)
@@ -125,6 +125,12 @@
 	chmod 755 $(CURDIR)/debian/$(PACKAGE)-db-postgresql/usr/share/*/db/*.php
 	chmod 644 $(CURDIR)/debian/$(PACKAGE)-db-postgresql/usr/share/gforge/cronjobs/*.inc
 
+	# gforge-plugin-globalsearch
+	cp -r plugins/globalsearch/bin/* $(CURDIR)/debian/gforge-plugin-globalsearch/usr/lib/gforge/plugins/globalsearch/bin/
+	cp -r plugins/globalsearch/lib/* $(CURDIR)/debian/gforge-plugin-globalsearch/usr/lib/gforge/plugins/globalsearch/lib/
+	cp -r plugins/globalsearch/common/* $(CURDIR)/debian/gforge-plugin-globalsearch/usr/share/gforge/plugins/globalsearch/common/
+	cp -r plugins/globalsearch/www/* $(CURDIR)/debian/gforge-plugin-globalsearch/usr/share/gforge/www/plugins/globalsearch/
+
 	# viewvc rights
 	find $(CURDIR)/debian/$(PACKAGE)-web-apache2/usr/share/*/www/scm/viewvc -type f -exec chmod 0644 {} \;
 	grep -ril '^#!' $(CURDIR)/debian/$(PACKAGE)-web-apache2/usr/share/*/www/scm/viewvc | xargs chmod 0755

Added: trunk/gforge/plugins/globalsearch/README
===================================================================
--- trunk/gforge/plugins/globalsearch/README	                        (rev 0)
+++ trunk/gforge/plugins/globalsearch/README	2009-04-29 09:42:02 UTC (rev 7521)
@@ -0,0 +1,34 @@
+README
+------
+This is the readme file for GlobalSearch Gforge plugin.
+It contains an utility to be call in the crond that gets all 
+the RSS's from the list of projects set up in the DB.
+
+TODO                 - There is a TODO file
+
+ROADMAP
+        
+DESIRED FUNCTIONALITY 
+    1) Search in another gforge
+    2) Publish associated sites 
+    3) Ranking/categorizing associated sites
+    4) Local caching
+    5) Plugin integration with Gforge
+
+To test it: http://site.com/plugins/globalsearch/
+PHP code in /usr/share/gforge/www/plugins/globalsearch/*
+include php in /usr/lib/gforge/plugins/globalsearch/include/* 
+Script to fetch rss in /usr/lib/gforge/plugins/globalsearch/bin/*
+sql-init in /usr/lib/gforge/plugins/globalsearch/lib/*
+
+To get the projects of associated sites run (if you can't wait the daily cron):
+/usr/lib/gforge/plugins/globalsearch/bin/get_assoc_sites_projects.pl
+
+New hook for site admin needed:
+  /usr/share/gforge/www/admin/index.php
+  <?php plugin_hook("site_admin_option_hook", false); ?>
+
+See also de debian/README.Debian
+
+Use the sources and the mailing lists:
+  http://ourproject.org/projects/libreprojects
\ No newline at end of file

Added: trunk/gforge/plugins/globalsearch/TODO
===================================================================
--- trunk/gforge/plugins/globalsearch/TODO	                        (rev 0)
+++ trunk/gforge/plugins/globalsearch/TODO	2009-04-29 09:42:02 UTC (rev 7521)
@@ -0,0 +1,18 @@
+lun oct 6 11:36:26 CEST 2003 kikov
+
+        * Try to modify the RSS XML to support extended attributes
+                like License, Dates, Category, etc...
+        
+        * Ring of Gforge sites: a list of the gforge sites subscribed 
+                - Need a param to say if a site is public ( so the url
+                        will be propagated among gforge sites ). It
+                        could have a private associated site.
+                
+        * Categorization support: 
+                - RSS modification needed
+                - Mixing trees needed
+
+        * Project Orders: needed the study
+                - Local info
+                - Distributed info
+                - Rings of Gforge sites needed/supported

Added: trunk/gforge/plugins/globalsearch/bin/db-delete.pl
===================================================================
--- trunk/gforge/plugins/globalsearch/bin/db-delete.pl	                        (rev 0)
+++ trunk/gforge/plugins/globalsearch/bin/db-delete.pl	2009-04-29 09:42:02 UTC (rev 7521)
@@ -0,0 +1,118 @@
+#!/usr/bin/perl -w
+#
+# $Id: db-delete.pl,v 1.1.1.1 2004/03/29 01:20:13 vjrj Exp $
+#
+# Debian-specific script to delete plugin-specific tables
+# Roland Mas <lolando at debian.org>
+
+use strict ;
+use diagnostics ;
+
+use DBI ;
+use MIME::Base64 ;
+use HTML::Entities ;
+
+use vars qw/$dbh @reqlist $query/ ;
+use vars qw/$sys_default_domain $sys_cvs_host $sys_download_host
+    $sys_shell_host $sys_users_host $sys_docs_host $sys_lists_host
+    $sys_dns1_host $sys_dns2_host $FTPINCOMING_DIR $FTPFILES_DIR
+    $sys_urlroot $sf_cache_dir $sys_name $sys_themeroot
+    $sys_news_group $sys_dbhost $sys_dbname $sys_dbuser $sys_dbpasswd
+    $sys_ldap_base_dn $sys_ldap_host $admin_login $admin_password
+    $server_admin $domain_name $newsadmin_groupid $statsadmin_groupid
+    $skill_list/ ;
+use vars qw/$pluginname/ ;
+
+sub is_lesser ( $$ ) ;
+sub is_greater ( $$ ) ;
+sub debug ( $ ) ;
+sub parse_sql_file ( $ ) ;
+
+require ("/usr/lib/gforge/lib/include.pl") ; # Include a few predefined functions 
+require ("/usr/lib/gforge/lib/sqlparser.pm") ; # Our magic SQL parser
+require ("/usr/lib/gforge/lib/sqlhelper.pm") ; # A few SQL helper functions
+
+debug "You'll see some debugging info during this installation." ;
+debug "Do not worry unless told otherwise." ;
+
+&db_connect ;
+
+# debug "Connected to the database OK." ;
+
+$pluginname = "globalsearch" ;
+
+$dbh->{AutoCommit} = 0;
+$dbh->{RaiseError} = 1;
+eval {
+    my ($sth, @array, $version, $action, $path, $target, $rname) ;
+
+    # Drop a few tables in a specific order
+    &drop_table_if_exists ($dbh, "plugin_globalsearch_assoc_site_project") ;
+    &drop_table_if_exists ($dbh, "plugin_globalsearch_assoc_site") ;
+    &drop_table_if_exists ($dbh, "plugin_globalsearch_assoc_status") ;
+
+    # Then drop any remaining data structures
+    my $pattern = "plugin_" . $pluginname . '_%' ;
+
+    $query = "SELECT relname FROM pg_class WHERE relname LIKE '$pattern' AND relkind='v'" ;
+    $sth = $dbh->prepare ($query) ;
+    $sth->execute () ;
+    while (@array = $sth->fetchrow_array ()) {
+        $rname = $array [0] ;
+        &drop_view_if_exists ($dbh, $rname) ;
+    }
+    $sth->finish () ;
+
+    $query = "SELECT relname FROM pg_class WHERE relname LIKE '$pattern' AND relkind='r'" ;
+    $sth = $dbh->prepare ($query) ;
+    $sth->execute () ;
+    while (@array = $sth->fetchrow_array ()) {
+        $rname = $array [0] ;
+        &drop_table_if_exists ($dbh, $rname) ;
+    }
+    $sth->finish () ;
+
+    $query = "SELECT relname FROM pg_class WHERE relname LIKE '$pattern' AND relkind='i'" ;
+    $sth = $dbh->prepare ($query) ;
+    $sth->execute () ;
+    while (@array = $sth->fetchrow_array ()) {
+        $rname = $array [0] ;
+        &drop_index_if_exists ($dbh, $rname) ;
+    }
+    $sth->finish () ;
+
+    $query = "SELECT relname FROM pg_class WHERE relname LIKE '$pattern' AND relkind='S'" ;
+    $sth = $dbh->prepare ($query) ;
+    $sth->execute () ;
+    while (@array = $sth->fetchrow_array ()) {
+        $rname = $array [0] ;
+        &drop_sequence_if_exists ($dbh, $rname) ;
+    }
+    $sth->finish () ;
+
+    $dbh->commit ();
+
+
+    debug "It seems your database deletion went well and smoothly.  That's cool." ;
+    debug "Please enjoy using Debian GForge." ;
+
+    # There should be a commit at the end of every block above.
+    # If there is not, then it might be symptomatic of a problem.
+    # For safety, we roll back.
+    $dbh->rollback ();
+};
+
+if ($@) {
+    warn "Transaction aborted because $@" ;
+    debug "Transaction aborted because $@" ;
+    debug "Last SQL query was:\n$query\n(end of query)" ;
+    $dbh->rollback ;
+    debug "Please report this bug on the Debian bug-tracking system." ;
+    debug "Please include the previous messages as well to help debugging." ;
+    debug "You should not worry too much about this," ;
+    debug "your DB is still in a consistent state and should be usable." ;
+    exit 1 ;
+}
+
+$dbh->rollback ;
+$dbh->disconnect ;


Property changes on: trunk/gforge/plugins/globalsearch/bin/db-delete.pl
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gforge/plugins/globalsearch/bin/db-upgrade.pl
===================================================================
--- trunk/gforge/plugins/globalsearch/bin/db-upgrade.pl	                        (rev 0)
+++ trunk/gforge/plugins/globalsearch/bin/db-upgrade.pl	2009-04-29 09:42:02 UTC (rev 7521)
@@ -0,0 +1,303 @@
+#!/usr/bin/perl -w
+#
+# $Id: db-upgrade.pl,v 1.1.1.1 2004/03/29 01:20:13 vjrj Exp $
+#
+# Debian-specific script to upgrade the database between releases
+# Roland Mas <lolando at debian.org>
+
+use strict ;
+use diagnostics ;
+
+use DBI ;
+use MIME::Base64 ;
+use HTML::Entities ;
+
+use vars qw/$dbh @reqlist $query/ ;
+use vars qw/$sys_default_domain $sys_cvs_host $sys_download_host
+    $sys_shell_host $sys_users_host $sys_docs_host $sys_lists_host
+    $sys_dns1_host $sys_dns2_host $FTPINCOMING_DIR $FTPFILES_DIR
+    $sys_urlroot $sf_cache_dir $sys_name $sys_themeroot
+    $sys_news_group $sys_dbhost $sys_dbname $sys_dbuser $sys_dbpasswd
+    $sys_ldap_base_dn $sys_ldap_host $admin_login $admin_password
+    $server_admin $domain_name $newsadmin_groupid $statsadmin_groupid
+    $skill_list/ ;
+use vars qw/$pluginname/ ;
+
+sub is_lesser ( $$ ) ;
+sub is_greater ( $$ ) ;
+sub debug ( $ ) ;
+sub parse_sql_file ( $ ) ;
+
+require ("/usr/lib/gforge/lib/include.pl") ; # Include a few predefined functions 
+require ("/usr/lib/gforge/lib/sqlparser.pm") ; # Our magic SQL parser
+
+debug "You'll see some debugging info during this installation." ;
+debug "Do not worry unless told otherwise." ;
+
+&db_connect ;
+
+# debug "Connected to the database OK." ;
+
+$pluginname = "globalsearch" ;
+
+$dbh->{AutoCommit} = 0;
+$dbh->{RaiseError} = 1;
+eval {
+    my ($sth, @array, $version, $path, $target) ;
+
+    &create_metadata_table ("0") ;
+    
+    $version = &get_db_version ;
+    $target = "0.1" ;
+    if (is_lesser $version, $target) {
+        my @filelist = ( "/usr/lib/gforge/plugins/$pluginname/lib/$pluginname-init.sql" ) ;
+        
+        foreach my $file (@filelist) {
+            debug "Processing $file" ;
+            @reqlist = @{ &parse_sql_file ($file) } ;
+            
+            foreach my $s (@reqlist) {
+                $query = $s ;
+                # debug $query ;
+                $sth = $dbh->prepare ($query) ;
+                $sth->execute () ;
+                $sth->finish () ;
+            }
+        }
+        @reqlist = () ;
+        
+        &update_db_version ($target) ;
+        debug "Committing." ;
+        $dbh->commit () ;
+    }
+    
+    $version = &get_db_version ;
+    $target = "0.2" ;
+    if (is_lesser $version, $target) {
+    debug "Adding local data." ;
+        
+    do "/etc/gforge/local.pl" or die "Cannot read /etc/gforge/local.pl" ;
+        
+    my $ip_address = qx/host $domain_name | awk '{print \$3}'/ ;
+        
+        @reqlist = (
+  #        "INSERT INTO plugin_".$pluginname."_sample_data (domain, ip_address) VALUES ('$domain_name', '$ip_address')",
+                    ) ;
+        
+        foreach my $s (@reqlist) {
+            $query = $s ;
+            # debug $query ;
+            $sth = $dbh->prepare ($query) ;
+            $sth->execute () ;
+            $sth->finish () ;
+        }
+        @reqlist = () ;
+        
+        &update_db_version ($target) ;
+        debug "Committing." ;
+        $dbh->commit () ;
+    }
+
+    debug "It seems your database install/upgrade went well and smoothly.  That's cool." ;
+    debug "Please enjoy using Debian GForge." ;
+
+    # There should be a commit at the end of every block above.
+    # If there is not, then it might be symptomatic of a problem.
+    # For safety, we roll back.
+    $dbh->rollback ();
+};
+
+if ($@) {
+    warn "Transaction aborted because $@" ;
+    debug "Transaction aborted because $@" ;
+    debug "Last SQL query was:\n$query\n(end of query)" ;
+    $dbh->rollback ;
+    debug "Please report this bug on the Debian bug-tracking system." ;
+    debug "Please include the previous messages as well to help debugging." ;
+    debug "You should not worry too much about this," ;
+    debug "your DB is still in a consistent state and should be usable." ;
+    exit 1 ;
+}
+
+$dbh->rollback ;
+$dbh->disconnect ;
+
+sub is_lesser ( $$ ) {
+    my $v1 = shift || 0 ;
+    my $v2 = shift || 0 ;
+
+    my $rc = system "dpkg --compare-versions $v1 lt $v2" ;
+
+    return (! $rc) ;
+}
+
+sub is_greater ( $$ ) {
+    my $v1 = shift || 0 ;
+    my $v2 = shift || 0 ;
+
+    my $rc = system "dpkg --compare-versions $v1 gt $v2" ;
+
+    return (! $rc) ;
+}
+
+sub debug ( $ ) {
+    my $v = shift ;
+    chomp $v ;
+    print STDERR "$v\n" ;
+}
+
+sub create_metadata_table ( $ ) {
+    my $v = shift || "0" ;
+    my $tablename = "plugin_" .$pluginname . "_meta_data" ;
+    # Do we have the metadata table?
+
+    $query = "SELECT count(*) FROM pg_class WHERE relname = '$tablename' and relkind = 'r'";
+    # debug $query ;
+    my $sth = $dbh->prepare ($query) ;
+    $sth->execute () ;
+    my @array = $sth->fetchrow_array () ;
+    $sth->finish () ;
+
+    # Let's create this table if we have it not
+
+    if ($array [0] == 0) {
+        debug "Creating $tablename table." ;
+        $query = "CREATE TABLE $tablename (key varchar primary key, value text not null)" ;
+        # debug $query ;
+        $sth = $dbh->prepare ($query) ;
+        $sth->execute () ;
+        $sth->finish () ;
+    }
+
+    $query = "SELECT count(*) FROM $tablename WHERE key = 'db-version'";
+    # debug $query ;
+    $sth = $dbh->prepare ($query) ;
+    $sth->execute () ;
+    @array = $sth->fetchrow_array () ;
+    $sth->finish () ;
+
+    # Empty table?  We'll have to fill it up a bit
+
+    if ($array [0] == 0) {
+        debug "Inserting first data into $tablename table." ;
+        $query = "INSERT INTO $tablename (key, value) VALUES ('db-version', '$v')" ;
+        # debug $query ;
+        $sth = $dbh->prepare ($query) ;
+        $sth->execute () ;
+        $sth->finish () ;
+    }
+}
+
+sub update_db_version ( $ ) {
+    my $v = shift or die "Not enough arguments" ;
+    my $tablename = "plugin_" .$pluginname . "_meta_data" ;
+
+    debug "Updating $tablename table." ;
+    $query = "UPDATE $tablename SET value = '$v' WHERE key = 'db-version'" ;
+    # debug $query ;
+    my $sth = $dbh->prepare ($query) ;
+    $sth->execute () ;
+    $sth->finish () ;
+}
+
+sub get_db_version () {
+    my $tablename = "plugin_" .$pluginname . "_meta_data" ;
+
+    $query = "SELECT value FROM $tablename WHERE key = 'db-version'" ;
+    # debug $query ;
+    my $sth = $dbh->prepare ($query) ;
+    $sth->execute () ;
+    my @array = $sth->fetchrow_array () ;
+    $sth->finish () ;
+
+    my $version = $array [0] ;
+
+    return $version ;
+}
+
+sub drop_table_if_exists ( $ ) {
+    my $tname = shift or die  "Not enough arguments" ;
+    $query = "SELECT count(*) FROM pg_class WHERE relname='$tname' AND relkind='r'" ;
+    my $sth = $dbh->prepare ($query) ;
+    $sth->execute () ;
+    my @array = $sth->fetchrow_array () ;
+    $sth->finish () ;
+
+    if ($array [0] != 0) {
+        # debug "Dropping table $tname" ;
+        $query = "DROP TABLE $tname" ;
+        # debug $query ;
+        $sth = $dbh->prepare ($query) ;
+        $sth->execute () ;
+        $sth->finish () ;
+    }
+}
+
+sub drop_sequence_if_exists ( $ ) {
+    my $sname = shift or die  "Not enough arguments" ;
+    $query = "SELECT count(*) FROM pg_class WHERE relname='$sname' AND relkind='S'" ;
+    my $sth = $dbh->prepare ($query) ;
+    $sth->execute () ;
+    my @array = $sth->fetchrow_array () ;
+    $sth->finish () ;
+
+    if ($array [0] != 0) {
+        # debug "Dropping sequence $sname" ;
+        $query = "DROP SEQUENCE $sname" ;
+        # debug $query ;
+        $sth = $dbh->prepare ($query) ;
+        $sth->execute () ;
+        $sth->finish () ;
+    }
+}
+
+sub drop_index_if_exists ( $ ) {
+    my $iname = shift or die  "Not enough arguments" ;
+    $query = "SELECT count(*) FROM pg_class WHERE relname='$iname' AND relkind='i'" ;
+    my $sth = $dbh->prepare ($query) ;
+    $sth->execute () ;
+    my @array = $sth->fetchrow_array () ;
+    $sth->finish () ;
+
+    if ($array [0] != 0) {
+        # debug "Dropping index $iname" ;
+        $query = "DROP INDEX $iname" ;
+        # debug $query ;
+        $sth = $dbh->prepare ($query) ;
+        $sth->execute () ;
+        $sth->finish () ;
+    }
+}
+
+sub drop_view_if_exists ( $ ) {
+    my $iname = shift or die  "Not enough arguments" ;
+    $query = "SELECT count(*) FROM pg_class WHERE relname='$iname' AND relkind='v'" ;
+    my $sth = $dbh->prepare ($query) ;
+    $sth->execute () ;
+    my @array = $sth->fetchrow_array () ;
+    $sth->finish () ;
+
+    if ($array [0] != 0) {
+        # debug "Dropping view $iname" ;
+        $query = "DROP VIEW $iname" ;
+        # debug $query ;
+        $sth = $dbh->prepare ($query) ;
+        $sth->execute () ;
+        $sth->finish () ;
+    }
+}
+
+sub bump_sequence_to ( $$ ) {
+    my ($sth, @array, $seqname, $targetvalue) ;
+
+    $seqname = shift ;
+    $targetvalue = shift ;
+
+    do {
+        $query = "select nextval ('$seqname')" ;
+        $sth = $dbh->prepare ($query) ;
+        $sth->execute () ;
+        @array = $sth->fetchrow_array () ;
+        $sth->finish () ;
+    } until $array[0] >= $targetvalue ;
+}


Property changes on: trunk/gforge/plugins/globalsearch/bin/db-upgrade.pl
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gforge/plugins/globalsearch/bin/get_assoc_sites_projects.pl
===================================================================
--- trunk/gforge/plugins/globalsearch/bin/get_assoc_sites_projects.pl	                        (rev 0)
+++ trunk/gforge/plugins/globalsearch/bin/get_assoc_sites_projects.pl	2009-04-29 09:42:02 UTC (rev 7521)
@@ -0,0 +1,199 @@
+#!/usr/bin/perl -w
+#
+# get_assoc_sites_projects.pl: script to get the projects of 
+#   sites associated, to try to make a ring of gforges sindicates
+#   by Vicente J. Ruiz Jurado (vjrj AT ourproject.org) Mar-2004
+#
+# depends: libgetopt-mixed-perl (Getopt::Long), libdbi-perl (DBI),
+#          libxml-rss-perl (XML::RSS), libwww-perl (LWP::Simple),
+#          libcrypt-ssleay-perl (for https sites),
+#          libunicode-string-perl (Unicode::String)
+#
+use DBI;
+use Getopt::Long qw(:config require_order);
+use XML::RSS;
+use LWP::UserAgent ;
+use Unicode::String qw(latin1 utf8);
+
+use strict;
+
+require("/usr/lib/gforge/lib/include.pl");  # Include all predefined functions
+
+# DB 
+#-------------------------------------------------------------------------------
+use vars qw/ $dbh / ; # Predeclaration of global vars
+
+# Variables
+#-------------------------------------------------------------------------------
+
+my $numArgs = @ARGV;
+my @args = @ARGV;
+
+sub usage();
+sub changeSiteStatus($$);
+sub deleteProjectsOfSite($);
+sub myescape($);
+
+
+my $debug;
+my $debugsql;
+my $assoc_site;
+my @results_array;
+my ($projecttitle, $projectlink, $projectdesc);
+
+my $ua = new LWP::UserAgent ;
+# Default get timeout to 30 seconds
+$ua->timeout(30);
+$ua->env_proxy ;
+
+# Options check
+#-------------------------------------------------------------------------------
+
+my $resultOptions = GetOptions(
+"debug" => \$debug,
+"debugsql" => \$debugsql
+);
+
+unless (($debug && $resultOptions == 2) || 
+                                ($debugsql && $resultOptions == 2) || 
+                                (($debug) && ($debugsql) && $resultOptions == 3) || 
+                                ($resultOptions == 1)) {
+        usage();
+        exit(1);
+}
+
+# Start to get de RSS
+#-------------------------------------------------------------------------------
+
+if ($debug) {print STDERR "Getting the associated sites.\n"};
+
+&db_connect;
+$dbh->{AutoCommit} = 0;
+$dbh->{RaiseError} = 1;
+
+my $query = "SELECT assoc_site_id, title, link, onlysw, status_id, rank 
+        FROM plugin_globalsearch_assoc_site WHERE enabled='t' ORDER BY rank";
+
+my $sth = $dbh->prepare($query);
+$sth->execute();
+
+while (my @array = $sth->fetchrow_array ()) {
+        push @results_array, \@array ;
+}
+$sth->execute() or die "Problems with the query '$query' in DB";
+$sth->finish() or die "Problems with the query '$query' in DB";
+$dbh->commit or die $dbh->errstr;
+
+foreach $assoc_site (@results_array) {
+        my ($assoc_site_id, $title, $link, $onlysw, $enabled, $status_id, $rank) = @{$assoc_site};
+        my $urlrss = $link."/export/rss_sfprojects.php";
+        my $response = $ua->get($urlrss);
+	
+        if ($response->is_success) {
+   	        my $content = $response->content ;
+                # Correct RSS get
+                if ($debug) {print STDERR "$title get ok.\n"};
+
+                my $rss = new XML::RSS (version => '0.91', encoding => "UTF-8");
+
+                eval {$rss->parse($content);}; 
+                if ($@) {
+                        # Parse error
+                        if ($debug) {print STDERR "ERROR parsing $title.\n"};
+
+                        # Site in db to status unparsable
+                        changeSiteStatus($assoc_site_id, 4);
+                        deleteProjectsOfSite($assoc_site_id);
+                }
+                else {
+                        # Parse ok
+                        deleteProjectsOfSite($assoc_site_id);
+                        # Insert projects in db
+                        if ($debug) {print STDERR "Inserting site $title projects\n"};
+                        foreach my $item (@{$rss->{'items'}}) {
+                                next unless (defined($item->{'title'}) && defined($item->{'link'}) && defined($item->{'description'}));
+                                # utf8 checking
+                                $projecttitle = myescape(utf8($item->{'title'}));
+                                $projectlink = myescape(utf8($item->{'link'}));
+                                $projectdesc = myescape(utf8($item->{'description'}));
+
+                                my $insert = "INSERT INTO plugin_globalsearch_assoc_site_project ".
+                                        "(assoc_site_id, project_title, project_link, project_description) ".
+                                        "VALUES ('$assoc_site_id','$projecttitle','$projectlink','$projectdesc')";
+
+                                if ($debugsql) {print STDERR "SQL: $insert\n"};
+
+                                my $sth = $dbh->prepare($insert);
+                                $sth->execute() or die "Problems with the insert of '$insert' in DB";
+                                $sth->finish() or die "Problems with the insert of '$insert' in DB";
+                                $dbh->commit or die $dbh->errstr;                                
+                        }
+
+                        # Site in db to status ok
+                        changeSiteStatus($assoc_site_id, 2);
+                }
+        }
+        else {
+                # Incorrect RSS get
+                if ($debug) {
+		    print STDERR "$urlrss get fail:\n" ;
+		    print STDERR $response->status_line()."\n" ;
+		};
+
+                # RSS in db to status fail
+                changeSiteStatus($assoc_site_id, 3);
+                deleteProjectsOfSite($assoc_site_id);
+        }
+}
+
+if ($debug) {print STDERR "get_assoc_sites_projects process finished ok\n"};
+exit(0);
+
+# Funcitions
+#-------------------------------------------------------------------------------
+
+sub usage() {
+        print STDERR "usage: get_assoc_sites_projects.pl [--debug] [--debugsql]\n";
+}
+
+
+sub changeSiteStatus($$) {
+        my $site = shift;
+        my $status = shift;
+
+        my $update = "UPDATE plugin_globalsearch_assoc_site SET status_id='$status' WHERE assoc_site_id='$site'";
+
+        if ($debugsql) {print STDERR "SQL: $update\n"};
+        my $sth = $dbh->prepare($update);
+        $sth->execute() or die "Problems with the update of '$update' in DB";
+        $sth->finish() or die "Problems with the update of '$update' in DB";
+        $dbh->commit or die $dbh->errstr;
+
+        return 0;
+}
+
+
+sub deleteProjectsOfSite($) {
+        my $site = shift;
+
+        if ($debug) {print STDERR "Deleting the projects of site $site.\n"};
+
+        my $delete = "DELETE FROM plugin_globalsearch_assoc_site_project WHERE assoc_site_id='$site'";
+
+        if ($debugsql) {print STDERR "SQL: $delete\n"};
+
+        my $sth = $dbh->prepare($delete);
+        $sth->execute() or die "Problems with the delete of '$delete' in DB";
+        $sth->finish() or die "Problems with the delete of '$delete' in DB";
+        $dbh->commit or die $dbh->errstr;
+
+        return 0;
+}
+
+sub myescape($) {
+        my $stringtoesc = shift;
+  $stringtoesc =~ s/'/''/g;
+  $stringtoesc =~ s/\\/\\\\/g;
+
+        return $stringtoesc;
+}


Property changes on: trunk/gforge/plugins/globalsearch/bin/get_assoc_sites_projects.pl
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/gforge/plugins/globalsearch/common/GlobalsearchPlugin.class.php
===================================================================
--- trunk/gforge/plugins/globalsearch/common/GlobalsearchPlugin.class.php	                        (rev 0)
+++ trunk/gforge/plugins/globalsearch/common/GlobalsearchPlugin.class.php	2009-04-29 09:42:02 UTC (rev 7521)
@@ -0,0 +1,47 @@
+<?php
+/**
+ * FusionForge globalsearch plugin
+ *
+ * Copyright 2003-2004, GForge, LLC
+ * Copyright 2007-2009, Roland Mas
+ *
+ * This file is part of FusionForge.
+ *
+ * FusionForge is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2 of the License,
+ * or (at your option) any later version.
+ * 
+ * FusionForge is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FusionForge; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+class globalSearchPlugin extends Plugin {
+        function globalSearchPlugin () {
+                $this->Plugin() ;
+                $this->name = "globalsearch" ;
+                $this->hooks[] = "site_admin_option_hook" ;
+        }
+
+        function CallHook ($hookname, $params) {
+                global $Language, $G_SESSION, $HTML, $group_id;
+
+                if ($hookname == "site_admin_option_hook") {
+                        print '<li><a href="/plugins/globalsearch/edit_assoc_sites.php">'._("Admin Associated Sites").'</a></li>';
+                }
+        }
+}
+
+// Local Variables:
+// mode: php
+// c-file-style: "bsd"
+// End:
+
+?>

Added: trunk/gforge/plugins/globalsearch/common/globalsearch-init.php
===================================================================
--- trunk/gforge/plugins/globalsearch/common/globalsearch-init.php	                        (rev 0)
+++ trunk/gforge/plugins/globalsearch/common/globalsearch-init.php	2009-04-29 09:42:02 UTC (rev 7521)
@@ -0,0 +1,14 @@
+<?php
+
+require_once ($GLOBALS['sys_plugins_path'].'/globalsearch/common/GlobalsearchPlugin.class.php') ;
+
+$globalSearchPluginObject = new globalSearchPlugin ;
+
+register_plugin ($globalSearchPluginObject) ;
+
+// Local Variables:
+// mode: php
+// c-file-style: "bsd"
+// End:
+
+?>

Added: trunk/gforge/plugins/globalsearch/common/globalsearch_edit_utils.php
===================================================================
--- trunk/gforge/plugins/globalsearch/common/globalsearch_edit_utils.php	                        (rev 0)
+++ trunk/gforge/plugins/globalsearch/common/globalsearch_edit_utils.php	2009-04-29 09:42:02 UTC (rev 7521)
@@ -0,0 +1,257 @@
+<?php
+/**
+ * FusionForge globalsearch plugin
+ *
+ * Copyright 1999-2001, VA Linux Systems, Inc.
+ * Copyright 2003-2004, GForge, LLC
+ * Copyright 2007-2009, Roland Mas
+ *
+ * This file is part of FusionForge.
+ *
+ * FusionForge is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2 of the License,
+ * or (at your option) any later version.
+ * 
+ * FusionForge is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FusionForge; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+/**
+ *      globalsearch_admin_table_add() - present a form for adding a record to the specified table
+ */
+function globalsearch_admin_table_add () {
+        global $PHP_SELF;
+
+	echo _('Create a new associated site below');
+	echo '<form name="add" action="'.$PHP_SELF.'?function=postadd" method="post">
+                        <table>';
+
+	echo '<tr><td><strong>'._('Title').'</strong></td><td><input type="text" name="title" /></td></tr>';
+	echo '<tr><td><strong>'._('Link').'</strong></td><td><input type="text" name="link" /></td></tr>';
+	echo '<tr><td><strong>'._('Software only').'</strong></td><td><input type="checkbox" checked name="onlysw" value="t"/></td></tr>';
+	echo '<tr><td><strong>'._('Enabled').'</strong></td><td><input type="checkbox" checked name="enabled" value="t"/></td></tr>';
+	echo '<tr><td><strong>'._('Rank').'</strong></td><td><input type="text" name="rank" /></td></tr>';
+	
+	echo '</table><input type="submit" value="'._('Submit new associated site').'" /></form>
+                        <form name="cancel" action="'.$PHP_SELF.'" method="post">
+                        <input type="submit" value="Cancel" />
+                        </form>';
+}
+
+/**
+ *      globalsearch_admin_table_postadd() - update the database based on a submitted change
+ */
+function globalsearch_admin_table_postadd () {
+	$new_title     = getStringFromRequest ('title');
+	$new_link      = getStringFromRequest ('link');
+	$new_onlysw    = getStringFromRequest ('onlysw');
+	$new_enabled   = getStringFromRequest ('enabled');
+	$new_rank      = getIntFromRequest ('rank', 1);
+	if ($new_onlysw != 't' and $new_onlysw != 'f') {
+		$new_onlysw = 'f' ;
+	}
+	if ($new_enabled != 't' and $new_enabled != 'f') {
+		$new_enabled = 'f' ;
+	}
+
+        $sql = "INSERT INTO plugin_globalsearch_assoc_site (title, link, onlysw, enabled, rank)
+VALUES ('$new_title', '$new_link', '$new_onlysw', '$new_enabled', '$new_rank')" ;
+
+        if (db_query($sql)) {
+		echo _('Associated site successfully added.');
+        } else {
+                echo db_error();
+        }
+}
+
+/**
+ *      globalsearch_admin_table_confirmdelete() - present a form to confirm requested record deletion
+ *
+ *      @param $id - the id of the record to act on
+ */
+function globalsearch_admin_table_confirmdelete ($id) {
+        global $PHP_SELF;
+
+        $result = db_query("SELECT * FROM plugin_globalsearch_assoc_site WHERE assoc_site_id=$id");
+        if ($result and db_numrows($result) == 1) {
+		$title     =  db_result ($result, 0, 'title');
+		$link      =  db_result ($result, 0, 'link');
+		$onlysw    =  db_result ($result, 0, 'onlysw');
+		$enabled   =  db_result ($result, 0, 'enabled');
+		$rank      =  db_result ($result, 0, 'rank', 1);
+
+                echo _('Are you sure you want to delete this associated site?') ;
+		echo '<table>';
+		echo '<tr><td><strong>'._('Title').'</strong></td><td>'.$title.'</td></tr>';
+		echo '<tr><td><strong>'._('Link').'</strong></td><td>'.$link.'</td></tr>';
+		echo '<tr><td><strong>'._('Software only').'</strong></td><td>'.(($onlysw == 't')?_('Yes'):_('No')) .'</td></tr>';
+		echo '<tr><td><strong>'._('Enabled').'</strong></td><td>'.(($enabled == 't')?_('Yes'):_('No')) .'</td></tr>';
+		echo '<tr><td><strong>'._('Rank').'</strong></td><td>'.$rank.'</td></tr>';
+		echo '</table>' ;
+		echo '<form name="delete" action="'.$PHP_SELF.'?function=delete&amp;id='.$id.'" method="post">
+                        <input type="submit" value="'._('Delete').'" />
+                        </form>
+                        <form name="cancel" action="'.$PHP_SELF.'" method="post">
+                        <input type="submit" value="'._('Cancel').'" />
+                        </form>';
+        } else {
+                echo db_error();
+        }
+}
+
+/**
+ *      globalsearch_admin_table_delete() - delete a record from the database after confirmation
+ *
+ *      @param $id - the id of the record to act on
+ */
+function globalsearch_admin_table_delete ($id) {
+        if (db_query("DELETE FROM plugin_globalsearch_assoc_site WHERE assoc_site_id=$id")) {
+		echo _('Associated site successfully deleted.');
+        } else {
+                echo db_error();
+        }
+}
+
+/**
+ *      globalsearch_admin_table_edit() - present a form for editing a record in the specified table
+ *
+ *      @param $id - the id of the record to act on
+ */
+function globalsearch_admin_table_edit ($id) {
+        global $PHP_SELF;
+
+        $result = db_query("SELECT * FROM plugin_globalsearch_assoc_site WHERE assoc_site_id=$id");
+        if ($result and db_numrows($result) == 1) {
+		$old_title     =  db_result ($result, 0, 'title');
+		$old_link      =  db_result ($result, 0, 'link');
+		$old_onlysw    =  db_result ($result, 0, 'onlysw');
+		$old_enabled   =  db_result ($result, 0, 'enabled');
+		$old_rank      =  db_result ($result, 0, 'rank', 1);
+
+                echo _('Modify the associated site below');
+		echo '<form name="edit" action="'.$PHP_SELF.'?function=postedit&amp;id='.$id.'" method="post">
+                        <table>';
+
+		echo '<tr><td><strong>'._('Title').'</strong></td><td><input type="text" name="title" value="'.$old_title.'"/></td></tr>';
+		echo '<tr><td><strong>'._('Link').'</strong></td><td><input type="text" name="link" value="'.$old_link.'"/></td></tr>';
+		echo '<tr><td><strong>'._('Software only').'</strong></td><td><input type="checkbox" '.(($old_onlysw == 't')?'checked':'') .' name="onlysw" value="t"/></td></tr>';
+		echo '<tr><td><strong>'._('Enabled').'</strong></td><td><input type="checkbox" '.(($old_enabled == 't')?'checked':'') .' name="enabled" value="t"/></td></tr>';
+		echo '<tr><td><strong>'._('Rank').'</strong></td><td><input type="text" name="rank" value="'.$old_rank.'"/></td></tr>';
+		
+		echo '</table><input type="submit" value="'._('Submit changes').'" /></form>
+                        <form name="cancel" action="'.$PHP_SELF.'" method="post">
+                        <input type="submit" value="'._('Cancel').'" />
+                        </form>';
+        } else {
+                echo db_error();
+        }
+}
+
+/**
+ *      globalsearch_admin_table_postedit() - update the database to reflect submitted modifications to a record
+ *
+ *      @param $id - the id of the record to act on
+ */
+function globalsearch_admin_table_postedit ($id) {
+	$new_title     = getStringFromRequest ('title');
+	$new_link      = getStringFromRequest ('link');
+	$new_onlysw    = getStringFromRequest ('onlysw');
+	$new_enabled   = getStringFromRequest ('enabled');
+	$new_rank      = getIntFromRequest ('rank', 999);
+	if ($new_onlysw != 't' and $new_onlysw != 'f') {
+		$new_onlysw = 'f' ;
+	}
+	if ($new_enabled != 't' and $new_enabled != 'f') {
+		$new_enabled = 'f' ;
+	}
+
+        $sql = 'UPDATE plugin_globalsearch_assoc_site SET ';
+
+	$sql .= "title='$new_title', ";
+	$sql .= "link='$new_link', ";
+	$sql .= "onlysw='$new_onlysw', ";
+	$sql .= "enabled='$new_enabled', ";
+	$sql .= "rank='$new_rank' ";
+
+        $sql .= "WHERE assoc_site_id=$id";
+
+        if (db_query($sql)) {
+		echo _('Associated site successfully modified.');
+        } else {
+                echo db_error();
+        }
+}
+
+/**
+ *      globalsearch_admin_table_show() - display the specified table, sorted by the primary key, with links to add, edit, and delete
+ */
+function globalsearch_admin_table_show () {
+        global $HTML, $PHP_SELF;
+
+        $result = db_query("SELECT * FROM plugin_globalsearch_assoc_site ORDER BY assoc_site_id");
+        if ($result) {
+                $rows = db_numrows($result);
+
+                $cell_data=array();
+                $cell_data[]=array(ngettext('Associated site','Associated sites',$rows).' <a href="'.$PHP_SELF.'?function=add">'._('[add new]').'</a>',
+                        'colspan="8"');
+
+                echo '<table border="0" width="100%">';
+                echo $HTML->multiTableRow('',$cell_data, TRUE);
+
+		echo '<td width="5%"></td>';
+		echo '<td><strong>'._('Site ID').'</strong></td>';
+		echo '<td><strong>'._('Title').'</strong></td>';
+		echo '<td><strong>'._('Link').'</strong></td>';
+		echo '<td><strong>'._('Software only').'</strong></td>';
+		echo '<td><strong>'._('Enabled').'</strong></td>';
+		echo '<td><strong>'._('Status').'</strong></td>';
+		echo '<td><strong>'._('Rank').'</strong></td>';
+                echo '</tr>';
+
+                for ($j = 0; $j < $rows; $j++) {
+                        echo '<tr '. $HTML->boxGetAltRowStyle($j) . '>';
+
+                        $id = db_result($result,$j,0);
+                        echo '<td><a href="'.$PHP_SELF.'?function=edit&amp;id='.$id.'">'._('[edit]').'</a> ';
+                        echo '<a href="'.$PHP_SELF.'?function=confirmdelete&amp;id='.$id.'">'._('[delete]').'</a> </td>';
+
+			echo '<td><strong>'.db_result ($result, $j, 'assoc_site_id').'</strong></td>';
+			echo '<td><strong>'.db_result ($result, $j, 'title').'</strong></td>';
+			echo '<td><strong>'.db_result ($result, $j, 'link').'</strong></td>';
+			echo '<td><strong>'.((db_result ($result, $j, 'onlysw') == 't')?_('Yes'):_('No')).'</strong></td>';
+			echo '<td><strong>'.((db_result ($result, $j, 'enabled') == 't')?_('Yes'):_('No')).'</strong></td>';
+			echo '<td><strong>'.globalsearch_status_name (db_result ($result, $j, 'status_id')).'</strong></td>';
+			echo '<td><strong>'.db_result ($result, $j, 'rank').'</strong></td>';
+			echo '</tr>';
+                }
+                echo '</table>';
+        } else {
+                echo db_error();
+        }
+}
+	
+function globalsearch_status_name ($status_id) {
+	switch ($status_id) {
+	case 1: return _('New'); break; 
+	case 2: return _('OK'); break; 
+	case 3: return _('Error fetching data'); break; 
+	case 4: return _('Error parsing data'); break; 
+	default: return _('Unknown status ID');
+	}
+}
+
+// Local Variables:
+// mode: php
+// c-file-style: "bsd"
+// End:
+
+?>

Added: trunk/gforge/plugins/globalsearch/common/globalsearch_stats_boxes.php
===================================================================
--- trunk/gforge/plugins/globalsearch/common/globalsearch_stats_boxes.php	                        (rev 0)
+++ trunk/gforge/plugins/globalsearch/common/globalsearch_stats_boxes.php	2009-04-29 09:42:02 UTC (rev 7521)
@@ -0,0 +1,112 @@
+<?php
+/**
+ * FusionForge globalsearch plugin
+ *
+ * Copyright 2003-2004, GForge, LLC
+ * Copyright 2007-2009, Roland Mas
+ *
+ * This file is part of FusionForge.
+ *
+ * FusionForge is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2 of the License,
+ * or (at your option) any later version.
+ * 
+ * FusionForge is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FusionForge; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+require_once('common/include/GForge.class.php');
+
+function show_globalsearch_stats_boxes() {
+        GLOBAL $HTML,$Language;
+        
+        $return = '';
+        $return .= $HTML->boxTop(_("Global Search"));
+        $return .= globalsearch_box();
+        $return .= $HTML->boxMiddle(_("Top associated sites stats"));
+        $return .= show_top_n_assocsites(5);
+        $return .= "<div align=\"center\">".sprintf(_("Total projects in associated sites: <b>%1$d</b>"),stats_get_total_projects_assoc_sites()). "</div>";
+        $return .= $HTML->boxBottom();
+        return $return;
+}
+
+function globalsearch_box() {
+        global $Language,$gwords,$gexact,$otherfreeknowledge;
+
+        $return = 'Search in other associated sites:<br />
+        <form method="post" action="/plugins/globalsearch/"/>
+        <input width="100%" type="text" name="gwords" value="'.$gwords.'"/>
+        <input type="submit" name="Search" value="'._("Search").'" /><br/>
+        <input type="checkbox" name="otherfreeknowledge" value="1"'.( $otherfreeknowledge ? ' checked' : ' unchecked' ).'>'._('Extend search to include non-software projects').'<br/>
+        <input type="checkbox" name="gexact" value="1"'.( $gexact ? ' checked' : ' unchecked' ).'>'._("Require all words").'</form>';
+        return $return;
+}
+
+/**
+ * show_top_n_assocsites() - Show the n top ranked associated sites
+ *
+ * @param   string  Number of associated sites to show
+ *
+ */
+
+function show_top_n_assocsites($num_assocsites) {
+        global $Language;
+
+        $res_top_n_assoc = db_query("
+                SELECT a.title, a.link, count(*) AS numprojects 
+                FROM plugin_globalsearch_assoc_site_project p, plugin_globalsearch_assoc_site a 
+                WHERE p.assoc_site_id = a.assoc_site_id AND p.assoc_site_id IN 
+                        (SELECT assoc_site_id FROM plugin_globalsearch_assoc_site 
+                        WHERE status_id = 2 AND enabled='t' ORDER BY rank LIMIT $num_assocsites) 
+                GROUP BY a.title, a.link");
+
+        if (db_numrows($res_top_n_assoc) == 0) {
+		return _('No stats available')." ".db_error();
+        }
+
+        $return .= "<div align=\"left\"><table>";
+        while ($row_topdown = db_fetch_array($res_top_n_assoc)) {
+                if ($row_topdown['numprojects'] > 0)
+                        $return .= "<tr><td><a href=\"$row_topdown[link]/\">";
+                        $return .= $row_topdown[title]."</a></td>"; 
+                        $return .= "<td><div align=\"right\">". number_format($row_topdown[numprojects], 0);
+                        $return .= " projects</div></td></tr>\n";
+        }
+        $return .= "</div></table>";
+        
+        return $return;
+}
+
+/**
+ * stats_get_total_projects_assoc_sites() - Show the total number of projects of associated sites
+ *
+ * @param   string  Number of associated sites to show
+ *
+ */
+
+function stats_get_total_projects_assoc_sites() {
+  global $Language;
+
+        $res_count = db_query("SELECT count(*) AS numprojects FROM plugin_globalsearch_assoc_site_project p, plugin_globalsearch_assoc_site a WHERE p.assoc_site_id = a.assoc_site_id AND a.status_id = 2");
+        if (db_numrows($res_count) > 0) {
+                $row_count = db_fetch_array($res_count);
+                return $row_count['numprojects'];
+        } else {
+		return _('No stats available')." ".db_error();
+        }
+}
+
+// Local Variables:
+// mode: php
+// c-file-style: "bsd"
+// End:
+
+?>

Added: trunk/gforge/plugins/globalsearch/lib/globalsearch-init.sql
===================================================================
--- trunk/gforge/plugins/globalsearch/lib/globalsearch-init.sql	                        (rev 0)
+++ trunk/gforge/plugins/globalsearch/lib/globalsearch-init.sql	2009-04-29 09:42:02 UTC (rev 7521)
@@ -0,0 +1,51 @@
+CREATE SEQUENCE "plugin_globalsearch_assoc_status_pk_seq" start 1 increment 1 maxvalue 2147483647 minvalue 1 cache 1;
+CREATE TABLE "plugin_globalsearch_assoc_status" (
+  "status_id" integer DEFAULT nextval('plugin_globalsearch_assoc_status_pk_seq'::text) NOT NULL,
+  "status_name" text DEFAULT '' NOT NULL,
+  CONSTRAINT "plugin_globalsearch_assoc_status_pkey" PRIMARY KEY ("status_id")
+);
+
+COPY "plugin_globalsearch_assoc_status" FROM stdin;
+1	New
+2	Ok
+3	Fail
+4	Unparsable
+\.
+SELECT setval ('"plugin_globalsearch_assoc_status_pk_seq"', 4, false);
+
+CREATE SEQUENCE "plugin_globalsearch_assoc_site_pk_seq" start 1 increment 1 maxvalue 2147483647 minvalue 1 cache 1;
+CREATE TABLE "plugin_globalsearch_assoc_site" (
+  "assoc_site_id" integer DEFAULT nextval('plugin_globalsearch_assoc_site_pk_seq'::text) NOT NULL,
+  "title" text,
+  "link" text,
+  "onlysw" boolean DEFAULT 't'::bool,
+  "enabled" boolean DEFAULT 't'::bool,
+  "status_id" integer DEFAULT '1' NOT NULL,
+  "rank" integer DEFAULT '1' NOT NULL,
+  CONSTRAINT "plugin_globalsearch_assoc_site_pkey" PRIMARY KEY ("assoc_site_id"),
+  CONSTRAINT "plugin_globalsearch_assoc_site_status_fkey" FOREIGN KEY (status_id) REFERENCES plugin_globalsearch_assoc_status(status_id)
+);
+
+COPY "plugin_globalsearch_assoc_site" FROM stdin;
+1	GForge.org	http://gforge.org/	t	t	1	1
+2	Alioth	https://alioth.debian.org/	t	t	1	2
+\.
+SELECT setval ('"plugin_globalsearch_assoc_site_pk_seq"', 2, false);
+
+CREATE TABLE "plugin_globalsearch_assoc_site_project" (
+  "assoc_site_id" integer DEFAULT '0' NOT NULL,
+  "project_title" text,
+  "project_link" text,
+  "project_description" text,
+  CONSTRAINT "plugin_globalsearch_assoc_site_project_site_fkey" FOREIGN KEY (assoc_site_id) REFERENCES plugin_globalsearch_assoc_site (assoc_site_id)
+);
+
+CREATE INDEX plugin_globalsearch_assoc_title_idx ON plugin_globalsearch_assoc_site USING btree (title);
+CREATE INDEX plugin_globalsearch_assoc_status_idx ON plugin_globalsearch_assoc_site USING btree (status_id);
+CREATE INDEX plugin_globalsearch_assoc_enabled_idx ON plugin_globalsearch_assoc_site USING btree (enabled);
+CREATE INDEX plugin_globalsearch_assoc_onlysw_idx ON plugin_globalsearch_assoc_site USING btree (onlysw);
+CREATE INDEX plugin_globalsearch_assoc_rank_idx ON plugin_globalsearch_assoc_site USING btree (rank);
+CREATE INDEX plugin_globalsearch_assocproj_asid_idx ON plugin_globalsearch_assoc_site_project USING btree (assoc_site_id);
+CREATE INDEX plugin_globalsearch_assocproj_titl_idx ON plugin_globalsearch_assoc_site_project USING btree (project_title);
+CREATE INDEX plugin_globalsearch_assocproj_link_idx ON plugin_globalsearch_assoc_site_project USING btree (project_link);
+CREATE INDEX plugin_globalsearch_assocproj_desc_idx ON plugin_globalsearch_assoc_site_project USING btree (project_description);

Added: trunk/gforge/plugins/globalsearch/www/edit_assoc_sites.php
===================================================================
--- trunk/gforge/plugins/globalsearch/www/edit_assoc_sites.php	                        (rev 0)
+++ trunk/gforge/plugins/globalsearch/www/edit_assoc_sites.php	2009-04-29 09:42:02 UTC (rev 7521)
@@ -0,0 +1,69 @@
+<?php
+/**
+ * FusionForge globalsearch plugin
+ *
+ * Copyright 2003-2004, GForge, LLC
+ * Copyright 2007-2009, Roland Mas
+ *
+ * This file is part of FusionForge.
+ *
+ * FusionForge is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2 of the License,
+ * or (at your option) any later version.
+ * 
+ * FusionForge is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FusionForge; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+require_once('pre.php');
+session_require(array('group'=>'1','admin_flags'=>'A'));
+include_once($GLOBALS['sys_plugins_path'].'/globalsearch/common/globalsearch_edit_utils.php');
+
+$HTML->header(array('title'=>_('Edit associated sites for global search')));
+
+echo '<h3>'._('Edit associated sites for global search').'</h3>
+<p><a href="/admin/">'._("Site Admin Home").'</a></p>';
+
+$function = getStringFromRequest ('function');
+$id = getIntFromRequest ('id');
+
+switch ($function) {
+        case 'add' : {
+                globalsearch_admin_table_add ();
+                break;
+        }
+        case 'postadd' : {
+                globalsearch_admin_table_postadd ();
+                break;
+        }
+        case 'confirmdelete' : {
+                globalsearch_admin_table_confirmdelete ($id);
+                break;
+        }
+        case 'delete' : {
+                globalsearch_admin_table_delete ($id);
+                break;
+        }
+        case 'edit' : {
+                globalsearch_admin_table_edit ($id);
+                break;
+        }
+        case 'postedit' : {
+                globalsearch_admin_table_postedit ($id);
+                break;
+        }
+}
+
+echo globalsearch_admin_table_show ();
+
+$HTML->footer(array());
+
+?>

Added: trunk/gforge/plugins/globalsearch/www/index.php
===================================================================
--- trunk/gforge/plugins/globalsearch/www/index.php	                        (rev 0)
+++ trunk/gforge/plugins/globalsearch/www/index.php	2009-04-29 09:42:02 UTC (rev 7521)
@@ -0,0 +1,210 @@
+<?php
+/**
+ * FusionForge globalsearch plugin
+ *
+ * Copyright 2003-2004 GForge, LLC
+ * Copyright 2007-2009, Roland Mas
+ *
+ * This file is part of FusionForge.
+ *
+ * FusionForge is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2 of the License,
+ * or (at your option) any later version.
+ * 
+ * FusionForge is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FusionForge; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+/**
+  *
+  * Parameters:
+  *   $gwords     = target words to search
+  *   $gexact     = 1 for search ing all words (AND), 0 - for any word (OR)
+  *   $otherfreeknowledge = 1 for search in Free/Libre Knowledge Gforge Initiatives
+  *   $order = "project_title" or "title"    -  criteria for ordering results: if empty or not allowed results are ordered by rank
+  *
+  */
+
+require_once('pre.php');
+require_once($GLOBALS['sys_plugins_path'].'/globalsearch/common/globalsearch_stats_boxes.php');
+
+$otherfreeknowledge = getIntFromRequest('otherfreeknowledge') ;
+$gwords = getStringFromRequest('gwords');
+$order = getStringFromRequest('order', 'rank');
+$offset = getStringFromRequest('offset');
+$gexact = getStringFromRequest('gexact');
+
+// Support for short aliases
+if (!$otherfreeknowledge) {
+        $otherfreeknowledge = 0;
+        $onlysw = "";
+}
+else {
+        $onlysw = "AND onlysw = 'f' ";
+}
+
+
+if ( ($order != "project_title") 
+     and ($order != "title") 
+     and ($order != "rank") ) {
+        $order = "rank";
+}
+
+function highlight_target_words($word_array,$text) {
+        if (!$text) {
+                return '&nbsp;';
+        }
+        $re=implode($word_array,'|');
+        return eregi_replace("($re)",'<span style="background-color:pink">\1</span>',$text);
+}
+
+$HTML->header(array('title'=>'Search','pagename'=>'search'));
+
+echo "<p>";
+
+// show search box which will return results on
+// this very page (default is to open new window)
+echo globalsearch_box();
+
+/*
+        Force them to enter at least three characters
+*/
+
+$gwords = htmlspecialchars(trim($gwords));
+$gwords = ereg_replace("[ \t]+", ' ', $gwords);
+
+if ($gwords && (strlen($gwords) < 3)) {
+        echo "<h2>"._("Search must be at least three characters")."</h2>";
+        $HTML->footer(array());
+        exit;
+}
+
+if (!$gwords) {
+        echo "<br /><b>"._("Enter Your Search Words Above")."</b></p>";
+        $HTML->footer(array());
+        exit;
+}
+
+$no_rows = 0;
+
+if ($gexact) {
+        $crit='AND';
+} else {
+        $crit='OR';
+}
+
+if (!$offset || $offset < 0) {
+        $offset = 0;
+}
+
+/*
+        Query to find projects
+*/
+
+// If multiple words, separate them and put ILIKE (pgsql's 
+// case-insensitive LIKE) in between
+// XXX:SQL: this assumes db understands backslash-quoting
+
+$array=explode(" ",quotemeta($gwords));
+// we need to use double-backslashes in SQL
+$array_re=explode(" ",addslashes(quotemeta($gwords)));
+
+$gwords1="project_title ILIKE '%" . implode($array,"%' $crit project_title ILIKE '%") ."%'";
+$gwords2="project_description ILIKE '%" . implode($array,"%' $crit project_description ILIKE '%") . "%'";
+
+$sql = "SELECT project_title, project_link, project_description, title, link "
+        ."FROM plugin_globalsearch_assoc_site_project, plugin_globalsearch_assoc_site "
+        ."WHERE plugin_globalsearch_assoc_site_project.assoc_site_id = plugin_globalsearch_assoc_site.assoc_site_id "
+        ."AND enabled = 't' AND status_id = 2 "
+        .$onlysw
+        ."AND (($gwords1) OR ($gwords2)) "
+        ."ORDER BY lower(".$order.")";
+
+$limit=25;
+
+$result = db_query($sql, $limit+1, $offset, SYS_DB_SEARCH);
+$rows = $rows_returned = db_numrows($result);
+
+if (!$result || $rows < 1) {
+        $no_rows = 1;
+        echo "<h2>".sprintf (_("No matches found for %1$s"),$gwords)."</h2>";
+        echo db_error();
+
+} else {
+
+        if ( $rows_returned > $limit) {
+                $rows = $limit;
+        }
+
+        echo "<h3>".sprintf (_("Search results for %1$s"),$gwords)."</h3><p>\n\n";
+
+        $title_arr = array();
+        $title_arr[] = '<a href="/plugins/globalsearch/?gwords='.urlencode($gwords).'&amp;order=project_title&amp;gexact='.$gexact.'">'._("Project Name").'</a>';
+        $title_arr[] = _('Description');
+        $title_arr[] = '<a href="/plugins/globalsearch/?gwords='.urlencode($gwords).'&amp;order=title&amp;gexact='.$gexact.'">'._("Site").'</a>';
+
+        echo $GLOBALS['HTML']->listTableTop($title_arr);
+
+        for ( $i = 0; $i < $rows; $i++ ) {
+                if (db_result($result, $i, 'type') == 2) {
+                        $what = 'foundry';
+                } else {
+                        $what = 'projects';
+                }
+                
+                print        "<tr ". $HTML->boxGetAltRowStyle($i)."><td><a href=\""
+                        . db_result($result, $i, 'project_link')."\" target=\"blank\">"
+                        . html_image("ic/msg.png","10","12",array("border"=>"0"))."&nbsp;"
+                        . highlight_target_words($array,db_result($result, $i, 'project_title'))."</a></td>"
+                        . "<td>".highlight_target_words($array,db_result($result,$i,'project_description'))."</td>"
+                        . "<td><center><a href=\"".db_result($result,$i,'link')."\" target=\"_blank\">"
+                        . db_result($result,$i,'title')."</a></center></td></tr>\n";
+        }
+
+        echo $GLOBALS['HTML']->listTableBottom();
+
+}
+
+   // This code puts the nice next/prev.
+if ( !$no_rows && ( ($rows_returned > $rows) || ($offset != 0) ) ) {
+
+        echo "<br />\n";
+
+        echo "<table style=\"background-color:".$HTML->COLOR_LTBACK1."\" width=\"100%\" cellpadding=\"5\" cellspacing=\"0\">\n";
+        echo "<tr>\n";
+        echo "\t<td align=\"left\">";
+        if ($offset != 0) {
+                echo "<span style=\"font-family:arial, helvetica;text-decoration: none\">";
+                echo "<a href=\"/plugins/globalsearch/?gwords=".urlencode($gwords)."&amp;order=".urlencode($order)."&amp;gexact=$gexact&amp;offset=".($offset-25);
+                echo "\"><strong>"._("Previous Results")."</strong></a></span>";
+        } else {
+                echo "&nbsp;";
+        }
+        echo "</td>\n\t<td align=\"right\">";
+        if ( $rows_returned > $rows) {
+                echo "<span style=\"font-family:arial, helvetica;text-decoration: none\">";
+                echo "<a href=\"/plugins/globalsearch/?gwords=".urlencode($gwords)."&amp;order=".urlencode($order)."&amp;gexact=$gexact&amp;offset=".($offset+25);
+                echo "\"><strong>"._("Next Results") . html_image("t.png","15","15",array("border"=>"0","align"=>"middle")) . "</strong></a></span>";
+        } else {
+                echo "&nbsp;";
+        }
+        echo "</td>\n</tr>\n";
+        echo "</table>\n";
+}
+
+$HTML->footer(array());
+
+// Local Variables:
+// mode: php
+// c-file-style: "bsd"
+// End:
+
+?>




More information about the Fusionforge-commits mailing list