Managing Team-Based Web Development 
by Jacob Gsoedl


Listing One
<% 'Global variables initialization
dim SSIni, Username, SSTempDir, DocsDir, ReplicationUser, 
                                              AdminUser, EveryoneUser
UserName       = Request.ServerVariables("Remote_USER")
'-----------------------------------------------------------------------------
'Account may need to be adjusted to match account names used in environment
'-----------------------------------------------------------------------------
ReplicationUser = "replica"
EveryoneUser    = "Everyone"
AdminUser       = "Administrators"
'-----------------------------------------------------------------------------
'-----------------------------------------------------------------------------
' This section does not have to be changed!
' Following Session variables are initialized the first time app is called:
' -- SSini:     Location of the srcsafe.ini file.
' -- SSTempDir: Location of the SourceSafe Working Folder
' -- SSDocsDir: Location of the Document folder of app you want to manage.
'-----------------------------------------------------------------------------
If Session("SSIni") = "" OR Session("SSTempDir") = 
                                      "" OR Session("DocsDir")=""  Then
   'Session has expired or missing parameters!
   If Request.QueryString("SSIni")="" OR Request.QueryString("SSTempDir")="" 
                                     OR Request.QueryString("DocsDir")="" Then
      Response.Write("<br><b>The User Session has expired or arguments 
                           are missing! You need to login again!</b><br><br>")
      Response.Write("<b>This application expects 3 parameters in 
                                                           the URL:</b><br>")
      Response.Write("-- <b>SSIni:</b>&nbsp;&nbsp;&nbsp;&nbsp;
                The path to the srcsafe.ini file of the current project<br>")
      Response.Write("-- <b>SSTempDir:</b>&nbsp;The location of 
                the Working Folder for Visual Source Safe<br>")
      Response.Write("-- <b>DocsDir:</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                &nbsp;&nbsp;The location of the Project<br><br>")
      Response.Write("Example: default.asp?SSIni=
           c:\Project\SRCSAFE.INI&SSTempDir=e:\VSStemp&DocsDir=c:\htdocs<br>")
      Response.End
   Else
      Session("SSIni")     = Request.QueryString("SSIni")
      Session("SSTempDir") = Request.QueryString("SSTempDir")
      Session("DocsDir")   = Request.QueryString("DocsDir")
   End If
End If
SSIni = Session("SSIni")
SSTempDir  = Session("SSTempDir")
DocsDir    = Session("DocsDir")
%>

Listing Two
<%@ Language=VBScript %>     
<%option explicit%>
<!-- #include file="inc/constants.asp"-->
<!-- #include file="inc/vssconst.asp"-->
<%
  Dim currentPath, index, docCount,FolderCount,
                                   strSlash, segmentCnt, strDBName,FSPath
  dim docs(),folders(),segments(50)
  dim  objVSSdb, objVSSObject,objVssRoot
 '--- Create an instance of a Visual Source Database object ---
 On Error Resume Next
 Set objVSSdb = CreateObject("SourceSafe")
 objVSSdb.Open SSIni, UserName
 If Err.Number <> 0 Then
    Response.Write "User '<b>" & Username & "</b>' doesn't exist in 
            SourceSafe, or the path to the srcsafe.ini (<b>" & 
            SSIni & "</b>) file is wrong!"
    Session.Abandon()
    Response.End
 End If
  '--- Variable initialization
  strDBName = objVSSdb.databasename
  currentPath= Request.QueryString("cp")
  If currentPath=empty  Then
    currentpath="/"
  Else
      currentpath=BPath(currentPath)
  End If   
  If currentPath = "/" Then
     strSlash = ""
  Else
     strSlash = "/"
  End If
  '--- Create vssItem Object ---
  set objVssRoot=objVSSdb.vssItem("$" + currentPath,False)
  If currentPath = "/" Then
     objVssRoot.LocalSpec=SSTempDir
  End If
  FSPath = Replace( DocsDir & currentPath,"/","\") 
                      'File System equivalent of the VSS Folder
  '--- Create docs and folders array of the proper size ---
  docCount=0
  folderCount=0
  for each objVSSObject In objVssRoot.items
  if  objVSSObject.Type = VSSITEM_FILE Then
    docCount=docCount+1
  else  
    foldercount=foldercount+1
  end If
  Next
  redim docs(doccount,2)
  redim folders(FolderCount,2)
  '--- Fills the docs & folders array with items in the current folder ---
  '--- Docs array stores: filename & Username in case file is checked out ---
  '--- Folders array stores: foldername & Username in case folder is checked out  --- 
  docCount=0
  folderCount=0
  for each objVSSObject In objVssRoot.items
    if objVSSObject.Type = VSSITEM_FILE Then
      docs(docCount,0)=objVSSObject.Name
      if objVSSObject.isCheckedOut = VSSFILE_NOTCHECKEDOUT then 
        docs(docCount,1)=""
      else
        docs(docCount,1)=LCase(objVSSObject.checkouts(1).username)
      end if  
      docCount=docCount+1
    else  
      folders(foldercount,0)=objVSSObject.Name
      folders(folderCount,1)= LCase(getItemCreator(FSPath & "\" & objVSSObject.Name))
      foldercount=foldercount+1 
    end If
  Next
   '--------------------------------------------------------------------------
   ' getItemCreator: Returns the Username that created the file or folder
   ' Input:  ItemName --> File or Folder name
   '--------------------------------------------------------------------------
   Function getItemCreator(ByVal ItemName)
      Dim Au, Item, Ace, AceUser, ItemCreator
      On Error Resume Next
      ItemCreator = ""
      Set Au = Server.CreateObject("Persits.AspUser")
      Set Item = Au.File(ItemName)
      If Err.Number <> 0 Then
        'An error is generated if the Folder was deleted from the File System'
        Response.Write "<b>A File or Folder doesn't exist!</b><BR>"
        Response.Write "Go one page back, check the Scan checkbox next 
                                                    to the folder name, <BR>"
        Response.Write "and click on the 'Scan for 
                                              New&Deleted Items' button!<BR>"
         Response.End
      End If
      For i = 1 to Item.AllowanceCount
         Set Ace = Item.GetAllowanceAce(i)
         AceUser = LCase(Ace.AccountName)
         If AceUser <> LCase(AdminUser) AND AceUser <> LCase(EveryoneUser) 
                                  AND AceUser <> LCase(ReplicationUser) Then
            ItemCreator = AceUser
            Exit For
         End If
      Next
      getItemCreator = ItemCreator
   End Function
   '--------------------------------------------------------------------------
   ' BPath: Replaces // with /
   ' Input: Path string
   '--------------------------------------------------------------------------
  function BPath(byVal s1)
      if len(s1)>2 then
       if mid(s1,1,2)="//" then  
        s1=left(s1,1) & right(s1,len(s1)-2)
       end if 
      end if 
      Bpath=s1
  end function 
   '--------------------------------------------------------------------------
   ' getPathSegments: Breaks up a path string (separated by /) and puts each 
   '                  segment into the segments array.
   ' Input: Path string
   '--------------------------------------------------------------------------
  function getPathSegments(byval s)
     dim cnt,i,slen,sStr,iStr
     cnt =0
     iStr = s
     i = InStr(iStr,"/")
     do while i > 0
        if i>1 then 
           sStr = Left(iStr,i-1) 
           segments(cnt) = sStr
           cnt = cnt + 1
        else 
           sStr="" 
        end if  
        iStr = Right(iStr,len(iStr)-len(sStr)-1)
        i = InStr(iStr,"/")
     loop
     if iStr <> "" then
        segments(cnt) = iStr
        cnt = cnt + 1
     end if
     getPathSegments = cnt
  end function
%>
<HTML>
<HEAD>
<TITLE>Source Code Control User Interface</TITLE>
</HEAD>
<SCRIPT LANGUAGE="JavaScript">
<!--
   function doCheckInOut(){
      document.frmItems.Mode.value = "CheckIn&Out";
      document.frmItems.submit();
      return(true);
   }
   function doScan(){
      document.frmItems.Mode.value = "Scan";
      document.frmItems.submit();
      return(true);
   }
-->
</SCRIPT>
<BODY>
<form name="frmItems" action="submit.asp" method="POST" >
  <table cellspacing="2" cellpadding="2" border="0">
  <tr><td colspan="8"><center><b><%=strDBName%></b></center></td></tr>
  <tr><td colspan="8"><HR></td></tr>
  <!-- -------------------------- -->
  <!-- Render the Navigation Link -->
  <!-- -------------------------- -->
  <tr><td colspan="8"><font size="2">
  <%  segmentCnt = getPathSegments(currentpath)
      dim i,ii,strcp,strSlsh1,strSlsh
      strSlsh1 = ""
      for i=0 to segmentCnt
            strcp="/"
            strSlsh = ""
            for ii=0 to (i-1)
               strcp = strcp & strSlsh & segments(ii)
               strSlsh = "/"
            next
  %>        <a href="default.asp?cp=<%=strcp%>">
            <%=strSlsh1%><%=segments(i)%>
  <%        strSlsh1 = "/"
      next 
  %>
  </font>
  </td></tr>
  <tr>
  <th></th>
  <th>&nbsp;Checkout&nbsp;</th>
  <th>&nbsp;Checkin&nbsp;</th>
  <th>&nbsp;Recursive&nbsp;</th>
  <th>&nbsp;</th>
  <th>&nbsp;Name&nbsp;</th>
  <th>&nbsp;Scan&nbsp;</th>
  <th>&nbsp;LockedBy&nbsp;</th>
  </tr>
  <!-- -------------------------- -->
  <!--       Render Folders       -->
  <!-- -------------------------- -->
<%for index=0 to foldercount-1 %>
  <tr><td>
<% if LCase(folders(index,1))= LCase(username) then %>
     <IMG SRC="images/bl_diam.gif"> 
<% else 
     if folders(index,1)<>""  then 
%>      <IMG SRC="images/or_diam.gif">
<%   else %>
        <IMG SRC="images/gr_diam.gif">
<%   end if
   end if  
%></td>
  <td align=center>
     <input type="Checkbox" name="o1_<%=index%>">&nbsp;
  </td>
  <td align=center>
     <input type="Checkbox" name="i1_<%=index%>">&nbsp;
  </td>
  <td align=center>
     <input type="Checkbox" name="r1_<%=index%>">&nbsp;
  </td>
  <td><IMG SRC="images/dir.gif"></td>
  <td><A href="default.asp?cp=<%=currentpath & strSlash & folders(index,0)%>">
                              <%=folders(index,0)%></A>&nbsp;&nbsp;&nbsp;</td>
  <td align=center><input type="Checkbox" name="s1_<%=index%>"></td>
  <td align="left"><%=folders(index,1)%>&nbsp;</td>
  </tr>
  <input type="Hidden" name="t1_<%=index%>" value="<%=currentpath  & 
                                            strSlash & folders(index,0)%>">
<%next%>
<!-- -------------------------- -->
<!--         Render Files       -->
<!-- -------------------------- -->
<% for index=0 to doccount-1 %>
  <tr><td>
<% if LCase(docs(index,1))= LCase(username) then %>
     <IMG SRC="images/bl_diam.gif">
<% else
     if docs(index,1)<>""  then 
%>      <IMG SRC="images/or_diam.gif">
<%   else %>
        <IMG SRC="images/gr_diam.gif">
<%   end if
   end if  
%> 
  </td>
  <td align=center>
<% if docs(index,1)=""  then %>
      <input type="Checkbox" name="o2_<%=index%>"  align="MIDDL">
<% end if %>&nbsp;
  </td>
  <td align=center>
<% if LCase(docs(index,1))= LCase(username) then %>
      <input type="Checkbox" name="i2_<%=index%>" align="MIDDL">
<%end if %>&nbsp;
  </td>
  <td align=center>&nbsp;</td>
  <td><IMG SRC="images/text.gif"></td>
  <td><%=docs(index,0)%>&nbsp;&nbsp;&nbsp;</td>
  <td align=center>&nbsp;</td>
   <td align=left><%=docs(index,1)%>&nbsp;</td>
  </tr>
  <input type="Hidden" name="t2_<%=index%>" 
                     value="<%=currentpath & strSlash & docs(index,0)%>">
<%next%>
  <tr><td colspan="8">&nbsp;</td></tr>
  <tr><td colspan="8" align="center">
       <input type="Hidden" name="Mode">
       <input type="Button" value="Check Out&In" 
                                        onClick="return doCheckInOut();">
       &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
       <input type="Button" value="Scan for New&Deleted Items" 
                                        onClick="return doScan();">
  </td></tr>
</table>
<input type="hidden" name="parent" value=<%=currentPath%>>
</form>
</BODY>
</HTML>





6

