bboard is an ACS application package built to provide
+scalable discussion forums to a community of users. As in older
+versions, bboard provides:
+
+
posting, browsing, and reading of messages in discussion forums
+
tools for moderators to maintain editorial standards
+
categorization and retrieval for knowledge management
+
+
+The initial 4.0 implementation adds the following new features:
+
+
+
fully templated presentation layer for easy customization
+
improved access control on bboard operations to support a wide
+variety of publisher policies
+
support for multiple distinct configurations of the bboard package
+(e.g. different forums and options at http://foo.com/bboard/ and
+http://foo.com/pittsburgh/bboard/)
+
+
+
+
The ACS 4.0 version of bboard is a re-engineering of
+the data model and presentation layer without certain capabilities
+present in the ACS 3.4 bboard. In future releases we intend to
+achieve the same level of maturity as the older bboard
+while building on the flexibility of the new design.
+
+In particular this implementation (9/2000) does not include the
+following features found in prior versions:
+
+
+
support for expiring messages
+
facilities for spamming dynamic classes of bboard users
+
bboard messages with rich media attachments
+
email alert functionality
+
full text messages searching
+
+
+
bboard is not intended to be the ultimate
+customizable web based discussion system. It is intended to be a
+practical and useful system that supports forums much like the
+photo.net Q&A forum. Publishers with special needs are encouraged to
+implement their solution as a module, much like bboard, built atop the
+framework acs-messaging provides.
+
+
acs-messaging is a general purpose component that
+provides threaded messaging services to higher level applications such
+as bboard. The motivation is to provide a base level
+data model and reusable presentation code that enables the rapid
+customization of messaging applications. acs-messaging is intended to
+simplify modules like general comments and
+webmail, as well as specialized messaging applications
+such as scorecard's geospatial
+bboard. Such a framework keeps custom organizational metadata,
+pageflow and navigation, and publishing and moderation policy separate
+from the basic tools needed for discussion.
+
+
III. Historical Considerations
+
+Over the course of ACS development, bboard has grown to
+encompass a wide variety of functionality. Much of this functionality
+was developed first for bboard and only later adapted
+into more general mechanisms (e.g. alerts, security, group scoping,
+etc.,). However bboard wasn't refactored to take
+advantage of the more general facilities, and its complexity
+challenged those in need of custom features. Furthermore there was a
+lot of ad hoc mechanism in both the data model and page flow to
+support different presentation styles, navigation schemes, and access
+control models. Although this bboard proved to be
+useful, scalable, and reliable, the ability to maintain and extend
+this code suffered.
+
+The ACS 4.0 release of bboard mimics the basic functionality of older
+bboard versions but built atop new ACS 4.0 general
+mechanisms (objects, persmissions, templating, acs-messaging,
+etc.,). .
+
+
IV. Competitive Analysis
+
+An analysis of the bboard feature space should be added here.
+
+
+
USENET a la gnus
+
slashdot
+
Userland
+
????
+
+
+
V. Design Tradeoffs
+
+
How does one reconcile all the possible discussion forums mentioned
+above into a single module? One does not! bboard is
+precisely one way to implement a discussion forum and should not be
+all things. In time, there should be a toolkit of components (user
+interface, data model, and procedural) for developers to assemble
+their custom.
+
+
Although many of the entities in the data model are implemented as
+subtyples of ACS object, we avoid using information from the ACS
+object table for anything but auditing purposes. For example, we
+could store a message's author in the ACS object creation_user field,
+however to keep query performance in line we rather use the author field
+in acs_messages.
+
+
VI. API
+
+
As of the initial ACS 4.0 release, acs-messaging and
+bboard do not provide well defined programming
+interfaces.
+
+
Although convenience functions will be provided for basic
+transactions on the acs-messaging and bboard
+entities, it remains to be seen what sort of abstraction layer is most
+appropriate.
+
+
VII. Data Model Discussion
+
+
acs-messaging defines the view
+acs_messages_all for the storage and access of threaded
+text messages and assorted information relevant to their display,
+access, and creation. Under the covers acs-messaging use the
+content repository for underlying storage.
+
+
bboard uses acs-messaging messages, and
+organizes them into forums and categories. For the purposed of the
+ACS permissions system, forums contain messages, and so any
+permissions on a forum will default to being inherited for individual
+messages.
+
+
A forum may be designated as moderated, in which case explicit
+approvals or denials are stored in the
+bboard_message_moderation. Messages without entries in
+the moderation table are considered unseen, and will be displayed or
+hidden in moderated forums based on policy.
+
+
Each forum may have some number of categories, tags denoting further
+specialization within a forum. Messages of a forum may be tagged as being
+in any of the categories pertaining to that forum.
+
+
Permissions
+
+Permissions in ACS 4.0 involve 3 interrelated hierarchies: users &
+groups, objects, and privileges. The user and group hiearchy is
+generally explained elsewhere.
+
+The short explanation:
+
+The long explanation:
+
+BBoard defines the following permissions:
+
+
+
nested under the create permission:
+
bboard_create_forum
+
bboard_create_category
+
bboard_create_message
+
+
nested under the write permission:
+
bboard_write_forum
+
bboard_write_category
+
bboard_write_message
+
+
nested under the read permission:
+
bboard_read_forum
+
bboard_read_category
+
bboard_read_message
+
+
nested under the delete permission:
+
bboard_delete_forum
+
bboard_delete_category
+
bboard_delete_message
+
+
nested under the moderate permission:
+
bboard_moderate_forum
+
+
+
VIII. User Interface
+
+
IX. Configuration/Parameters
+
+
X. Acceptance Tests
+
+
XI. Future Improvements/Areas of Likely Change
+
+
Much of the functionality of the ACS content repository will
+eventually provide tangible benefits to bboard and any
+acs-messaging application. Foremost among these features
+will be full text searching and rich media attachments.
+
+
When ACS provides a general mechanism for an installation to send and
+receive email, bboard can provide email alerts and
+email based reply and post.
+
+Version 4.0.2b6 of BBoard is Yet Another Attempt to get 4.0.2
+released. This version requires ACS 4.0.1 but has been tested against
+4.1 as well. A lot of bugs have been fixed and minor features implemented:
+
+
+
emailing a friend or email alerts should no longer leave persistent garbage around.
+
a link is now provided for uncategorized messages.
+
cleaner views
+
deletion of threads as well as just messages
+
email alerts show a link to the message and indicate which forum they came from
+
+
+For improved functionality you should upgrade to the latest version of
+ACS 4.1 and the latest version of ACS Messaging (as of 2/13/01 4.1.1
+NOT included in ACS 4.1).
+
+For more details on bugfixes and improvements, visit the bboard
+section of the ArsDigita
+SDM.
+
+Note: This documentation has not been reviewed and is
+not considered up to standards. More comprehensive and more refined
+documentation will be available in an upcoming point release. If you
+have further questions, feel free to ask on the applications
+bboard.
+
+
+
Overview
+
+BBoard implements a system for persistent asynchronous web based
+discussions. A BBoard instance as configured from ACS-Admin can
+contain some number for discussion forums. Each forums provides a
+context for users with appropriate access to read and post messages.
+Messages may optionally be tagged in a list categories to facilitate
+sorting and searching.
+
+
Installation
+
+Using bboard requires an operating ACS 4.0.1 installation. If you
+haven't upgraded, do so first! Installing and enabling the bboard
+package should be relatively painless: just go to your server's
+/acs-admin/apm/package-load page and enter
+"http://www.arsdigita.com/acs-repository/download/apm/bboard-4.0.2r1.apm".
+If you're reading this on your own server, you've already done
+this.
+
+Once the package is installed and enabled, a subsite administrator can
+then mount instances on their subsite. If you're the lone
+über-admin of your site, you can just go to your site's
+/admin/site-nodes/ page and create a new subfolder under the "/"
+directory. Pick a creative label for your subfolder like "bboard" or
+"dg". Select "new application" for that subfolder, and choose BBoard
+from the pulldown menu. It is probably best to label the application
+instance the same as your subfolder; do otherwise if it helps you keep
+your site straight.
+
+At this point you should have a BBoard instance mounted in the
+subfolder directory, let's say you chose "/bboard". Before delving
+into configuration, let's run over BBoard's permissions model.
+
+
Initial Configuration
+
+Once mounted, you can surf over to /bboard as an administrator, create
+some forums, and start discussing that crazy U.S. election!
+
+The following parameters are configurable on a package instance basic from the
+appropirate node in /admin/site-nodes/.
+
+
+
+
ThreadingEnabledP
+
+
This enables or disables threading indentation on a single thread
+basis. "t" enables threading and "f" (the default) turns it off.
+
+
MailFriendEnabledP
+
+
This enables the option for users to mail copies of a bboard
+posting to a friend (or themselves). Since this functionality can be
+abused, consider disabling the functionality.
+
+
UserPostsEditableP
+
+
This grants users privileges to edit their own message. Note:
+toggling this parameter will not change the ability of user to edit
+existing messages. This parameter only effects whether users are
+granted rights to edit at the message's posting time. This must be
+enabled for attachments to work.
+
+
AttachmentsEnabledP
+
+
This lets users who have edit capability on a message upload file
+or image attachments.
+
+
MaxAttachmentSize
+
+
This specifies the maximum size in bytes to accept for binary
+attachments. The default is 1 megabyte.
+
+
DisplayLastNDays
+
+
This parameter controls how many days worth of recent messages are
+displayed on the forum overview page by default. 0 specifies
+that all messages should be displayed.
+
+
+
+
Advanced Configuration and Permissions Overview
+
+The ACS 4.0 permissions system is about hierarchies and in particular
+hiearchical containment. There are three important hiearchies: the
+user hierarchy (users, groups, and parties), the object hierarchy
+(objects nested in the contexts of others), and the privilege hiearchy
+(privileges can entail other entails). This complexity of mechanism
+is designed to allow for simplicity of use for programmers and
+administrators. Unfortunately, interfaces to facilitate this
+simplicity of use are not here yet. Until then, sophisticated control
+and configuration of BBoard necessitates an understanding of these
+details.
+
+The first hierarchy is straightforward. There are users and groups
+(or together parties). Privileges granted to groups inherit to their
+members.
+
+Unless explicitly disabled (see below), privileges granted to parties
+are inherited down an object hierarchy. The nature of the BBoard
+hierarchy is as follows: subsites contain bboard package instances;
+bboard package instances contain forums; forums contain both
+categories and messages. Privileges granted to parties on the package
+instance are inherited to all the forums nested within and so on.
+
+The third hiearchy is the least clear. Privileges can be nested into
+other privileges. This lets us group related privileges like those
+for reading a message and reading a forum together to allow us to
+easily grant "read access" on a hiearchy of objects to a party even
+though there are separate notions of "read a message" and "read a
+forum". All the bboard privileges are nested in one of the following
+system level "super"-privileges: "read", "write", "create", "delete",
+and "admin".
+
+The full set of self explanatory bboard privileges is listed here:
+
+
bboard_create_forum
+
bboard_create_category
+
bboard_create_message
+
bboard_write_forum
+
bboard_write_category
+
bboard_write_message
+
bboard_read_forum
+
bboard_read_category
+
bboard_read_message
+
bboard_delete_forum
+
bboard_delete_category
+
bboard_delete_message
+
bboard_moderate_forum
+
+
+
+Permissions on package instances are controlled through the "set
+permissions" options on the appropriate folder in the admin site map
+(/admin/site-map/). While in principal, the system should allow you
+to grant permissions on lower level objects like forums or even
+individual messages and categories, right now the UI is limited to
+granting permissions on the application instance. SQL*Plus users or
+even URL hackers can probably figure out how to do this if they're so
+inclined.
+
+The default set of permissions granted in a bboard system are those
+inherited from the main site:
+
+
+
Registered Users have bboard_create_message
+
The Public has bboard_read_category
+
The Public has bboard_read_forum
+
The Public has bboard_read_message
+
The Public has read
+
[Admin user] admin
+
+
+Granting additional privileges to parties is fairly straightforward.
+For moderated forums, creating a moderators group and granting them
+"bboard_moderate_forum" (or "admin" if you're feeling lucky) will let
+you delegate more of the discussion culling.
+
+For significantly different configurations you might need to revoke
+privileges already granted by the defaults. In this case you must
+configure the package instance not to inherit permissions from the
+main site and then add back any permissions needed. Granting "read"
+to registered users and bboard_create_message to "Elite d00ds" will
+give you a pseudo-private forum.
+
+Note: To facilitate usability in the common case, BBoard pages present
+the option to post or reply even if the user doesn't have the
+bboard_create_message privilege. If you remove posting ability from
+registered users, you may wish to alter the templates to appropriately
+display options.
+
+
Miscellaneous Notes
+
+Text searching requires the maintaince of the content repository
+cr_rev_content_index index; either by hand or by
+context.
+
+As usual, please file bugs and feature requests in the bboard
+SDM.
+
+
This document outlines necessary functionality and behavior of
+ the new ACS 4.0 Bulletin Board system (herein referred to as bboard).
+
+
Our intent (as of 8/2000) is to start with a simple
+ implementation that can accomodate future advanced functionality.
+ As a result, these requirements may not prescribe functionality
+ present in the ACS 3.4 bboard system. We are using the
+ uslaw-bboard module as inspiration for a lightweight
+ implementation.
+
+
Futhermore, this document is conservative in attempting to
+ describe the ultimate framework for modular web based messaging.
+ We hope such an architecture may well be born out of iterative
+ process when designing this system. However, the scope is being
+ primarily limited to functional requirements.
+
+
The future requirements (section VII) should inform the design
+ process if not initially implemented.
+
+
II. Vision Statement
+
+
An electronic bulletin board system is one of the simplest and
+ most effective forms of collaboration between people separated in
+ space and time. Bboards provide a centralized and shared venue
+ for discussion that save communication costs over ad-hoc
+ mechanisms (like arbitrary email lists). Since messages are
+ organized by topic as well as temporally, bboard can provide
+ lightweight interfaces for rapidly navigating to interesting
+ messages. This low barrier to participation encourages
+ spontaneous collaboration between disperse parties in the
+ community.
+
+
The bboard system also serves as a useful archive and ad-hoc
+ knowledge management tool by virtue of its persistence, light
+ weight organizational structure, and flexible browse and search
+ facilities. This sort of knowledge base can be easily leveraged
+ to provide long term pedagogical value as well as aid in future
+ problem solving.
+
+
When integrated with an email system, bboards radically improve
+ email based collaboration. Email notifications can encourage
+ continuous awareness of community issues. Email based reply
+ functionality further lowers the barrier to participation,
+ encouraging more Interaction around the TransactionTM.
+
+
III. System/Application Overview
+
+
The bboard system allows users to browse, read, and
+ post messages organized into forums. Messages consist of short
+ text messages with optional attachments such as image files or
+ html documents. Messages are organized into threads when users
+ reply to each other, maintaining the temporal flow of a particular
+ discussion.
+
+
Forums are contexts for discussion relating to a particular
+ domain of interest. Examples include the photo.net Q&A forum, the
+ ArsDigita Web/DB forum, and the away.com discussion forum.
+ Messages within a particular forum can optionally be tagged as
+ being in certain categories to assist searching and navigation.
+ Forums are always created in the context of a subsite.
+
+
IV. Use-cases and User Scenarios
+
+
Administrator: Phillis Goodsport is a world famous
+ lithographer who wants to share her knowledge about lithography
+ and encourage interaction between a community of lithographers on
+ her new site litho.net. Although she likes the idea of a broad
+ forum for general lithography discussion, she wants browsing to be
+ tractable when traffic increases. If quality goes down, she'd
+ like to dedicate one of her minions to moderating traffic to
+ maintain her high standards.
+
+
Casual browser and poster: Joe Schmoe goes to photo.net
+ for the first time and wants to ask what zoom lens to buy. He
+ needs to find the appropriate category/topic to post his message.
+
+
Compulsive reader and expert poster: Jane Developer is a
+ web development guru and wants to keep up with as much of the
+ traffic on the web/db forum as possible. She wants to become
+ aware of posts that might become relevant to her in the future
+ as well as help out folks who have problems she knows how to
+ solve. Since Jane is on lots of developer mailing lists, her
+ preferred form of interaction is via email.
+
+
Moderator: Dave Balderdash is a chatter.net moderator and
+ wants to delete redundant or useless posts. He's short
+ on time, so he wants a quick interface for rejecting and approving
+ posts.
+
+
Targeted researcher: Ted Stetson is an ACS developer who
+ remembers someone mentioning something about his Oracle problem on
+ a bboard. He wants to find records of similar problems and any
+ related solutions.
+
+
10.10.10 The bboard system must provide
+ mechanism for users to effectively choose which messages to read
+ within a forum. Bboard must provide an overview interface to
+ enable users to find messages of interest or relevant to them.
+ This overview should provide the user with cursory information to
+ facilitate quick scanning and meaningful evaluation of message
+ contents.
+
+
10.10.15 The full text of bboard messages
+ should be searchable by user queries.
+
+
10.10.20 [unimplemented] Bboard should consistently provide
+ a mechanism to limit or sort displayed posts by categories, posters,
+ and date range as well as to perform a text search.
+
+
10.10.30 [unimplemented] Most users primarily want
+ to browse and read new posts or replies since their last visit.
+ The bboard interface must allow users to ignore messages they've
+ already read.
+
+
10.10.40 [unimplemented] Users should be able to search within
+ and limit scope to messages they have already read as well as
+ messages they have not read at all.
+
+
10.10.50 Users must be able to easily post new
+ messages to a bboard, or reply to existing messages they have come
+ across. When replying, users must be presenting with enough
+ context to assist their composition.
+
+
Email Integration
+
+
10.20.10 Users can register for email
+ notification of new messages in a particular forums.
+
+
10.20.13 Users can register for email
+ notifications on a particular thread.
+
+
10.20.16 Users can register for email
+ notifications on a particular category.
+
+
10.20.20 [unimplemented] Notifications can be sent as each
+ message arrives or in an organized digest form over a configurable
+ time period.
+
+
10.20.30 Individual messages will have appropriate RFC 822
+ headers to enable threading in the mail client.
+
+
10.20.40 [unimplemented]
+ Email from the alert system should be tagged in the
+ header with the site and forum name to enable easy filtering in
+ mail clients. Well, as easy as the mail clients make it anyway.
+
+
10.20.50 [unimplemented]
+ If the user requests it, email generated should use MIME
+ encoding to deliver attachements and appropriately encode HTML.
+ Otherwise plain text emails should be augmented with URLs and
+ styling cues in place of rich content.
+
+
Administrative Requirements
+
+
10.30.10 The bboard system must support a
+ flexible presentation layer that allows custom layout of bboard
+ content.
+
+
10.30.15 Publishers should have the option of
+ displaying discussions in a flat linear fashion or in an indented
+ threaded view.
+
+
10.30.20 Parties with administrative
+ privileges on a particular subsite can create, delete, and edit
+ forums scoped to that subsite.
+
+
10.30.30 Forums can be designated moderated in
+ which case parties with sufficient privileges must approve
+ messages before they are displayed generally.
+
+
Access Control Requirements
+
+ Objects must be structured to allow the flexible configuration and
+ assignment of the following privileges:
+
+
10.40.60 Managing the forum (editing title and
+ description, determining moderation and restriction policies,
+ granting approval privileges to others, banning users)
+
+
10.80.10 Messages are the basic units of the
+ bboard module. The bboard system will provide a repository to
+ store text messages.
+
+
10.80.20 Messages will be tagged as having
+ HTML, plain text, or preformatted text in their body.
+
+
10.80.30 Messages will have a brief plain text
+ subject line.
+
+
10.80.40 Messages will be related to their
+ creating user.
+
+
10.80.50 Messages may optionally have
+ binary attachments.
+
+
10.80.60 The bboard system must store relations
+ between messages and their replies to enable threaded views.
+
+
Forums
+
+
10.90.10 Forums are the main administrative
+ units of the bboard system. Forums are containers to which
+ messages uniquely belong.
+
+
10.90.20 Forums must have a brief text
+ descriptions and optionally a longer description called a charter.
+
+
Categories
+
+
10.100.10 There must be a mechanism for
+ intra-forum categorization to facilitate filter, searching, and
+ tractability.
+
+
VI.C Requirements: API
+
+ No requirements in this section are met by the
+ current implementation.
+
+
Since bboard is primarily an end user application any exposed
+ APIs will come out of the design rather than nailed down
+ requirements from the start. Stay tuned.
+
+
VI.D Possible Future Requirements
+
+
10.255.10 bboard should provide a framework
+ for extending the generic messaging repository with meta-data
+ and in tandem extending the user interface to take advantage of
+ this meta-data. This would let developers properly layer
+ functionality such as geo-spatial messaging and slashdot style
+ scoring. This is actually provided via ACS messaging and the ACS
+ Object system.
+
+
10.255.20 bboard should support replying to
+ and initiating threads from email. Administrative email list
+ functionality should be developed or integrated.
+
+
10.255.30 Bboard should let users register
+ interests (categories, certain users, keywords) for the purpose of
+ filtering and sorting message displays.
+
+
10.255.40 Users should have the option of
+ enabling spell checking on their posts. A framework for filtering
+ (removing bad words, promoting text URLs to html links, auto
+ detecting HTML vs. plain text, etc.,) should exist.
+
+
10.255.50 Allow users to configure how big the
+ textareas editing widgets they get are.
+
+
10.255.60 Moderators should be given the
+ option of making notes on a given discussion that appear
+ prominently in the discussion display.
+
+
10.255.70 Moderators should be able to set
+ posts to expire at a configurable time in the future.
+
+
10.255.80 Mega bonus points: an nntp gateway to
+ bboards for access from standard news clients.
+
+
10.255.90 The bboard system should be able to
+ take advantage of a caching system that stores the results of
+ database queries for optimal scalability.
+
+
10.255.100 Publishers should have the option
+ of allowing users to edit various parts of messages after they are
+ posted (e.g. the text body, the subject, the text presentaiton
+ style etc.,)
+
+
10.255.110 A user interface should allow
+ administrators to easily categorize or recategorize existing
+ messages.
+
+
10.255.120 Publishers should be able to
+ classify users based on their forum contributions and
+ appropriately target them for email, promotions, etc.,
+
+
10.255.130 Explicit permissions for posting
+ new messages vs. posting replies.
+
+
10.255.140 Explicit permissions for posting
+ attachments.
+
+
Performance requirements
+
+
VII. Revision History
+
+
+
+
Document Revision #
+
Action Taken, Notes
+
When?
+
By Whom?
+
+
+
+
0.1
+
Creation
+
08/23/2000
+
Anukul Kapoor
+
+
+
+
0.2
+
Revision: More standard style, more detailed requirements.
+
08/24/2000
+
Anukul Kapoor
+
+
+
+
+
+
+
+Last modified: $Id: requirements.html,v 1.1 2001/04/20 20:51:09 donb Exp $
+
+
Index: openacs-4/contrib/obsolete-packages/mp3jukebox/mp3jukebox.info
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/mp3jukebox/Attic/mp3jukebox.info,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/contrib/obsolete-packages/mp3jukebox/mp3jukebox.info 20 Apr 2001 20:51:11 -0000 1.1
@@ -0,0 +1,92 @@
+
+
+
+
+ MP3 JukeBox
+ MP3 Jukeboxes
+ f
+
+
+
+ oracle
+ postgresql
+
+ Peter Vessenes
+ An MP3 Jukebox for Locally stored MP3 files.
+ 2001-03-20
+ Ybos Corporation
+ An MP3 Jukebox for Locally stored MP3 files. It doesn't stream.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: openacs-4/contrib/obsolete-packages/mp3jukebox/bin/mp3_file_scan
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/mp3jukebox/bin/Attic/mp3_file_scan,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/contrib/obsolete-packages/mp3jukebox/bin/mp3_file_scan 20 Apr 2001 20:51:11 -0000 1.1
@@ -0,0 +1,22 @@
+#!/usr/bin/perl
+
+use MPEG::MP3Info;
+
+my $file = shift;
+
+my $tag = get_mp3tag($file);
+
+my $info = get_mp3info($file);
+
+
+
+for (keys %$tag) {
+ printf " { %s {%s} } ", $_, $tag->{$_};
+}
+
+for (keys %$info) {
+ printf " { %s {%s} } ", $_, $info->{$_};
+}
+
+
+
Index: openacs-4/contrib/obsolete-packages/mp3jukebox/bin/mp3_info_determine
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/mp3jukebox/bin/Attic/mp3_info_determine,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/contrib/obsolete-packages/mp3jukebox/bin/mp3_info_determine 20 Apr 2001 20:51:11 -0000 1.1
@@ -0,0 +1,35 @@
+#!/usr/bin/perl
+
+use MPEG::MP3Info;
+
+$scanned = 0;
+$total = 0;
+while () {
+
+ $total++;
+ chop;
+ my $file = $_;
+
+ my $tag = get_mp3tag($file) or next;
+
+
+ my $info = get_mp3info($file);
+
+ print "--Start Track--\n";
+
+ for (keys %$tag) {
+ printf "%s => %s\n", $_, $tag->{$_};
+ }
+
+ for (keys %$info) {
+ printf "%s => %s\n", $_, $info->{$_};
+}
+
+ print "--End Track--\n";
+ undef $tag;
+ undef $info;
+
+ $scanned++;
+}
+
+print "\n-----\nTotal Songs: $total\nScanned Songs: $scanned\n-----\n";
Index: openacs-4/contrib/obsolete-packages/mp3jukebox/sql/oracle/mp3jukebox-create.sql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/mp3jukebox/sql/oracle/Attic/mp3jukebox-create.sql,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/contrib/obsolete-packages/mp3jukebox/sql/oracle/mp3jukebox-create.sql 20 Apr 2001 20:51:11 -0000 1.1
@@ -0,0 +1,545 @@
+-- @author tigre@ybos.net
+-- @author jennie@ybos.net
+
+begin
+ acs_object_type.create_type (
+ supertype => 'acs_object',
+ object_type => 'mp3',
+ pretty_name => 'MP3',
+ pretty_plural => 'MP3s',
+ table_name => 'MP3_MP3S',
+ id_column => 'MP3_ID'
+ );
+
+ acs_object_type.create_type (
+ supertype => 'acs_object',
+ object_type => 'mp3_playlist',
+ pretty_name => 'Playlist',
+ pretty_plural => 'Playlists',
+ table_name => 'MP3_PLAYLISTS',
+ id_column => 'PLAYLIST_ID'
+ );
+end;
+/
+
+create table mp3_mp3s (
+ mp3_id constraint mp3_mp3_id_fk
+ references acs_objects (object_id)
+ constraint mp3_mp3s_pk
+ primary key,
+ file_path varchar(200)
+ constraint mp3_mp3s_nn
+ not null
+ constraint mp3_mp3s_file_unique
+ unique,
+ title varchar(200)
+ constraint mp3_mp3s_title_nn
+ not null,
+ artist varchar(100),
+ bitrate varchar(50),
+ album varchar(200),
+ tracknum integer,
+ genre varchar(100),
+ year varchar(10),
+ layer integer,
+ copyright_p char(1) default 'f'
+ constraint mp3_mp3s_copyright_p_ck
+ check(copyright_p in ('t','f')),
+ version integer,
+ mode_num integer,
+ stereo_p char(1) default 'f'
+ constraint mp3_mp3s_stereo_p_ck
+ check(stereo_p in ('t','f')),
+ frequency number,
+ minutes integer,
+ seconds integer,
+ comments varchar(200),
+ vbr_p char(1) default 'f'
+ constraint mp3_mp3s_vbr_p_ck
+ check(vbr_p in ('t','f')),
+ state varchar(50),
+ deleted_p char(1) default 'f'
+ constraint mp3_mp3s_deleted_p_ck
+ check(deleted_p in ('t','f'))
+);
+
+create table mp3_playlists (
+ playlist_id constraint mp3_playlist_id_fk
+ references acs_objects (object_id)
+ constraint mp3_playlists_pk
+ primary key,
+ name varchar(100),
+ shuffle_p char(1) default 'f'
+ constraint mp3_playlists_shuffle_p_ck
+ check(shuffle_p in ('f','t')),
+ remove_threshold integer
+);
+
+create table mp3_mp3_playlist_map (
+ mp3_id constraint mp3_map_mp3_id_fk
+ references mp3_mp3s (mp3_id),
+ playlist_id constraint mp3_map_playlist_id_fk
+ references mp3_playlists (playlist_id),
+ sort_key integer,
+ -- This pk constraint will have ot be changed, maybe add a column
+ -- for the pk, thus allowing multiple instances of a given song
+ -- on a playlist
+ constraint mp3_map_pk
+ primary key (mp3_id,playlist_id)
+);
+
+create table mp3_mp3_stats (
+ mp3_id constraint mp3_mp3_stats_mp3_id_fk
+ references mp3_mp3s (mp3_id),
+ user_id constraint mp3_mp3_stats_user_id_fk
+ references users(user_id),
+ access_date date
+ constraint mp3_mp3_stats_access_date_nn
+ not null
+);
+
+create table mp3_playlist_stats (
+ playlist_id constraint mp3_playlist_stats_playlist_fk
+ references mp3_playlists (playlist_id),
+ user_id constraint mp3_playlists_stats_user_id_fk
+ references users(user_id),
+ access_date date
+ constraint mp3_playlist_stats_date_nn
+ not null
+);
+
+create table mp3_votes (
+ mp3_id constraint mp3_votes_mp3_id_fk
+ references mp3_mp3s (mp3_id),
+ playlist_id constraint mp3_votes_playlist_id_fk
+ references mp3_playlists (playlist_id),
+ user_id constraint mp3_votes_user_id_fk
+ references users(user_id),
+ vote integer
+ constraint mp3_votes_vote_nn
+ not null,
+ vote_date date
+);
+
+create or replace view mp3_mp3_playlist_map_view as
+ select m.mp3_id,
+ m.playlist_id,
+ m.sort_key,
+ nvl(v.total,0) as total
+ from mp3_mp3_playlist_map m,
+ (select mp3_id,
+ playlist_id,
+ sum(vote) as total
+ from mp3_votes
+ group by mp3_id, playlist_id) v
+ where m.mp3_id = v.mp3_id (+)
+ and m.playlist_id = v.playlist_id (+);
+
+create or replace view mp3_mp3s_not_deleted as
+ select *
+ from mp3_mp3s
+ where deleted_p = 'f';
+
+create or replace view mp3_playlist_song_count as
+ select mpv.playlist_id, count(*) as songs
+ from mp3_mp3_playlist_map_view mpv,
+ mp3_mp3s_not_deleted mnd,
+ mp3_playlists mp
+ where mpv.mp3_id = mnd.mp3_id
+ and mpv.playlist_id = mp.playlist_id
+ and mpv.total > mp.remove_threshold
+ group by mpv.playlist_id;
+
+create or replace package mp3
+as
+ function new (
+ mp3_id in mp3_mp3s.mp3_id%TYPE default null,
+ file_path in mp3_mp3s.file_path%TYPE,
+ title in mp3_mp3s.title%TYPE,
+ artist in mp3_mp3s.artist%TYPE default null,
+ bitrate in mp3_mp3s.bitrate%TYPE default null,
+ album in mp3_mp3s.album%TYPE default null,
+ tracknum in mp3_mp3s.tracknum%TYPE default null,
+ genre in mp3_mp3s.genre%TYPE default null,
+ year in mp3_mp3s.year%TYPE default null,
+ layer in mp3_mp3s.layer%TYPE default null,
+ copyright_p in mp3_mp3s.copyright_p%TYPE default null,
+ version in mp3_mp3s.version%TYPE default null,
+ mode_num in mp3_mp3s.mode_num%TYPE default null,
+ stereo_p in mp3_mp3s.stereo_p%TYPE default null,
+ frequency in mp3_mp3s.frequency%TYPE default null,
+ minutes in mp3_mp3s.minutes%TYPE default null,
+ seconds in mp3_mp3s.seconds%TYPE default null,
+ comments in mp3_mp3s.comments%TYPE default null,
+ vbr_p in mp3_mp3s.vbr_p%TYPE default null,
+ state in mp3_mp3s.state%TYPE default null,
+ deleted_p in mp3_mp3s.deleted_p%TYPE default 'f',
+ object_type in acs_objects.object_type%TYPE default 'mp3',
+ creation_date in acs_objects.creation_date%TYPE default sysdate,
+ creation_user in acs_objects.creation_user%TYPE default null,
+ creation_ip in acs_objects.creation_ip%TYPE default null,
+ context_id in acs_objects.context_id%TYPE default null
+ ) return acs_objects.object_id%TYPE;
+
+ procedure delete (
+ mp3_id in mp3_mp3s.mp3_id%TYPE
+ );
+
+ procedure mark_as_deleted (
+ mp3_id in mp3_mp3s.mp3_id%TYPE
+ );
+
+end mp3;
+/
+show errors
+
+create or replace package body mp3
+as
+ function new (
+ mp3_id in mp3_mp3s.mp3_id%TYPE default null,
+ file_path in mp3_mp3s.file_path%TYPE,
+ title in mp3_mp3s.title%TYPE,
+ artist in mp3_mp3s.artist%TYPE default null,
+ bitrate in mp3_mp3s.bitrate%TYPE default null,
+ album in mp3_mp3s.album%TYPE default null,
+ tracknum in mp3_mp3s.tracknum%TYPE default null,
+ genre in mp3_mp3s.genre%TYPE default null,
+ year in mp3_mp3s.year%TYPE default null,
+ layer in mp3_mp3s.layer%TYPE default null,
+ copyright_p in mp3_mp3s.copyright_p%TYPE default null,
+ version in mp3_mp3s.version%TYPE default null,
+ mode_num in mp3_mp3s.mode_num%TYPE default null,
+ stereo_p in mp3_mp3s.stereo_p%TYPE default null,
+ frequency in mp3_mp3s.frequency%TYPE default null,
+ minutes in mp3_mp3s.minutes%TYPE default null,
+ seconds in mp3_mp3s.seconds%TYPE default null,
+ comments in mp3_mp3s.comments%TYPE default null,
+ vbr_p in mp3_mp3s.vbr_p%TYPE default null,
+ state in mp3_mp3s.state%TYPE default null,
+ deleted_p in mp3_mp3s.deleted_p%TYPE default 'f',
+ object_type in acs_objects.object_type%TYPE default 'mp3',
+ creation_date in acs_objects.creation_date%TYPE default sysdate,
+ creation_user in acs_objects.creation_user%TYPE default null,
+ creation_ip in acs_objects.creation_ip%TYPE default null,
+ context_id in acs_objects.context_id%TYPE default null
+ ) return acs_objects.object_id%TYPE
+ is
+ v_mp3_id mp3_mp3s.mp3_id%TYPE;
+ begin
+ v_mp3_id := acs_object.new (
+ object_id => mp3_id,
+ object_type => object_type,
+ creation_date => creation_date,
+ creation_user => creation_user,
+ creation_ip => creation_ip,
+ context_id => context_id
+ );
+ insert into mp3_mp3s
+ (mp3_id, file_path, title, artist, bitrate, album, tracknum, genre, year, layer,
+ copyright_p, version, mode_num, stereo_p, frequency, minutes, seconds, comments,
+ vbr_p, state, deleted_p)
+ values
+ (v_mp3_id, file_path, title, artist, bitrate, album, tracknum, genre,
+ year, layer, copyright_p, version, mode_num, stereo_p, frequency,
+ minutes, seconds, comments, vbr_p, state, deleted_p);
+
+ return v_mp3_id;
+ end new;
+
+
+
+ procedure delete (
+ mp3_id in mp3_mp3s.mp3_id%TYPE
+ )
+ is
+ begin
+ delete from mp3_mp3s where mp3_id = mp3.delete.mp3_id;
+ acs_object.delete(mp3_id);
+ end delete;
+
+
+
+ procedure mark_as_deleted (
+ mp3_id in mp3_mp3s.mp3_id%TYPE
+ )
+ is
+ begin
+
+ update mp3_mp3s
+ set deleted_p ='t'
+ where mp3_id = mp3.mark_as_deleted.mp3_id;
+
+ end mark_as_deleted;
+
+end mp3;
+/
+show errors
+
+
+create or replace package mp3_playlist
+as
+
+ function new (
+ playlist_id in mp3_playlists.playlist_id%TYPE default null,
+ name in mp3_playlists.name%TYPE default null,
+ shuffle_p in mp3_playlists.shuffle_p%TYPE default 'f',
+ remove_threshold in mp3_playlists.remove_threshold%TYPE default null,
+ object_type in acs_objects.object_type%TYPE default 'mp3_playlist',
+ creation_date in acs_objects.creation_date%TYPE default sysdate,
+ creation_user in acs_objects.creation_user%TYPE default null,
+ creation_ip in acs_objects.creation_ip%TYPE default null,
+ context_id in acs_objects.context_id%TYPE
+ ) return acs_objects.object_id%TYPE;
+
+ procedure delete (
+ playlist_id in mp3_playlists.playlist_id%TYPE
+ );
+
+ procedure item_add (
+ mp3_id in mp3_mp3s.mp3_id%TYPE,
+ playlist_id in mp3_playlists.playlist_id%TYPE,
+ sort_key in mp3_mp3_playlist_map.sort_key%TYPE default null
+ );
+
+ procedure item_remove (
+ mp3_id in mp3_mp3s.mp3_id%TYPE,
+ playlist_id in mp3_playlists.playlist_id%TYPE
+ );
+
+ function vote_cast (
+ user_id in users.user_id%TYPE,
+ playlist_id in mp3_playlists.playlist_id%TYPE,
+ mp3_id in mp3_mp3s.mp3_id%TYPE,
+ vote in mp3_votes.vote%TYPE,
+ vote_date in mp3_votes.vote_date%TYPE default sysdate
+ ) return mp3_mp3_playlist_map_view.total%TYPE;
+
+ procedure item_order_swap (
+ playlist_id in mp3_playlists.playlist_id%TYPE,
+ sort_key in mp3_mp3_playlist_map.sort_key%TYPE
+ );
+
+end mp3_playlist;
+/
+show errors
+
+
+
+create or replace package body mp3_playlist
+as
+ function new (
+ playlist_id in mp3_playlists.playlist_id%TYPE default null,
+ name in mp3_playlists.name%TYPE default null,
+ shuffle_p in mp3_playlists.shuffle_p%TYPE default 'f',
+ remove_threshold in mp3_playlists.remove_threshold%TYPE default null,
+ object_type in acs_objects.object_type%TYPE default 'mp3_playlist',
+ creation_date in acs_objects.creation_date%TYPE default sysdate,
+ creation_user in acs_objects.creation_user%TYPE default null,
+ creation_ip in acs_objects.creation_ip%TYPE default null,
+ context_id in acs_objects.context_id%TYPE
+ ) return acs_objects.object_id%TYPE
+ is
+ v_playlist_id mp3_playlists.playlist_id%TYPE;
+ begin
+ v_playlist_id := acs_object.new (
+ object_id => playlist_id,
+ object_type => object_type,
+ creation_date => creation_date,
+ creation_user => creation_user,
+ creation_ip => creation_ip,
+ context_id => context_id
+ );
+ insert into mp3_playlists
+ (playlist_id, name, shuffle_p, remove_threshold)
+ values
+ (v_playlist_id, name, shuffle_p, remove_threshold);
+ return v_playlist_id;
+ end new;
+
+ procedure delete (
+ playlist_id in mp3_playlists.playlist_id%TYPE
+ )
+ is
+ begin
+ delete from mp3_votes
+ where playlist_id = mp3_playlist.delete.playlist_id;
+ delete from mp3_mp3_playlist_map
+ where playlist_id = mp3_playlist.delete.playlist_id;
+ delete from mp3_playlists
+ where playlist_id = mp3_playlist.delete.playlist_id;
+ acs_object.delete(playlist_id);
+ end delete;
+
+ -- Note: item_add uses "insert after" ordering, so "order" points to
+ -- the last record _not_ to be updated
+ procedure item_add (
+ mp3_id in mp3_mp3s.mp3_id%TYPE,
+ playlist_id in mp3_playlists.playlist_id%TYPE,
+ sort_key in mp3_mp3_playlist_map.sort_key%TYPE default 0
+ )
+ is
+ cursor map_cur is
+ select mmpm.mp3_id, mmpm.playlist_id, mmpm.sort_key
+ from mp3_mp3_playlist_map mmpm, mp3_mp3s_not_deleted mmnd
+ where mmpm.mp3_id = mmnd.mp3_id
+ and mmpm.playlist_id = mp3_playlist.item_add.playlist_id
+ and mmpm.sort_key > mp3_playlist.item_add.sort_key
+ order by mmpm.sort_key;
+ l_sort_key mp3_mp3_playlist_map.sort_key%TYPE;
+ l_max_sort_key mp3_mp3_playlist_map.sort_key%TYPE;
+ l_new_sort_key mp3_mp3_playlist_map.sort_key%TYPE;
+ begin
+ select nvl(max(sort_key),0) into l_max_sort_key
+ from mp3_mp3_playlist_map
+ where playlist_id = mp3_playlist.item_add.playlist_id;
+ if sort_key > l_max_sort_key
+ then
+ l_sort_key := l_max_sort_key;
+ else
+ l_sort_key := sort_key;
+ end if;
+ l_new_sort_key := l_sort_key + 2;
+ for map_rec in map_cur
+ loop
+ update mp3_mp3_playlist_map
+ set sort_key = l_new_sort_key
+ where mp3_id = map_rec.mp3_id
+ and playlist_id = map_rec.playlist_id;
+ l_new_sort_key := l_new_sort_key + 1;
+ end loop;
+ insert into mp3_mp3_playlist_map
+ (mp3_id, playlist_id, sort_key)
+ values
+ (mp3_id, playlist_id, l_sort_key + 1);
+ end item_add;
+
+ -- We'll just delete the mapping and it's corresponding votes
+ -- We won't worry about gaps in the order
+ procedure item_remove (
+ mp3_id in mp3_mp3s.mp3_id%TYPE,
+ playlist_id in mp3_playlists.playlist_id%TYPE
+ )
+ is
+ begin
+ delete from mp3_votes
+ where mp3_id = mp3_playlist.item_remove.mp3_id
+ and playlist_id = mp3_playlist.item_remove.playlist_id;
+ delete from mp3_mp3_playlist_map
+ where mp3_id = mp3_playlist.item_remove.mp3_id
+ and playlist_id = mp3_playlist.item_remove.playlist_id;
+ end item_remove;
+
+ function vote_cast (
+ user_id in users.user_id%TYPE,
+ playlist_id in mp3_playlists.playlist_id%TYPE,
+ mp3_id in mp3_mp3s.mp3_id%TYPE,
+ vote in mp3_votes.vote%TYPE,
+ vote_date in mp3_votes.vote_date%TYPE default sysdate
+ ) return mp3_mp3_playlist_map_view.total%TYPE
+ is
+ l_vote_sum mp3_votes.vote%TYPE;
+ begin
+ insert into mp3_votes
+ (mp3_id, playlist_id, user_id, vote, vote_date)
+ values
+ (mp3_id, playlist_id, user_id, vote, vote_date);
+ select total into l_vote_sum
+ from mp3_mp3_playlist_map_view
+ where mp3_id = mp3_playlist.vote_cast.mp3_id
+ and playlist_id = mp3_playlist.vote_cast.playlist_id;
+ return l_vote_sum;
+ end vote_cast;
+
+ -- "swap w/ next"
+ procedure item_order_swap (
+ playlist_id in mp3_playlists.playlist_id%TYPE,
+ sort_key in mp3_mp3_playlist_map.sort_key%TYPE
+ )
+ is
+ l_next_order mp3_mp3_playlist_map.sort_key%TYPE;
+ begin
+ select min(sort_key) into l_next_order
+ from mp3_mp3_playlist_map m, mp3_mp3s_not_deleted d
+ where m.mp3_id = d.mp3_id
+ and m.sort_key > mp3_playlist.item_order_swap.sort_key;
+
+ update mp3_mp3_playlist_map mmpm
+ set sort_key = decode(mmpm.sort_key,
+ mp3_playlist.item_order_swap.sort_key,
+ mp3_playlist.item_order_swap.sort_key + 1,
+ mp3_playlist.item_order_swap.sort_key)
+ where sort_key in (mp3_playlist.item_order_swap.sort_key,
+ l_next_order);
+ end item_order_swap;
+
+end mp3_playlist;
+/
+show errors
+
+
+-- permissions don't quite work with the file system we've set up; most
+-- would be useful under /admin, where the admin permission is required.
+
+--declare
+-- default_context acs_objects.object_id%TYPE;
+-- registered_users acs_objects.object_id%TYPE;
+-- the_public acs_objects.object_id%TYPE;
+
+--begin
+-- acs_privilege.create_privilege('mp3_view_mp3');
+-- acs_privilege.create_privilege('mp3_create_mp3');
+-- acs_privilege.create_privilege('mp3_delete_mp3');
+-- acs_privilege.create_privilege('mp3_modify_mp3');
+-- acs_privilege.create_privilege('mp3_view_playlist');
+-- acs_privilege.create_privilege('mp3_create_playlist');
+-- acs_privilege.create_privilege('mp3_delete_playlist');
+-- acs_privilege.create_privilege('mp3_modify_playlist');
+-- acs_privilege.create_privilege('mp3_admin_mp3');
+-- acs_privilege.create_privilege('mp3_admin_playlist');
+-- acs_privilege.create_privilege('mp3_admin');
+-- acs_privilege.add_child('mp3_admin_mp3', 'mp3_view_mp3');
+-- acs_privilege.add_child('mp3_admin_mp3', 'mp3_create_mp3');
+-- acs_privilege.add_child('mp3_admin_mp3', 'mp3_delete_mp3');
+-- acs_privilege.add_child('mp3_admin_mp3', 'mp3_modify_mp3');
+-- acs_privilege.add_child('mp3_admin_playlist', 'mp3_view_playlist');
+-- acs_privilege.add_child('mp3_admin_playlist', 'mp3_create_playlist');
+-- acs_privilege.add_child('mp3_admin_playlist', 'mp3_delete_playlist');
+-- acs_privilege.add_child('mp3_admin_playlist', 'mp3_modify_playlist');
+-- acs_privilege.add_child('mp3_admin', 'mp3_admin_playlist');
+-- acs_privilege.add_child('mp3_admin', 'mp3_admin_mp3');
+
+-- -- bind privileges to global names
+
+-- acs_privilege.add_child('create','mp3_create_mp3');
+-- acs_privilege.add_child('create','mp3_create_playlist');
+-- acs_privilege.add_child('write','mp3_modify_mp3');
+-- acs_privilege.add_child('write','mp3_modify_playlist');
+-- acs_privilege.add_child('read','mp3_view_mp3');
+-- acs_privilege.add_child('read','mp3_view_playlist');
+-- acs_privilege.add_child('delete','mp3_delete_mp3');
+-- acs_privilege.add_child('delete','mp3_delete_playlist');
+-- acs_privilege.add_child('admin','mp3_admin');
+
+-- default_context := acs.magic_object_id('default_context');
+-- registered_users := acs.magic_object_id('registered_users');
+-- the_public := acs.magic_object_id('the_public');
+
+-- -- give the public the power to view playlists by default
+
+-- acs_permission.grant_permission (
+-- object_id => acs.magic_object_id('default_context'),
+-- grantee_id => acs.magic_object_id('the_public'),
+-- privilege => 'mp3_view_playlist'
+-- );
+
+
+-- -- give the public the power to view mp3s by default
+
+-- acs_permission.grant_permission (
+-- object_id => acs.magic_object_id('default_context'),
+-- grantee_id => acs.magic_object_id('the_public'),
+-- privilege => 'mp3_view_mp3'
+-- );
+
+-- end;
+-- /
Index: openacs-4/contrib/obsolete-packages/mp3jukebox/sql/oracle/mp3jukebox-drop.sql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/mp3jukebox/sql/oracle/Attic/mp3jukebox-drop.sql,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/contrib/obsolete-packages/mp3jukebox/sql/oracle/mp3jukebox-drop.sql 20 Apr 2001 20:51:11 -0000 1.1
@@ -0,0 +1,67 @@
+-- @author jennie@ybos.net
+-- @author wirth@ybos.net
+
+-- dropping permissions
+delete from acs_permissions
+ where privilege in
+ ('mp3_view_mp3','mp3_create_mp3','mp3_delete_mp3','mp3_modify_mp3',
+ 'mp3_view_playlist','mp3_create_playlist','mp3_delete_playlist',
+ 'mp3_modify_playlist','mp3_admin_mp3','mp3_admin_playlist',
+ 'mp3_admin');
+
+delete from acs_privilege_hierarchy
+ where privilege in
+ ('mp3_view_mp3','mp3_create_mp3','mp3_delete_mp3','mp3_modify_mp3',
+ 'mp3_view_playlist','mp3_create_playlist','mp3_delete_playlist',
+ 'mp3_modify_playlist','mp3_admin_mp3','mp3_admin_playlist',
+ 'mp3_admin');
+
+delete from acs_privilege_hierarchy
+ where child_privilege in
+ ('mp3_view_mp3','mp3_create_mp3','mp3_delete_mp3','mp3_modify_mp3',
+ 'mp3_view_playlist','mp3_create_playlist','mp3_delete_playlist',
+ 'mp3_modify_playlist','mp3_admin_mp3','mp3_admin_playlist',
+ 'mp3_admin');
+
+delete from acs_privileges
+ where privilege in
+ ('mp3_view_mp3','mp3_create_mp3','mp3_delete_mp3','mp3_modify_mp3',
+ 'mp3_view_playlist','mp3_create_playlist','mp3_delete_playlist',
+ 'mp3_modify_playlist','mp3_admin_mp3','mp3_admin_playlist',
+ 'mp3_admin');
+
+
+declare
+ cursor play_cur is
+ select playlist_id from mp3_playlists;
+ cursor mp3_cur is
+ select mp3_id from mp3_mp3s;
+begin
+ for play_rec in play_cur loop
+ mp3_playlist.delete(play_rec.playlist_id);
+ end loop;
+ for mp3_rec in mp3_cur loop
+ mp3.delete(mp3_rec.mp3_id);
+ end loop;
+end;
+/
+show errors
+
+drop package mp3_playlist;
+drop package mp3;
+drop view mp3_playlist_song_count;
+drop view mp3_mp3s_not_deleted;
+drop view mp3_mp3_playlist_map_view;
+drop table mp3_mp3_playlist_map;
+drop table mp3_mp3_stats;
+drop table mp3_playlist_stats;
+drop table mp3_votes;
+drop table mp3_playlists;
+drop table mp3_mp3s;
+
+begin
+ acs_object_type.drop_type ('mp3_playlist');
+ acs_object_type.drop_type ('mp3');
+end;
+/
+show errors
\ No newline at end of file
Index: openacs-4/contrib/obsolete-packages/mp3jukebox/tcl/mp3-procs.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/mp3jukebox/tcl/Attic/mp3-procs.tcl,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/contrib/obsolete-packages/mp3jukebox/tcl/mp3-procs.tcl 20 Apr 2001 20:51:11 -0000 1.1
@@ -0,0 +1,29 @@
+ad_library {
+
+ general procs for the MP3 Jukebox.
+
+ @author wirth@ybos.net
+ @creation-date Mar-12-2001
+ taken largely from cm-defs.tcl
+}
+
+
+ad_proc -public mp3_search_select_sql {
+ {
+ -order_by "upper(title)"
+ -conditions ""
+ }
+ search_string_name
+} {
+ Returns the sql to perform the file search based on the search string
+ stored in the named variable and any additional search criteria.
+ Additional conditions must be valid SQL with a leading 'and'
+} {
+ return "
+select title, artist, album, mp3_id
+from mp3_mp3s_not_deleted
+where upper(title) like '%' || upper(:$search_string_name) || '%'
+or upper(artist) like '%' || upper(:$search_string_name) || '%'
+$conditions
+order by $order_by"
+}
Index: openacs-4/contrib/obsolete-packages/mp3jukebox/tcl/scanner-procs.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/mp3jukebox/tcl/Attic/scanner-procs.tcl,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/contrib/obsolete-packages/mp3jukebox/tcl/scanner-procs.tcl 20 Apr 2001 20:51:11 -0000 1.1
@@ -0,0 +1,33 @@
+ad_library {
+
+ The Scanner procs for the MP3 Jukebox
+
+ @author peterv@ybos.net
+ @creation-date Mar-02-2001
+ @cvs-id $Id: scanner-procs.tcl,v 1.1 2001/04/20 20:51:11 donb Exp $
+}
+
+
+
+
+ad_proc -public get_list_of_mp3s {
+} {
+ This proc uses the package_id to check an appropriate directory.
+ It uses ad_parameter to check the MP3FileLocation variable.
+} {
+ set package_id [ad_conn package_id]
+ set file_list [exec /usr/bin/find [ad_parameter -package_id $package_id MP3StagingLocation] ]
+
+ return $file_list
+}
+
+ad_proc -public mp3_name_from_file { filename } {
+
+} {
+ if { [regexp {([^/]*)\.[mM][Pp]3$} $filename match mp3_name] } {
+ return $mp3_name
+ } else {
+ return "Not AN MP3 File Name!"
+ }
+}
+
Index: openacs-4/contrib/obsolete-packages/mp3jukebox/www/index.adp
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/mp3jukebox/www/Attic/index.adp,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/contrib/obsolete-packages/mp3jukebox/www/index.adp 20 Apr 2001 20:51:11 -0000 1.1
@@ -0,0 +1,27 @@
+
+@context_bar@
+@page_title@
+@title@
+
+
+You are about to delete the playlist @playlist_name@. Are you sure you want to proceed?
+
+
+Delete
+ | Back to Playlist
\ No newline at end of file
Index: openacs-4/contrib/obsolete-packages/mp3jukebox/www/admin/playlist-delete.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/mp3jukebox/www/admin/Attic/playlist-delete.tcl,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/contrib/obsolete-packages/mp3jukebox/www/admin/playlist-delete.tcl 20 Apr 2001 20:51:11 -0000 1.1
@@ -0,0 +1,32 @@
+# /packages/mp3jukebox/www/admin/playlist-delete.tcl
+
+ad_page_contract {
+
+ This page serves as a warning before deleting a playlist
+
+ @author wirth@ybos.net
+ @creation-date 2000-03-02
+
+} {
+ playlist_id:naturalnum,notnull
+
+} -properties {
+
+ page_title:onevalue
+ context_bar:onevalue
+ playlist_id:onevalue
+ playlist_name:onevalue
+}
+
+set title "Delete a Playlist"
+set context_bar [list $title]
+set page_title "Delete a Playlist"
+
+#requires admin permission as under /admin
+
+#set playlist_id here for double-click protection
+
+set playlist_name "[db_1row playlist_info "select name from mp3_playlists where playlist_id=:playlist_id" ]"
+
+
+ad_return_template
\ No newline at end of file
Index: openacs-4/contrib/obsolete-packages/mp3jukebox/www/admin/playlist-edit-2.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/mp3jukebox/www/admin/Attic/playlist-edit-2.tcl,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/contrib/obsolete-packages/mp3jukebox/www/admin/playlist-edit-2.tcl 20 Apr 2001 20:51:11 -0000 1.1
@@ -0,0 +1,66 @@
+# /packages/mp3jukebox/www/admin/playlist-edit-2.tcl
+
+ad_page_contract {
+
+ This page edits a playlist
+
+ @author wirth@ybos.net
+ @creation-date 2000-03-02
+
+} {
+
+ playlist_id:naturalnum,notnull
+ remove_threshold:integer,notnull
+ playlist_name
+
+} -properties {
+
+ page_title:onevalue
+ context_bar:onevalue
+ form_action:onevalue
+ hidden_vars:onevalue
+ name
+ remove_threshold:onevalue
+}
+
+set title "Edit a Playlist"
+set context_bar [list $title]
+set page_title "Edit a Playlist"
+
+#requires admin permission as under /admin
+
+set creation_ip [ad_conn "peeraddr"]
+set creation_user [ad_conn "user_id"]
+
+#remove_threshold expects a negative number for vote threshold, but the user
+#will expect to type in a positive number. So we change it to negative behind
+#the scenes for them. If they type in a negative number or zero, we input the number as is.
+
+if {$remove_threshold > 0} {
+ set neg_remove_threshold [expr $remove_threshold * -1]
+} else {
+ set neg_remove_threshold $remove_threshold
+}
+
+if [catch {
+ db_dml update_playlist "
+ update mp3_playlists set
+ name=:playlist_name,
+ remove_threshold=:neg_remove_threshold
+ where playlist_id=:playlist_id
+"
+} errmsg ] {
+
+ set complaint " The database did not accept your input.
+ See details for the error message below\n\n\t
+This document outlines the design and use of the Ybos MP3Jukebox application, built on the ACS 4.1 platform.
+
+
III. Historical Considerations
+
+We like MP3s. We work together. Also, once we were in a tiny little
+office, with only like 300 square feet, and we all worked at one big
+table. Really! One corner of the office looked like the picture on the
+right. This meant we could listen to the same stereo, (especially Abba)
+without serious problems.
+Now, we work in a large office, with multiple bays, and better lighting.
+We can't listen to the same songs all the time. People like me (Peter)
+get blasted out by the Abba, when it's loud enough for other people to hear.
+And, my enthusiasm for Abba is fading after a few years of Dancing Queen.
+
+Now, we can each, as groups, create shared playlists, and download them
+to stereos in our bays. This keeps us from being a group of people with
+headphones on that never talk, and it also makes me less annoyed with
+the office.
+
+
IV. Competitive Analysis
+Combine the cost of Oracle, a server, and a network topology that
+doesn't mind sending out MP3s without streaming, plus ACS installation,
+and you've got yourself at least 1,000 or so CDs plus 5 CD changers to
+hold them.
+
+On the other hand, you can't vote on the web with your CD changers.
+
+I'd call us neck and neck with the competition.
+
+
V. Design
+
+The system allows
+
+
Voting
+
Playlist Creation
+
Downloading
+
+It fits our rationality test for community applications -- you can annoy
+other people with it. (If you can't annoy someone, it's not a community
+application.)
+
+We don't
+
+
Stream
+
keep tight controls on the MP3 files (no BFILE columns)
+
+
+
VI. API
+Much of the API is covered in the mp3-create.sql file. The mp3 package body and the mp3_playlist package body holds all of the PL/SQL functions and procedures.
+
+
mp3.new: creates a mp3jukebox mp3 item
+
mp3.delete: deletes a mp3jukebox mp3 item
+
mp3.mark_as_deleted: marks a mp3jukebox mp3 item, without removing it from the file system
+
mp3_playlist.new: creates a mp3jukebox playlist item
+
mp3_playlist.delete: deletes a mp3jukebox playlist item
+
mp3_playlist.item_add: adds a mp3jukebox mp3 item to a playlist
+
mp3_playlist.item_remove: removes a mp3jukebox mp3 item from a playlist
+
mp3_playlist.vote_cast: adds a vote for or against an mp3jukebox mp3 item on a playlist
+
mp3_playlist.item_order_swap: swap the order of a mp3 on a playlist with one listed after it
+
mp3_search_select_sql: returns sql to perform file search according passed parameters
+
get_list_of_mp3s: returns the list of mp3 from the approriate mp3 file location
+
mp3_name_from_file: returns the mp3 name from the file name
+
+
+
+
+
VII. Data Model Discussion
+The MP3Jukebox package makes use of the ACS objects system. The creation of an mp3 item adds a row in the mp3_mp3s table as well as the acs_objects table, where the usual meta-information about this object is stored. This is also true for creation of a playlist item (that adds a row to the mp3_playlists table).
+
+Currently, only the playlists are distinguished according to the different mount instances of the mp3jukebox. This functionality is available for mp3s, however, was not utilized in this version of the application.
+
+
VIII. User Interface
+How to use it
+
+
Create a playlist
+
Add some MP3s to the playlist
+
Click the headphones
+
Enjoy!
+
+
+Clicking the headphones when they refer to a playlist will download
+an m3u file. Both xmms and winamp should be able to recognize this.
+You'll need to set up Netscape to deal with the .m3u files correctly;
+check out www.xmms.org for more information.
+
+
+
+Clicking the headphones when they refer to an MP3 will download the MP3
+directly from AOLServer. We don't, for instance, stream.
+
+
+The publicly accessible pages are in the root directory of the mounted instance. The administrative pages are under the root directory of the mounted instance (/root directory/admin). You must be granted admin on the node to have access to the admin pages.
+
+The public is allowed to view and download available playlists for each mount instance (playlists are mount-specific). The public is also allowed to vote for currently available mp3s on a playlist. Their votes only affect whether an mp3 is included when a playlist is played. Only administrators can remove an mp3 from a playlist. An mp3 is no longer included when a playlist is served, when the total of the votes submitted is less than or equal to the vote total (to remove an mp3), which is set by a site-wide administrator.
+
+Site-wide administrators may create and delete playlists, add and remove mp3s from playlists, choose the vote total, and add and mark_as_deleted mp3s.
+Please note that currently, administrators only mark an mp3 as deleted, i.e. an mp3 is not deleted from the mp3_mp3s table, the acs_objects table, or the file system. (The PL/SQL procedure for that is avavilable
+but just not used.)
+
+
+
IX. Configuration/Parameters
+This package was built on the ACS 4.1 platform.
+
+During installation of a package instance, an administrator needs to set up two parameters:
+
+
'MP3FileLocation,' the location of the MP3 Files on your server
+
'MP3StagingLocation', an open directory where MP3s will be placed before they are moved to the MP3FileLocation by the scanner.
+
+
+The general concept is that the MP3StagingLocation should be world writable.
+People will dump MP3s into that directory, via whatever means available.
+As the scanner is run, the files will be picked up, inserted into the
+database, and moved over to the MP3FileLocation.
+
+We use an ID3 scanner written in Perl to check the information in the
+MP3s. If none is returned, we just insert based on the title.
+
X. Acceptance Tests
+
+
+
XI. Future Improvements/Areas of Likely Change
+
+
More highly refined permissioning system
+
Playlist administrators and mp3 administrators?
+
feature allowing users to "suggest" an mp3, that maybe voted into a playlist
+
One user / one vote..
+
MP3s, like playlists, context-dependent (we're not sure on this one.)
+
+Currently, site-wide administrators are given full permission for any function in the mp3-jukebox package. Users may view, vote, and download available playlists of mp3s. Only site-wide administrators can manipulate playlists and mp3s.
+
+
Installation Guide
+After downloading this package and mounting it on the site-map, the administrator needs to do a few things before the package will work:
+
+
+
Create a staging directory for your MP3s. This directory should be world writeable. Users will place MP3s here to be scanned. We usually call it '/var/shared/mp3s'.
+
Create a final destination for your MP3s. Only nsadmin needs to be able to read / write here. This creates a semi-clean directory where the MP3s are kept, separate from the craziness of a world writeable directory. We usually place it in the servers hierarchy, but NOT in the package's directory. Currently, our final destination directory is '/web/servername/mp3_files'.
+
Edit the parameters for your application, and set 'MP3StagingLocation' to your staging directory's location.
+
Change MP3FileLocation to the final destination directory.
+
+This document outlines the requirements for the Ybos MP3 Jukebox application built on the ACS 4.1 platform.
+
+
II. Vision Statement
+MP3 Jukebox was written to allow a community to share common playlists of MP3s, with community members able to vote to keep or remove songs from playlists.
+
+
+
+
III. System/Application Overview
+
+
IV. Use-cases and User-scenarios
+The different classes of users are administrators and readers. Administrative power is currently based on site-wide administrative power. Typical user scenarios include:
+
+
Community members use the MP3 Jukebox to listen to a playlist or vote songs on or off of an existing playlist
+
Administrators create the playlists and add MP3s to playlists. Administrators also decide the threshold at which an MP3 is voted out of the playlist by the community.
+
+For example, an administrator decides that her office needs a "Cool Office Songs" playlist. She downloads MP3s into the MP3 staging location as defined by the "MP3StagingLocation" parameter. She then scans the staging directory for new MP3s, using the link on the admin/index page. She creates a new playlist and names it "Cool Office Songs," deciding that 10 net votes against a song will remove it from the playlist. She then searches for the MP3s she wishes to add to the playlist using the search function on the one-playlist page. After choosing each song, she decides what order that song will appear on the list. When she is done, she clicks "listen to playlist" and enjoys the tunes.
+A co-worker also enjoys the "Cool Office Songs" playlist but cannot stand "Dancing Queen" by ABBA, one of the songs on the playlist. He votes against the song and encourages 9 other officemates to do so. The song reaches its threshold at 10 net votes against, and no longer is included in the playlist.
+
+
V. Related Links
+
+
VI. Requirements
+
+
VI.1 Data Model
+
10.30. Privilege
+ 10.30.10 The only available privileges are admin and non-admin privileges, which currently correspond to site-wide privileges. A party can be granted "admin" permission on MP3 Jukebox.
+
+
10.40 Parameters
+ 10.40.10 Provide a parameter 'MP3FileLocation,' an abolute path
+which indicates the location of the MP3 Files on your server.
+ 10.40.20 Provide a 'MP3StagingLocation' parameter which indicates the
+Open Directory where MP3s will be placed before they are moved to the MP3FileLocation by the scanner.
+
+
+
VI.2 General User Interface
+
20.10 Provide a list of available playlists with a link to listen to the playlist if it contains MP3s
+ 20.20 Provide a one-item view of each playlist, including the current score of each MP3 within the playlist and links to vote for or against the song in the playlist.
+
+
VI.3 Registered User Interface
+
30.10 Same requirements as under 20.x.
+
+
VI.4 Administrator Interface
+
40.10 Same as under 20.x, except that voting si only available on the non-administration pages.
+ 40.20 Provide links to recently uploaded MP3s
+ 40.30 Provide links to add or delete MP3s or Playlists
+ 40.40 On one-playlist page, provide links to change the order of MP3s within a playlist or to forcibly remove an MP3 from a playlist (as opposed to voting for its removal).
+ 40.50 Provide a link to scan the staging location (see parameters) for new MP3s.
+
+
VI.5 Template Administration
+
+
VI.6 Additional Requirements
+
+
+
+
+
+
\ No newline at end of file
Index: openacs-4/contrib/obsolete-packages/mp3jukebox/www/doc/ybos-sad-2.jpg
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/mp3jukebox/www/doc/Attic/ybos-sad-2.jpg,v
diff -u -N
Binary files differ
Index: openacs-4/contrib/obsolete-packages/mp3jukebox/www/doc/ybos_office_80_60.jpg
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/mp3jukebox/www/doc/Attic/ybos_office_80_60.jpg,v
diff -u -N
Binary files differ
Index: openacs-4/contrib/obsolete-packages/mp3jukebox/www/images/delete.gif
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/mp3jukebox/www/images/Attic/delete.gif,v
diff -u -N
Binary files differ
Index: openacs-4/contrib/obsolete-packages/mp3jukebox/www/images/frowney_face.gif
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/mp3jukebox/www/images/Attic/frowney_face.gif,v
diff -u -N
Binary files differ
Index: openacs-4/contrib/obsolete-packages/mp3jukebox/www/images/headphones-16.gif
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/mp3jukebox/www/images/Attic/headphones-16.gif,v
diff -u -N
Binary files differ
Index: openacs-4/contrib/obsolete-packages/mp3jukebox/www/images/smiley_face.gif
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/mp3jukebox/www/images/Attic/smiley_face.gif,v
diff -u -N
Binary files differ
Index: openacs-4/contrib/obsolete-packages/mp3jukebox/www/m3u/index.vuh
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/mp3jukebox/www/m3u/Attic/index.vuh,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/contrib/obsolete-packages/mp3jukebox/www/m3u/index.vuh 20 Apr 2001 20:51:11 -0000 1.1
@@ -0,0 +1,24 @@
+# This file will process all m3u requests
+
+
+set path_info [ad_conn path_info]
+
+# assume we get playlistid/playlist_name.m3u as the path
+
+set playlist_id [lindex [split $path_info /] 0]
+
+db_1row playlist_threshold "select remove_threshold from mp3_playlists where playlist_id=:playlist_id"
+
+db_foreach mp3_list "select m.mp3_id, s.title, m.total from mp3_mp3_playlist_map_view m, mp3_mp3s_not_deleted s
+ where m.playlist_id = :playlist_id
+ and s.mp3_id = m.mp3_id
+ and m.total > :remove_threshold
+ order by m.sort_key
+
+ " {
+ append page_text "http://jk30.ybos.net/mp3/mp3s/$mp3_id/$title.mp3\n"
+ } if_no_rows {
+ set page_text ""
+ }
+
+ns_return 200 audio/x-mpegurl $page_text
Index: openacs-4/contrib/obsolete-packages/mp3jukebox/www/mp3s/index.vuh
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/mp3jukebox/www/mp3s/Attic/index.vuh,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/contrib/obsolete-packages/mp3jukebox/www/mp3s/index.vuh 20 Apr 2001 20:51:11 -0000 1.1
@@ -0,0 +1,14 @@
+# This file will process all mp3 requests
+
+set path_info [ad_conn path_info]
+
+# assume we get mp3id/mp3title.mp3 as the path
+
+set mp3_id [lindex [split $path_info /] 0]
+
+set file_path "[ad_parameter MP3FileLocation]/[db_string get_file_location "
+ select file_path from mp3_mp3s where mp3_id = :mp3_id
+"]"
+
+
+ns_returnfile 200 audio/mpeg $file_path
Index: openacs-4/contrib/obsolete-packages/photo-album-lite/photo-album-lite.info
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/photo-album-lite/photo-album-lite.info,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/contrib/obsolete-packages/photo-album-lite/photo-album-lite.info 20 Apr 2001 20:51:11 -0000 1.1
@@ -0,0 +1,97 @@
+
+
+
+
+ Photo Album Lite
+ Photo Album Lites
+ f
+
+
+
+ oracle
+ postgresql
+
+ Andrew Grumet
+ A full-featured, easy-to-use photo storage and display application.
+ 2001-02-21
+ ArsDigita Corporation
+ Photo Album Lite is a simple application for storing photo files. Users can upload multiple photos and ZIP archives at a time and organize them into folders. Proper configuration of ImageMagick and Intermedia are assumed. For more information, please install the package and point your browser to /doc/photo-album-lite.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: openacs-4/contrib/obsolete-packages/photo-album-lite/sql/oracle/cleanup-failed-drop.sql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/photo-album-lite/sql/oracle/cleanup-failed-drop.sql,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/contrib/obsolete-packages/photo-album-lite/sql/oracle/cleanup-failed-drop.sql 20 Apr 2001 20:51:11 -0000 1.1
@@ -0,0 +1,51 @@
+-- Run this when dropping fails due to integrity constraints.
+-- This script destroys undeleted data.
+
+----- PHOTOS -----
+create table pl_photos as
+ select object_id as photo_id from acs_objects where object_type = 'pl_photo';
+
+declare
+ v_gc_installed_p integer;
+ cursor cur is
+ select photo_id as id from pl_photos;
+begin
+ select count(1) into v_gc_installed_p
+ from user_tables where table_name = 'GENERAL_COMMENTS';
+ for photo in cur loop
+ if v_gc_installed_p = 1 then
+ execute immediate 'begin
+ for message in (select comment_id as id from general_comments
+ where object_id = ' || photo.id || ') loop
+ acs_message.delete(message.id);
+ end loop;
+end;';
+ end if;
+ delete from acs_permissions where object_id = photo.id;
+ acs_object.delete(photo.id);
+ end loop;
+ acs_object_type.drop_type('pl_photo');
+end;
+/
+show errors
+
+drop table pl_photos;
+
+----- FOLDERS -----
+create table pl_folders as
+ select object_id as folder_id from acs_objects where object_type = 'pl_folder';
+
+declare
+ cursor cur is
+ select folder_id as id from pl_folders;
+begin
+ for folder in cur loop
+ delete from acs_permissions where object_id = folder.id;
+ acs_object.delete(folder.id);
+ end loop;
+ acs_object_type.drop_type('pl_folder');
+end;
+/
+show errors
+
+drop table pl_folders;
Index: openacs-4/contrib/obsolete-packages/photo-album-lite/sql/oracle/photo-album-lite-create.sql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/photo-album-lite/sql/oracle/photo-album-lite-create.sql,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/contrib/obsolete-packages/photo-album-lite/sql/oracle/photo-album-lite-create.sql 20 Apr 2001 20:51:11 -0000 1.1
@@ -0,0 +1,164 @@
+--
+-- $Id: photo-album-lite-create.sql,v 1.1 2001/04/20 20:51:11 donb Exp $
+--
+-- We are going to subclass acs_object as opposed to using
+-- the content repository.
+
+create table pl_folders (
+ folder_id integer
+ constraint pl_folders_id_nn
+ not null
+ constraint pl_folders_pk
+ primary key
+ constraint pl_folders_obj_fk
+ references acs_objects(object_id),
+ title varchar(100)
+ constraint pl_folders_title_nn
+ not null,
+ descr varchar(4000),
+ default_exp_date date,
+ default_prefix varchar(250),
+ deleted_p char(1) default 'f'
+ constraint pl_folders_deleted_p_ck
+ check (deleted_p in ('t','f'))
+);
+
+create table pl_photos (
+ photo_id integer
+ constraint pl_photos_id_nn
+ not null
+ constraint pl_photos_pk
+ primary key
+ constraint pl_photos_obj_fk
+ references acs_objects(object_id),
+ folder_id integer
+ constraint pl_photos_folder_nn
+ not null
+ constraint pl_photos_folder_fk
+ references pl_folders,
+ exposure_date date,
+ sort_n integer
+ constraint pl_photos_sort_nn
+ not null,
+ caption varchar(3000),
+ client_filename varchar(256)
+ constraint pl_photos_file_nn
+ not null,
+ file_extension varchar(4)
+ constraint pl_photos_file_xtn_nn
+ not null,
+ thumb_width integer,
+ thumb_height integer,
+ thumb_kbytes integer,
+ med_width integer,
+ med_height integer,
+ med_kbytes integer,
+ orig_width integer,
+ orig_height integer,
+ orig_kbytes integer,
+ indexable_stuff varchar(4000),
+ deleted_p char(1) default 'f'
+ constraint pl_photos_deleted_p_ck
+ check (deleted_p in ('t','f'))
+);
+
+-- we use this temp table to avoid the "table is mutating" problem
+-- when re-calculating the sort_n's after a photo is deleted.
+create table pl_reshuffle_queue (
+ folder_id integer
+);
+
+-- We use this sequence to make sure we can give
+-- photos a unique sort_n when we move them into
+-- a new folder. We assume no folder will have
+-- more than a million photos
+create sequence pl_moved_photo_sort_n_seq start with 1000000;
+
+-- object system support
+
+-- I. photos
+
+begin
+ acs_object_type.create_type (
+ supertype => 'acs_object',
+ object_type => 'pl_photo',
+ pretty_name => 'Photo',
+ pretty_plural => 'Photos',
+ table_name => 'PL_PHOTOS',
+ id_column => 'PHOTO_ID'
+ );
+end;
+/
+show errors;
+
+-- II. folders
+
+begin
+ acs_object_type.create_type (
+ supertype => 'acs_object',
+ object_type => 'pl_folder',
+ pretty_name => 'Folder',
+ pretty_plural => 'Folders',
+ table_name => 'PL_FOLDERS',
+ id_column => 'FOLDER_ID'
+ );
+end;
+/
+show errors;
+
+@@ photo-album-lite-views
+@@ photo-album-lite-plsql
+@@ photo-album-lite-triggers
+
+create index pl_photo_idx
+on pl_photos(indexable_stuff)
+indextype is ctxsys.context;
+
+prompt **
+prompt ** Setting up search...
+prompt ** NOTE: this requires that you grant the execute privilege
+prompt ** on ctx_ddl to your server user.
+prompt ** For more information see
+prompt ** @yourserver/packages/photo-album-lite/sql/photo-album-lite-create.sql
+prompt **
+prompt ** Don't worry if this fails...the package will still work just fine
+prompt ** except that the search index will not be rebuilt automatically.
+prompt **
+
+-- keep this index in sync with a dbms_job
+-- WARNING: you need to explicitly grant execute
+-- privileges on ctx_ddl to the aolserver database user
+-- for this to work!!!!
+--
+-- Here's how:
+--
+-- 1. log in to sql*plus as ctxsys
+-- 2. SQL> grant execute on ctx_ddl to yourservicename;
+--
+
+-- this table should have just one row
+-- to hold the dbms job for rebuilding the
+-- search index.
+create table pl_jobs (
+ job integer not null primary key
+);
+
+create or replace procedure pl_rebuild_idx
+is
+begin
+ ctx_ddl.sync_index('pl_photo_idx');
+end;
+/
+show errors;
+
+variable pl_rebuild_idx_job number;
+begin
+ dbms_job.submit(:pl_rebuild_idx_job,
+ 'pl_rebuild_idx;',
+ interval => 'sysdate + 1/6');
+ insert into pl_jobs values (:pl_rebuild_idx_job);
+end;
+/
+show errors;
+print pl_rebuild_idx_job
+
Index: openacs-4/contrib/obsolete-packages/photo-album-lite/sql/oracle/photo-album-lite-drop.sql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/photo-album-lite/sql/oracle/photo-album-lite-drop.sql,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/contrib/obsolete-packages/photo-album-lite/sql/oracle/photo-album-lite-drop.sql 20 Apr 2001 20:51:11 -0000 1.1
@@ -0,0 +1,99 @@
+--
+-- $Id: photo-album-lite-drop.sql,v 1.1 2001/04/20 20:51:11 donb Exp $
+--
+
+prompt **
+prompt ** NOTE: This script will fail if you did not delete all photos and
+prompt ** folders on your system.
+prompt **
+prompt ** You can recover from a failed drop attempt by running this script:
+prompt ** @yourserver/packages/photo-album-lite/sql/cleanup-failed-drop.sql
+prompt **
+
+-- remove all rows associated with deleted objects.
+declare
+ v_gc_installed_p integer;
+ cursor cur1 is
+ select photo_id from pl_photos
+ where deleted_p = 't';
+ cursor cur2 is
+ select folder_id from pl_folders
+ where deleted_p = 't';
+ v_id integer;
+begin
+ select count(1) into v_gc_installed_p
+ from user_tables where table_name = 'GENERAL_COMMENTS';
+
+ open cur1;
+ loop
+ fetch cur1 into v_id;
+ exit when cur1%NOTFOUND;
+ delete from acs_permissions where object_id = v_id;
+ if v_gc_installed_p = 1 then
+ execute immediate 'begin
+ for message in (select comment_id as id from general_comments
+ where object_id = ' || v_id || ') loop
+ acs_message.delete(message.id);
+ end loop;
+end;';
+ end if;
+ acs_object.delete (v_id);
+ end loop;
+ close cur1;
+
+ open cur2;
+ loop
+ fetch cur2 into v_id;
+ exit when cur2%NOTFOUND;
+ delete from acs_permissions where object_id = v_id;
+ acs_object.delete (v_id);
+ end loop;
+
+end;
+/
+show errors
+
+-- this will fail if you haven't deleted
+-- all photos and folders.
+begin
+ acs_object_type.drop_type ('pl_photo');
+ acs_object_type.drop_type ('pl_folder');
+end;
+/
+show errors
+
+drop procedure pl_rebuild_idx;
+
+-- shut off the dbms_job
+declare
+ cursor cur1 is
+ select job from pl_jobs;
+ v_job integer;
+begin
+ open cur1;
+ loop
+ fetch cur1 into v_job;
+ exit when cur1%NOTFOUND;
+ dbms_job.remove(v_job);
+ end loop;
+ close cur1;
+end;
+/
+show errors
+
+drop table pl_jobs;
+drop table pl_reshuffle_queue;
+
+drop function pl_photo_date_format;
+drop function pl_relative_date;
+
+drop view pl_v_photos;
+drop view pl_v_folders;
+
+drop table pl_photos;
+drop table pl_folders;
+
+drop package pl_photo;
+drop package pl_folder;
+
+drop sequence pl_moved_photo_sort_n_seq;
Index: openacs-4/contrib/obsolete-packages/photo-album-lite/sql/oracle/photo-album-lite-plsql.sql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/photo-album-lite/sql/oracle/photo-album-lite-plsql.sql,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/contrib/obsolete-packages/photo-album-lite/sql/oracle/photo-album-lite-plsql.sql 20 Apr 2001 20:51:11 -0000 1.1
@@ -0,0 +1,427 @@
+--
+-- $Id: photo-album-lite-plsql.sql,v 1.1 2001/04/20 20:51:11 donb Exp $
+--
+
+set define off;
+
+-- 1. photos
+
+create or replace package pl_photo
+as
+ function new (
+ photo_id in pl_photos.photo_id%TYPE default null,
+ folder_id in pl_photos.folder_id%TYPE default null,
+ exposure_date in pl_photos.exposure_date%TYPE default null,
+ caption in pl_photos.caption%TYPE default null,
+ client_filename in pl_photos.client_filename%TYPE default null,
+ file_extension in pl_photos.file_extension%TYPE default null,
+ object_type in acs_object_types.object_type%TYPE default 'pl_photo',
+ creation_date in acs_objects.creation_date%TYPE
+ default sysdate,
+ creation_user in acs_objects.creation_user%TYPE
+ default null,
+ creation_ip in acs_objects.creation_ip%TYPE default null,
+ context_id in acs_objects.context_id%TYPE default null
+ ) return pl_photos.photo_id%TYPE;
+
+ function next_photo_id (
+ folder_id in pl_folders.folder_id%TYPE,
+ sort_n in pl_photos.sort_n%TYPE,
+ party_id in parties.party_id%TYPE
+ default acs.magic_object_id('the_public'),
+ privilege in acs_privileges.privilege%TYPE default 'read'
+ ) return pl_photos.photo_id%TYPE;
+
+ function prev_photo_id (
+ folder_id in pl_folders.folder_id%TYPE,
+ sort_n in pl_photos.sort_n%TYPE,
+ party_id in parties.party_id%TYPE
+ default acs.magic_object_id('the_public'),
+ privilege in acs_privileges.privilege%TYPE default 'read'
+ ) return pl_photos.photo_id%TYPE;
+
+ function exp_date (
+ photo_id in pl_photos.photo_id%TYPE
+ ) return date;
+
+ function folder_title (
+ photo_id in pl_photos.photo_id%TYPE
+ ) return pl_folders.title%TYPE;
+
+ function name (
+ photo_id in pl_photos.photo_id%TYPE
+ ) return pl_photos.client_filename%TYPE;
+
+ function default_name (
+ photo_id in pl_photos.photo_id%TYPE
+ ) return pl_photos.client_filename%TYPE;
+
+ procedure apply_default_name (
+ photo_id in pl_photos.photo_id%TYPE
+ );
+
+ procedure delete (
+ photo_id in pl_photos.photo_id%TYPE
+ );
+end pl_photo;
+/
+show errors
+
+create or replace package body pl_photo
+as
+ -- Note: you must call pl_reshuffle within the same transaction.
+ function new (
+ photo_id in pl_photos.photo_id%TYPE default null,
+ folder_id in pl_photos.folder_id%TYPE default null,
+ exposure_date in pl_photos.exposure_date%TYPE default null,
+ caption in pl_photos.caption%TYPE default null,
+ client_filename in pl_photos.client_filename%TYPE default null,
+ file_extension in pl_photos.file_extension%TYPE default null,
+ object_type in acs_object_types.object_type%TYPE default 'pl_photo',
+ creation_date in acs_objects.creation_date%TYPE
+ default sysdate,
+ creation_user in acs_objects.creation_user%TYPE
+ default null,
+ creation_ip in acs_objects.creation_ip%TYPE default null,
+ context_id in acs_objects.context_id%TYPE default null
+ ) return pl_photos.photo_id%TYPE
+ is
+ v_photo_id integer;
+ begin
+ v_photo_id := acs_object.new (
+ object_id => photo_id,
+ object_type => object_type,
+ creation_date => creation_date,
+ creation_user => creation_user,
+ creation_ip => creation_ip,
+ context_id => context_id
+ );
+
+ insert into pl_photos (
+ photo_id,
+ folder_id,
+ exposure_date,
+ sort_n,
+ caption,
+ client_filename,
+ file_extension )
+ values (
+ v_photo_id,
+ folder_id,
+ exposure_date,
+ v_photo_id,
+ caption,
+ client_filename,
+ file_extension );
+
+ acs_permission.grant_permission (
+ object_id => v_photo_id,
+ grantee_id => creation_user,
+ privilege => 'admin'
+ );
+
+ return v_photo_id;
+ end new;
+
+ function next_photo_id (
+ folder_id in pl_folders.folder_id%TYPE,
+ sort_n in pl_photos.sort_n%TYPE,
+ party_id in parties.party_id%TYPE
+ default acs.magic_object_id('the_public'),
+ privilege in acs_privileges.privilege%TYPE default 'read'
+ ) return pl_photos.photo_id%TYPE
+ is
+ v_photo_id pl_photos.photo_id%TYPE;
+ begin
+ select p.photo_id into v_photo_id
+ from pl_v_photos p
+ where p.folder_id = pl_photo.next_photo_id.folder_id
+ and p.sort_n in (select min(sort_n)
+ from pl_v_photos p2
+ where p2.folder_id = pl_photo.next_photo_id.folder_id
+ and p2.sort_n > pl_photo.next_photo_id.sort_n
+ and acs_permission.permission_p(p2.photo_id,
+ pl_photo.next_photo_id.party_id,
+ pl_photo.next_photo_id.privilege) = 't');
+ return v_photo_id;
+ end next_photo_id;
+
+ function prev_photo_id (
+ folder_id in pl_folders.folder_id%TYPE,
+ sort_n in pl_photos.sort_n%TYPE,
+ party_id in parties.party_id%TYPE
+ default acs.magic_object_id('the_public'),
+ privilege in acs_privileges.privilege%TYPE default 'read'
+ ) return pl_photos.photo_id%TYPE
+ is
+ v_photo_id pl_photos.photo_id%TYPE;
+ begin
+ select p.photo_id into v_photo_id
+ from pl_v_photos p
+ where p.folder_id = pl_photo.prev_photo_id.folder_id
+ and p.sort_n in (select max(sort_n)
+ from pl_v_photos p2
+ where p2.folder_id = pl_photo.prev_photo_id.folder_id
+ and p2.sort_n < pl_photo.prev_photo_id.sort_n
+ and acs_permission.permission_p(p2.photo_id,
+ pl_photo.prev_photo_id.party_id,
+ pl_photo.prev_photo_id.privilege) = 't');
+ return v_photo_id;
+ end prev_photo_id;
+
+ function exp_date (
+ photo_id in pl_photos.photo_id%TYPE
+ ) return date
+ is
+ v_exp_date date;
+ begin
+ select exposure_date into v_exp_date
+ from pl_photos p
+ where p.photo_id = pl_photo.exp_date.photo_id;
+
+ return v_exp_date;
+ end exp_date;
+
+ function folder_title (
+ photo_id in pl_photos.photo_id%TYPE
+ ) return pl_folders.title%TYPE
+ is
+ v_title pl_folders.title%TYPE;
+ begin
+ select f.title into v_title
+ from pl_folders f, pl_photos p
+ where p.photo_id = pl_photo.folder_title.photo_id
+ and f.folder_id = p.folder_id;
+
+ return v_title;
+ end folder_title;
+
+ function name (
+ photo_id in pl_photos.photo_id%TYPE
+ ) return pl_photos.client_filename%TYPE
+ is
+ v_client_filename pl_photos.client_filename%TYPE;
+ begin
+ select client_filename into v_client_filename
+ from pl_photos
+ where photo_id = pl_photo.name.photo_id;
+ return 'Photo: ' || v_client_filename;
+ end;
+
+ function default_name (
+ photo_id in pl_photos.photo_id%TYPE
+ ) return pl_photos.client_filename%TYPE
+ is
+ v_client_filename pl_photos.client_filename%TYPE;
+ begin
+ select decode(f.default_prefix,NULL,p.client_filename,f.default_prefix || '-' || to_char(p.sort_n,'TM') || p.file_extension) into v_client_filename
+ from pl_photos p,
+ pl_folders f
+ where p.photo_id = pl_photo.default_name.photo_id
+ and p.folder_id = f.folder_id;
+
+ return v_client_filename;
+ end;
+
+ procedure apply_default_name (
+ photo_id in pl_photos.photo_id%TYPE
+ )
+ is
+ v_client_filename pl_photos.client_filename%TYPE;
+ begin
+ select pl_photo.default_name(pl_photo.apply_default_name.photo_id)
+ into v_client_filename from dual;
+ update pl_photos
+ set client_filename = v_client_filename
+ where photo_id = pl_photo.apply_default_name.photo_id;
+ end apply_default_name;
+
+ procedure delete (
+ photo_id in pl_photos.photo_id%TYPE
+ )
+ is
+ begin
+ delete from pl_photos
+ where photo_id = pl_photo.delete.photo_id;
+ end delete;
+
+end pl_photo;
+/
+show errors;
+
+-- 2. folders
+
+create or replace package pl_folder
+as
+ function new (
+ folder_id in pl_folders.folder_id%TYPE default null,
+ title in pl_folders.title%TYPE default null,
+ descr in pl_folders.descr%TYPE default null,
+ default_exp_date in pl_folders.default_exp_date%TYPE default null,
+ default_prefix in pl_folders.default_prefix%TYPE default null,
+ object_type in acs_object_types.object_type%TYPE default 'pl_folder',
+ creation_date in acs_objects.creation_date%TYPE
+ default sysdate,
+ creation_user in acs_objects.creation_user%TYPE
+ default null,
+ creation_ip in acs_objects.creation_ip%TYPE default null,
+ context_id in acs_objects.context_id%TYPE default null
+ ) return pl_folders.folder_id%TYPE;
+
+ function photo_count (
+ folder_id in pl_folders.folder_id%TYPE
+ ) return integer;
+
+ function name (
+ folder_id in pl_folders.folder_id%TYPE
+ ) return pl_folders.title%TYPE;
+
+ procedure delete (
+ folder_id in pl_folders.folder_id%TYPE
+ );
+
+end pl_folder;
+/
+show errors
+
+create or replace package body pl_folder
+as
+ function new (
+ folder_id in pl_folders.folder_id%TYPE default null,
+ title in pl_folders.title%TYPE default null,
+ descr in pl_folders.descr%TYPE default null,
+ default_exp_date in pl_folders.default_exp_date%TYPE default null,
+ default_prefix in pl_folders.default_prefix%TYPE default null,
+ object_type in acs_object_types.object_type%TYPE default 'pl_folder',
+ creation_date in acs_objects.creation_date%TYPE
+ default sysdate,
+ creation_user in acs_objects.creation_user%TYPE
+ default null,
+ creation_ip in acs_objects.creation_ip%TYPE default null,
+ context_id in acs_objects.context_id%TYPE default null
+ ) return pl_folders.folder_id%TYPE
+ is
+ v_folder_id integer;
+ begin
+ v_folder_id := acs_object.new (
+ object_id => folder_id,
+ object_type => object_type,
+ creation_date => creation_date,
+ creation_user => creation_user,
+ creation_ip => creation_ip,
+ context_id => context_id
+ );
+
+ insert into pl_folders (
+ folder_id,
+ title,
+ descr,
+ default_exp_date,
+ default_prefix
+ ) values (
+ v_folder_id,
+ title,
+ descr,
+ default_exp_date,
+ default_prefix );
+
+ acs_permission.grant_permission (
+ object_id => v_folder_id,
+ grantee_id => creation_user,
+ privilege => 'admin'
+ );
+
+ return v_folder_id;
+
+ end new;
+
+ function photo_count (
+ folder_id in pl_folders.folder_id%TYPE
+ ) return integer
+ is
+ v_photo_count integer;
+ begin
+ select count(photo_id) into v_photo_count
+ from pl_v_photos
+ where folder_id = pl_folder.photo_count.folder_id;
+
+ return v_photo_count;
+ end photo_count;
+
+ function name (
+ folder_id in pl_folders.folder_id%TYPE
+ ) return pl_folders.title%TYPE
+ is
+ v_title pl_folders.title%TYPE;
+ begin
+ select title into v_title
+ from pl_folders
+ where folder_id = pl_folder.name.folder_id;
+ return 'Folder: ' || v_title;
+ end;
+
+ procedure delete (
+ folder_id in pl_folders.folder_id%TYPE
+ )
+ is
+ begin
+ delete from pl_folders where folder_id = pl_folder.delete.folder_id;
+ end delete;
+
+end pl_folder;
+/
+show errors;
+
+create or replace function pl_photo_date_format (
+ date_to_format in date
+)
+return varchar
+is
+begin
+ if date_to_format is null then
+ return null;
+ end if;
+
+ return to_char(date_to_format,'fmDD') || ' ' || to_char(date_to_format,'fmMon') || ' ' || to_char(date_to_format,'YYYY');
+end pl_photo_date_format;
+/
+show errors;
+
+create or replace function pl_relative_date (
+ the_date date
+)
+return varchar
+is
+begin
+ if trunc(the_date) = trunc(sysdate) then
+ return to_char(the_date,'fmHH:fmMI:SSam');
+ else
+ return pl_photo_date_format(the_date);
+ end if;
+end pl_relative_date;
+/
+show errors;
+
+create or replace procedure pl_reshuffle
+is
+ cursor cur is
+ select distinct folder_id as id
+ from pl_reshuffle_queue;
+begin
+ for folder in cur loop
+ for photo in (select p.*,
+ rownum as row_num
+ from (select photo_id as id
+ from pl_v_photos
+ where folder_id = folder.id
+ order by sort_n) p) loop
+ update pl_photos set sort_n = photo.row_num where photo_id = photo.id;
+ end loop;
+ delete from pl_reshuffle_queue
+ where folder_id = folder.id;
+ end loop;
+end pl_reshuffle;
+/
+show errors;
+
+set define on;
Index: openacs-4/contrib/obsolete-packages/photo-album-lite/sql/oracle/photo-album-lite-triggers.sql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/photo-album-lite/sql/oracle/photo-album-lite-triggers.sql,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/contrib/obsolete-packages/photo-album-lite/sql/oracle/photo-album-lite-triggers.sql 20 Apr 2001 20:51:11 -0000 1.1
@@ -0,0 +1,67 @@
+--
+-- $Id: photo-album-lite-triggers.sql,v 1.1 2001/04/20 20:51:11 donb Exp $
+--
+
+create or replace trigger pl_photos_ins_update_tr
+before insert or update on pl_photos
+for each row
+declare
+ v_creation_user integer;
+ v_email varchar(100);
+ v_sort_n integer;
+begin
+ select creation_user into v_creation_user from acs_objects where object_id = :new.photo_id;
+ select email into v_email from parties where party_id = v_creation_user;
+
+ :new.indexable_stuff := :new.client_filename || ' ' || :new.caption || ' ' || person.name(v_creation_user) || ' ' || v_email;
+
+ if :old.folder_id is null or
+ :new.folder_id != :old.folder_id then
+ -- new photo or moved photo
+ insert into pl_reshuffle_queue (folder_id)
+ values (:new.folder_id);
+
+ if :old.folder_id is not null then
+ -- moved photo
+ insert into pl_reshuffle_queue (folder_id)
+ values (:old.folder_id);
+
+ -- Assign a large, unique sort_n to the moved photo.
+ -- Call pl_reshuffle within the transaction to bump it back down.
+ select pl_moved_photo_sort_n_seq.nextval into v_sort_n from dual;
+ :new.sort_n := v_sort_n;
+
+ end if;
+
+ end if;
+
+end pl_photos_ins_update_tr;
+/
+show errors
+
+create or replace trigger pl_photos_post_update_tr
+after update on pl_photos
+for each row
+begin
+ update acs_objects
+ set last_modified = sysdate,
+ context_id = :new.folder_id
+ where object_id = :new.photo_id;
+
+ if :new.deleted_p = 't' then
+ insert into pl_reshuffle_queue (folder_id)
+ values (:new.folder_id);
+ end if;
+end pl_photos_post_update_tr;
+/
+show errors
+
+create or replace trigger pl_folders_update_tr
+after update on pl_folders
+for each row
+begin
+ update acs_objects set last_modified = sysdate
+ where object_id = :new.folder_id;
+end pl_folders_update_tr;
+/
+show errors
Index: openacs-4/contrib/obsolete-packages/photo-album-lite/sql/oracle/photo-album-lite-views.sql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/photo-album-lite/sql/oracle/photo-album-lite-views.sql,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/contrib/obsolete-packages/photo-album-lite/sql/oracle/photo-album-lite-views.sql 20 Apr 2001 20:51:11 -0000 1.1
@@ -0,0 +1,27 @@
+--
+-- $Id: photo-album-lite-views.sql,v 1.1 2001/04/20 20:51:11 donb Exp $
+--
+
+create or replace view pl_v_photos
+as
+ select p.*,
+ o.creation_date,
+ o.creation_user,
+ o.context_id,
+ o.last_modified
+ from pl_photos p,
+ acs_objects o
+ where p.photo_id = o.object_id
+ and p.deleted_p = 'f';
+
+create or replace view pl_v_folders
+as
+ select f.*,
+ o.creation_date,
+ o.creation_user,
+ o.context_id,
+ o.last_modified
+ from pl_folders f,
+ acs_objects o
+ where f.folder_id = o.object_id
+ and f.deleted_p = 'f';
Index: openacs-4/contrib/obsolete-packages/photo-album-lite/sql/oracle/upgrade-4.0.1-4.1.1b.sql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/photo-album-lite/sql/oracle/upgrade-4.0.1-4.1.1b.sql,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/contrib/obsolete-packages/photo-album-lite/sql/oracle/upgrade-4.0.1-4.1.1b.sql 20 Apr 2001 20:51:11 -0000 1.1
@@ -0,0 +1,73 @@
+-- Help the object system construct pretty names
+update acs_object_types
+set name_method = 'pl_photo.name'
+where object_type = 'pl_photo';
+
+update acs_object_types
+set name_method = 'pl_folder.name'
+where object_type = 'pl_folder';
+
+-- Grant 'admin' privilege to the creater of each
+-- pl_photo and pl_folder.
+begin
+ for folder in (select p.folder_id as id,
+ o.creation_user
+ from pl_folders p,
+ acs_objects o
+ where p.folder_id = o.object_id) loop
+ acs_permission.grant_permission (
+ object_id => folder.id,
+ grantee_id => folder.creation_user,
+ privilege => 'admin'
+ );
+ end loop;
+
+ for photo in (select p.photo_id as id,
+ o.creation_user
+ from pl_photos p,
+ acs_objects o
+ where p.photo_id = o.object_id) loop
+ acs_permission.grant_permission (
+ object_id => photo.id,
+ grantee_id => photo.creation_user,
+ privilege => 'admin'
+ );
+ end loop;
+end;
+/
+show errors
+
+-- All photos in a folder
+-- get this exposure date by default
+alter table pl_folders add (default_exp_date date);
+
+-- Helpful for over-writing computer-generated names.
+alter table pl_folders add (default_prefix varchar(250));
+
+-- Deprecated table.
+drop table pl_deleted_photos;
+
+-- we use this temp table to avoid the "table is mutating" problem
+-- when re-calculating the sort_n's after a photo is deleted.
+create table pl_reshuffle_queue (
+ folder_id integer
+);
+
+-- We use this sequence to make sure we can give
+-- photos a unique sort_n when we move them into
+-- a new folder. We assume no folder will have
+-- more than a million photos
+create sequence pl_moved_photo_sort_n_seq start with 1000000;
+
+@@ photo-album-lite-plsql
+@@ photo-album-lite-triggers
+@@ photo-album-lite-views
+
+-- Fix any sort bugs in previous installation
+begin
+ insert into pl_reshuffle_queue (folder_id)
+ select folder_id from pl_v_folders;
+ pl_reshuffle;
+end;
+/
+show errors
Index: openacs-4/contrib/obsolete-packages/photo-album-lite/sql/oracle/upgrade-4.0.1a-4.0.1b.sql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/photo-album-lite/sql/oracle/upgrade-4.0.1a-4.0.1b.sql,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/contrib/obsolete-packages/photo-album-lite/sql/oracle/upgrade-4.0.1a-4.0.1b.sql 20 Apr 2001 20:51:11 -0000 1.1
@@ -0,0 +1,26 @@
+--
+-- upgrade-4.0.1a-4.0.1b.sql
+--
+-- aegrumet@arsdigita.com
+--
+-- create pa_jobs table and put an entry in it
+
+-- this table should have just one row
+-- to hold the dbms job for rebuilding the
+-- search index.
+create table pa_jobs (
+ job integer not null primary key
+);
+
+declare
+ cursor cur is
+ select job
+ from user_jobs
+ where what = 'pa_rebuild_idx;';
+begin
+ for job in cur loop
+ insert into pa_jobs (job) values (job.job);
+ end loop;
+end;
+/
+show errors
Index: openacs-4/contrib/obsolete-packages/photo-album-lite/sql/oracle/upgrade-4.0.1b-4.0.1.sql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/photo-album-lite/sql/oracle/upgrade-4.0.1b-4.0.1.sql,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/contrib/obsolete-packages/photo-album-lite/sql/oracle/upgrade-4.0.1b-4.0.1.sql 20 Apr 2001 20:51:11 -0000 1.1
@@ -0,0 +1,189 @@
+--
+-- upgrade-4.0.1b-4.0.1.sql
+--
+-- Upgrades from the beta.
+-- We had to rename everything from pa_* to pl_*
+-- to avoid conflicts with the photo-album package.
+-- This is pretty heavy-duty stuff.
+--
+-- There is also some code at the bottom to remap the sort_n's
+-- to always start at 1 for each folder.
+
+-- plan:
+-- 1. disable object_type fk constraint
+-- 2. rename the object type for each of pa_photo and pa_folder:
+-- a. update these columns in acs_object_types
+-- object_type
+-- table_name
+-- b. update acs_objects table
+-- 3. enable the object_type fk constraint
+-- 4. rename the pa_photo and pa_folder tables
+-- 5. rename all the constraints by dropping and adding them
+-- 6. drop the index rebuild job
+-- 7. drop old views/triggers/plsql
+-- 8. re-run all views/triggers/plsql
+-- 9. add the index rebuild job
+
+-- AND HERE WE GO...
+
+alter table acs_objects disable constraint acs_objects_object_type_fk;
+
+update acs_object_types
+ set object_type = 'pl_photo',
+ table_name = 'PL_PHOTOS'
+ where object_type = 'pa_photo';
+
+update acs_objects
+ set object_type = 'pl_photo'
+ where object_type = 'pa_photo';
+
+update acs_object_types
+ set object_type = 'pl_folder',
+ table_name = 'PL_FOLDERS'
+ where object_type = 'pa_folder';
+
+update acs_objects
+ set object_type = 'pl_folder'
+ where object_type = 'pa_folder';
+
+alter table acs_objects enable constraint acs_objects_object_type_fk;
+
+alter table pa_photos rename to pl_photos;
+alter table pa_folders rename to pl_folders;
+
+alter table pl_photos drop constraint pa_photos_id_nn;
+alter table pl_photos drop constraint pa_photos_pk;
+alter table pl_photos drop constraint pa_photos_obj_fk;
+alter table pl_photos drop constraint pa_photos_folder_nn;
+alter table pl_photos drop constraint pa_photos_folder_fk;
+alter table pl_photos drop constraint pa_photos_sort_nn;
+alter table pl_photos drop constraint pa_photos_file_nn;
+alter table pl_photos drop constraint pa_photos_file_xtn_nn;
+alter table pl_photos drop constraint pa_photos_deleted_p_ck;
+alter table pl_photos drop constraint pa_photos_folder_sort_un;
+alter table pl_folders drop constraint pa_folders_id_nn;
+alter table pl_folders drop constraint pa_folders_pk;
+alter table pl_folders drop constraint pa_folders_obj_fk;
+alter table pl_folders drop constraint pa_folders_title_nn;
+alter table pl_folders drop constraint pa_folders_deleted_p_ck;
+
+alter table pl_folders add constraint pl_folders_pk
+ primary key (folder_id);
+alter table pl_folders add constraint pl_folders_obj_fk
+ foreign key (folder_id) references acs_objects(object_id);
+alter table pl_folders add constraint pl_folders_title_nn
+ check (title is not null);
+alter table pl_folders add constraint pl_folders_deleted_p_ck
+ check (deleted_p in ('t','f'));
+
+alter table pl_photos add constraint pl_photos_pk
+ primary key (photo_id);
+alter table pl_photos add constraint pl_photos_obj_fk
+ foreign key (photo_id) references acs_objects(object_id);
+alter table pl_photos add constraint pl_photos_folder_nn
+ check (folder_id is not null);
+alter table pl_photos add constraint pl_photos_folder_fk
+ foreign key (folder_id) references pl_folders;
+alter table pl_photos add constraint pl_photos_sort_nn
+ check (sort_n is not null);
+alter table pl_photos add constraint pl_photos_file_nn
+ check (client_filename is not null);
+alter table pl_photos add constraint pl_photos_file_xtn_nn
+ check (file_extension is not null);
+alter table pl_photos add constraint pl_photos_deleted_p_ck
+ check (deleted_p in ('t','f'));
+
+declare
+ cursor cur1 is
+ select job from pa_jobs;
+ v_job integer;
+begin
+ open cur1;
+ loop
+ fetch cur1 into v_job;
+ exit when cur1%NOTFOUND;
+ dbms_job.remove(v_job);
+ end loop;
+ close cur1;
+end;
+/
+show errors
+
+delete from pa_jobs;
+
+alter table pa_jobs rename to pl_jobs;
+
+drop procedure pa_rebuild_idx;
+drop package pa_photo;
+drop package pa_folder;
+drop function pa_photo_date_format;
+drop function pa_relative_date;
+drop trigger pa_photos_ins_update_tr;
+drop trigger pa_photos_post_update_tr;
+drop trigger pa_folders_update_tr;
+drop view pa_v_photos;
+drop view pa_v_folders;
+
+-- we use this temp table to avoid the "table is mutating" problem
+-- when re-calculating the sort_n's after a photo is deleted.
+
+create table pl_deleted_photos (
+ folder_id integer
+ constraint pl_deleted_photos_folder_nn
+ not null,
+ sort_n integer
+ constraint pl_delete_photos_sort_n_nn
+ not null,
+ swept_p char(1) default 'f'
+ constraint pl_deleted_photos_swept_p_ck
+ check (swept_p in ('t','f'))
+);
+
+@@ photo-album-lite-views
+@@ photo-album-lite-plsql
+@@ photo-album-lite-triggers
+
+alter index pa_photo_idx rename to pl_photo_idx;
+
+create or replace procedure pl_rebuild_idx
+is
+begin
+ ctx_ddl.sync_index('pl_photo_idx');
+end;
+/
+show errors;
+
+variable pl_rebuild_idx_job number;
+begin
+ dbms_job.submit(:pl_rebuild_idx_job,
+ 'pl_rebuild_idx;',
+ interval => 'sysdate + 1/6');
+ insert into pl_jobs values (:pl_rebuild_idx_job);
+end;
+/
+show errors;
+print pl_rebuild_idx_job
+
+-- Make sort_n start at 1 for each folder so
+-- that we can easily display "Photo 3 of 12".
+-- Since we preserve the original order
+-- we don't need to defer the unique constraint
+-- on (sort_n,folder_id).
+declare
+ v_count integer;
+ cursor cur is
+ select folder_id as id
+ from pl_folders;
+begin
+ for folder in cur loop
+ v_count := 0;
+ for photo in (select photo_id as id from pl_v_photos where folder_id = folder.id order by sort_n) loop
+ v_count := v_count + 1;
+ update pl_photos set sort_n = v_count
+ where photo_id = photo.id;
+ end loop;
+ end loop;
+end;
+/
+show errors
+
Index: openacs-4/contrib/obsolete-packages/photo-album-lite/tcl/bulk-upload-procs.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/photo-album-lite/tcl/bulk-upload-procs.tcl,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/contrib/obsolete-packages/photo-album-lite/tcl/bulk-upload-procs.tcl 20 Apr 2001 20:51:12 -0000 1.1
@@ -0,0 +1,60 @@
+ad_library {
+ @author Andrew Grumet
+ @cvs-id: $Id: bulk-upload-procs.tcl,v 1.1 2001/04/20 20:51:12 donb Exp $
+}
+
+ad_proc pl_bulk_insert {
+ {-use_default_date 0}
+ {-use_default_prefix 0}
+ folder_id
+ server_tempnam
+} {
+
+ Upload a zip file full of pictures.
+ Shamelessly copied from Wimpy Point.
+ Thank You Nuno Santos .
+
+} {
+ # Step 1: Create temp directory.
+
+ set tmp_dir [file dirname $server_tempnam]
+ append tmp_dir "/[ns_mktemp "$folder_id-XXXXXX"]"
+ if [catch { ns_mkdir $tmp_dir } errMsg ] {
+ ns_log Notice "photo-album-lite: Error creating directory $tmp_dir: $errMsg"
+ return -code error "photo-album-lite: there was an error unzipping your file. Please contact the server administrator for assistance."
+ }
+
+ # Step 2: Unzip the archive
+
+ set unzip_home [ad_parameter PathToUnzip photo-album-lite /usr/bin]
+
+ # unzip -C -j zipfile *.gif *.jpg -d directory
+ # only extract GIFs and JPGs (-C=case-insensitive) into directory;
+ # don't create subdirs (-j);
+ # ignore "caution: filename not matched" unzip message
+ # (if one of the formats is not present in the archive)
+
+ if { [catch { exec $unzip_home/unzip -C -j $server_tempnam *.gif *.jpg -d $tmp_dir } errMsg] && ![regexp {caution: filename not matched} $errMsg]} {
+ ns_log Notice "photo-album-lite: Error unzipping $server_tempnam: $errMsg"
+ file delete -force $tmp_dir
+ return -code error "photo-album-lite: there was an error unzipping your file. Please contact the server administrator for assistance."
+ }
+
+ # Step 3: use glob to get a list of files in the directory
+ set file_exts {[Gg][Ii][Ff],[Jj][Pp][Gg]}
+ set image_file_list [lsort [glob -nocomplain $tmp_dir/*.{$file_exts}]]
+
+ # Step 4: loop through the files and do the insert
+
+ foreach image_file $image_file_list {
+ if [catch {pl_photo_insert -use_default_date $use_default_date -use_default_prefix $use_default_prefix $folder_id $image_file} errMsg] {
+ global errorInfo
+ return -code error "photo-album-lite: sorry, there was an error: $errMsg"
+ }
+ }
+
+ # Step 5: clean up
+
+ file delete -force $tmp_dir
+
+}
Index: openacs-4/contrib/obsolete-packages/photo-album-lite/tcl/photo-album-lite-init.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/photo-album-lite/tcl/photo-album-lite-init.tcl,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/contrib/obsolete-packages/photo-album-lite/tcl/photo-album-lite-init.tcl 20 Apr 2001 20:51:12 -0000 1.1
@@ -0,0 +1,248 @@
+ad_library {
+
+ Photo album helper procedures.
+ @author Andrew Grumet
+ @creation-date 12 Dec 2000
+ @cvs-id: $Id: photo-album-lite-init.tcl,v 1.1 2001/04/20 20:51:12 donb Exp $
+
+}
+
+ad_proc pl_photo_cleanup_filename {
+ filename
+} {
+
+ # Regsub out spaces and other characters from the client filename.
+
+ # Returns 1 if both general comments is installed
+ # and GeneralCommentsEnabledP is 1, otherwise returns 0.
+ # HINT: This would be a good place to add fancy permission checks.
+
+} {
+
+ if ![ad_parameter GeneralCommentsEnabledP photo-album-lite pl_photos] {
+ # general-comments is disabled for this package
+ return 0
+ }
+
+ if [empty_string_p [namespace eval :: {info procs general_comments_get_comments}]] {
+ # general-comments is not installed
+ return 0
+ }
+
+ # If we made it here, comments are okay.
+ return 1
+}
+
+ad_proc pl_base_directory {
+ {-read_only:boolean}
+ photo_id
+} {
+
+ # returns a destination directory for this photo.
+ # creates the directory if necessary
+
Index: openacs-4/contrib/obsolete-packages/photo-album-lite/www/index.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/photo-album-lite/www/index.tcl,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/contrib/obsolete-packages/photo-album-lite/www/index.tcl 20 Apr 2001 20:51:12 -0000 1.1
@@ -0,0 +1,104 @@
+ad_page_contract {
+
+ @author Andrew Grumet
+ @cvs-id: $Id: index.tcl,v 1.1 2001/04/20 20:51:12 donb Exp $
+
+ Show recent photos and summary info.
+
+} {}
+
+# Give a friendly warning for fresh installs, or set a parameter
+# for use below.
+if [catch {set default_height [ad_parameter ThumbHeight photo-album-lite 100]}] {
+ ad_return_error "Error calling ad_parameter." "There was an error calling ad_parameter. If this is a fresh install, please restart your server."
+}
+
+set context_bar [ad_context_bar]
+
+set package_id [ad_conn package_id]
+
+set instance_name [db_string pl_instance_name {
+ select instance_name from apm_packages where package_id = :package_id
+}]
+
+set photo_count [db_string pl_photo_count {
+ select count(p.photo_id)
+ from pl_v_photos p,
+ pl_v_folders f
+ where p.folder_id = f.folder_id
+ and f.context_id = :package_id
+}]
+
+set last_upload [db_string pl_last_upload {
+ select pl_relative_date(max(p.creation_date))
+ from pl_v_photos p,
+ pl_v_folders f
+ where p.folder_id = f.folder_id
+ and f.context_id = :package_id
+}]
+
+set line_break [ad_parameter RightMargin photo-album-lite 450]
+set line_count 1
+set running_width 0
+
+set photo_table "
"
+
+# assumption: 20 photos is enough to fill the page.
+# don't think you can do this with pure templating logic.
+# we do some goofy nvl'ing and arithmetic to handle
+# missing heights and widths
+db_foreach new_photos {
+ select * from (
+ select p.client_filename,
+ p.photo_id,
+ decode(p.thumb_width,NULL,'','width="' || p.thumb_width || '"') as width_tag,
+ 'height="' || nvl(p.thumb_height,:default_height) || '"' as height_tag,
+ nvl(p.thumb_width,round(:default_height * 1.33)) as thumb_width
+ from pl_v_photos p,
+ pl_v_folders f
+ where p.folder_id = f.folder_id
+ and f.context_id = :package_id
+ order by p.creation_date desc )
+ where rownum < 20
+} {
+ if { $running_width > $line_break } {
+ incr line_count
+ set running_width 0
+ if { $line_count < 4 } {
+ append photo_table "
+
+Add image files or Zip archives from your hard drive
+ (you'll be able to add more information after the photos
+are on the server;
+for best results, limit the total upload to 10MB or less)
+
+