Difference between revisions of "Development"

From ISFDB
Jump to navigation Jump to search
(45 intermediate revisions by 5 users not shown)
Line 1: Line 1:
This page serves as the hub for discussing ISFDB-related software development. Related resources include:
+
{{Isfdb-general-header}}
 +
{{development-resources}}
  
* the [https://sourceforge.net/p/isfdb/discussion/ Sourceforge discussion]
+
This page serves as the hub for discussing ISFDB-related software development.
* the [https://sourceforge.net/p/isfdb/_list/tickets Sourceforge tickets]
 
** the [https://sourceforge.net/p/isfdb/bugs/ bugs] (obsolete [[ISFDB Bug List]])
 
** the [https://sourceforge.net/p/isfdb/feature-requests/ feature requests] (obsolete [[ISFDB Feature List]])
 
* [[ISFDB:Proposed Design Changes‎]]
 
* [[ISFDB:Proposed Interface Changes]]
 
* [[Development/Recent Patches‎|Recent Patch list]]
 
* [[User talk:Fixer|Fixer's Talk page]] (for Fixer-related issues)
 
* [[ISFDB Design Documentation]] (old)
 
* [[ISFDB Downloads]] (contains links to the installation instructions)
 
* [[ISFDB Build Process]] (explanation of the build/install process)
 
* [[ISFDB Page Map]] — a list of which pages link to which other pages
 
  
 
==Developers and Testers==
 
==Developers and Testers==
  
 
*[[User:MartyD|MartyD]] — developer
 
*[[User:MartyD|MartyD]] — developer
*[[User:BLongley|BLongley]] — developer
 
 
*[[User:Kpulliam|Kpulliam]] — developer (of meager ability) / Tester
 
*[[User:Kpulliam|Kpulliam]] — developer (of meager ability) / Tester
 
*[[User:Roglo|Roglo]] — developer (inactive since mid-2009)
 
*[[User:Roglo|Roglo]] — developer (inactive since mid-2009)
Line 33: Line 22:
 
At this time the development process works as follows:
 
At this time the development process works as follows:
  
* A Bug or Feature Request ("FR") is created in SourceForge. Anyone can do it, even "anonymous".
+
* A Bug, Support Request ("SR") or Feature Request ("FR") is created in [https://sourceforge.net/projects/isfdb/ SourceForge]. Anyone can do it, even "anonymous".
* FRs should be discussed on the Community Portal and approved by the community before the work begins. Obvious bugs can be fixed and submitted without a prior discussion.
+
* FRs should be discussed on the [[ISFDB:Community Portal]] and approved by the community before the work begins. Obvious bugs can be fixed and submitted without a prior discussion.
* Once a developer decides to work on a Bug/FR, he identifies the scripts that are affected and lists the Bug/FR along with the scripts on the Development page under "Outstanding Changes". This helps avoid effort duplication.
+
* Once a developer decides to work on a Bug/SR/FR, s/he identifies the scripts that are affected and lists the Bug/SR/FR along with the scripts on the Development page under "Outstanding Changes". This helps avoid effort duplication.
* The developer makes changes on his development server and tests them. He then checks the updated modules into SourceForge and adds the new version numbers to the "Outstanding Changes" table.
+
* The developer makes changes on his or her development server and tests them. S/he then sends to the ISFDB administrator (Ahasuerus since 2009), who tests them on his local development server. In some cases the administrator may ask another developer to test the changes.
* The administrator (Ahasuerus in 2009–2013) downloads the changes to his local development server and tests them. In some cases the administrator asks another developer to test the changes.
+
* If everything works fine, the administrator commits the changes to the SourceForge repository using the SVN "commit" command, e.g.:
* If everything works fine, the administrator uses the CVS "tag" command to tag the script(s) that will go into the next build, e.g., "cvs tag r2010-80 script.py". Usually a build includes one or two changes, although occasionally the number is higher. Builds follow the 2010-NN naming convention.
+
** <source enclose=div lang=bash>svn commit -m "FR 1099 Add Last Activity date to 'Top Contributor/Moderator/etc' lists - Part 1"</source>
* The administrator signs on to the live server and uses the CVS "export" command to download all scripts for the latest build/tag to a new directory, e.g., "cvs export -r r2010-80 -d r2010-80 isfdb2"
+
* The administrator gets the latest revision number from the SourceForge repository:
* The administrator tar's the directory up, e.g., "tar -cvf r2010-80.tar *", copies the tarball to /home/avonruff/isfdb2/, untars it and types "make install" (or "make -B install" if the build added new scripts or otherwise requires a complete rebuild.)
+
** <source enclose=div lang=bash>svn info --show-item=revision -r HEAD</source>
* The administrator gzips the tarball and moves it to the archive area.
+
* The administrator creates a deployable tarball file from the modified source files, e.g:
* The administrator marks the Bug(s)/FR(s) as "Fixed/Completed" in SourceForge.
+
** <source enclose=div lang=bash>tar -cvf ~/patches/3.tar biblio/toptaggers.py</source> where '3' is the revision number retrieved in the previous step
 +
* The administrator copies the tarball to the ISFDB server and moves it to <code>/home/avonruff/isfdb2/</code>, where the main copy of the source code currently resides
 +
* The administrator untars the tarball and types <code>make install</code> (or <code>make -B install</code> if the patch added new scripts or otherwise requires a complete rebuild)
 +
* The administrator gzips the tarball and moves it to the archive area
 +
* The administrator marks the Bug(s)/SR(s)/FR(s) as "Fixed/Completed" in SourceForge
 
* The administrator moves the completed change(s) from the list of Outstanding Changes on the Development page to the "Recent Patches" sub-page. "Recent Changes" covers all builds for the current year, so it's a useful page for developers to review.
 
* The administrator moves the completed change(s) from the list of Outstanding Changes on the Development page to the "Recent Patches" sub-page. "Recent Changes" covers all builds for the current year, so it's a useful page for developers to review.
  
Line 49: Line 42:
 
=== Recent Patches ===
 
=== Recent Patches ===
  
[[Development/Archive|Patch Archive for previous years]]
+
[[Development/Archive|Patch Archive for 2009–2019]]
  
See [[Development/Recent Patches]] for the list of changes implemented in 2013.
+
See [[Development/Recent Patches]] for the list of changes implemented recently.
  
 
=== Outstanding changes ===
 
=== Outstanding changes ===
  
{|class="TablePager"
+
{|class="wikitable"
 
|-
 
|-
!Bug or Feature <!-- Use {{FReq|id#}} or {{Bug|id#}} for easy linking. -->
+
!Bug or Feature <!-- Use {{Tracker|FR|id#}} or {{Tracker|Bug|id#}} for easy linking. -->
 
!width="40%" |Description
 
!width="40%" |Description
 
!Modules and versions
 
!Modules and versions
Line 69: Line 62:
 
=== Planned changes ===
 
=== Planned changes ===
  
{|class="TablePager"
+
{|class="wikitable"
 
|-
 
|-
!Bug or Feature <!-- Use {{FReq|id#}} or {{Bug|id#}} for easy linking. -->
+
!Bug or Feature <!-- Use {{FR|id#}} or {{Bug|id#}} for easy linking. -->
 
!width="40%" |Description
 
!width="40%" |Description
 
!Modules and versions
 
!Modules and versions
Line 80: Line 73:
  
 
|-
 
|-
|{{Bug|3183863}}
+
|{{SR|24}}
 
|Static and dynamic content cannot be "rehomed" correctly
 
|Static and dynamic content cannot be "rehomed" correctly
 
|
 
|
Line 92: Line 85:
  
 
== Current Activity ==
 
== Current Activity ==
=== JesseW ===
 
==== Rename the three PrintNavBar's to distinguish them ====
 
See {{FReq|3115118}}.  It'd be very easy, but I want some feedback before I do it. [[User:JesseW|JesseW]] 05:58, 22 November 2010 (UTC)
 
==== Clarify the license ====
 
See {{Bug|3115153}}; it's not good that the actual files make no mention of the license the code is released under. [[User:JesseW|JesseW]] 07:09, 22 November 2010 (UTC)
 
  
=== Kevin ===
+
=== HTTPS Migration ===
==== Change Clone and Edit 'Submit' Buttons ====
+
 
Change the text in the Clone Submit and the Edit Submit button to be clear to the editor which is being submitted. Discuss at [[ISFDB:Proposed Interface Changes#Change Clone and Edit 'Submit' Buttons]]
+
See [[Development/HTTPS]], [[User:Alvonruff/HTTPS Notes]], and [[User:Alvonruff/ISFDB Move]]. The auto-renewal of certs is still an open item, and I am generally unsatisfied with the cookie-cutter, copy-and-paste methodology I used to get the current HTTPS solution running. Some deeper expertise needs to be cultivated. --[[User:Alvonruff|Alvonruff]] ([[User talk:Alvonruff|talk]]) 11:01, 16 September 2022 (EDT)
  
 
=== MartyD ===
 
=== MartyD ===
Concentrating on bugs, clean-up/consolidation, and small features. If anything ever comes of the tagging discussion at [[ISFDB:Community Portal#Title type tags in bibliography display]], I will revisit the tagging used, too.
+
Concentrating on bugs, clean-up/consolidation, and small features. If anything ever comes of the tagging discussion at [[ISFDB:Community Portal/Archive/Archive14#Title type tags in bibliography display]], I will revisit the tagging used, too.
  
== Tips and Tricks ==
+
== Development Process ==
  
 
=== General Principles ===
 
=== General Principles ===
The ISFDB code base is over 1.5MB in size and has a number of dependencies, which are not always obvious. For example, the JavaScript generator affects dozens of Web pages and even a simple change may have unexpected side effects. For this reason, developers should follow the "if it ain't broken, don't fix it" principle. Developers should also try to address one problem at a time. If a feature or a bug fix requires mass changes, discuss it with other developers and the administrator first.
+
The ISFDB code base is over 5MB in size and has a number of dependencies, which are not always obvious. For this reason, developers should follow the "if it ain't broken, don't fix it" principle. Developers should also try to address one problem at a time. If a feature or a bug fix requires mass changes, discuss it with other developers and the administrator first.
  
 
=== Coding style ===
 
=== Coding style ===
Among the developers, there is a wide variety of backgrounds and levels of Python experience. Due to this, it's important to take care to keep the code understandable without a high level of Python-specific knowledge. Using basic structured programming constructs (i.e., ''def'', ''if'', ''while'', etc.) and simple classes rather than heavy object-orientation or more esoteric functional programming tricks is recommended. If you need to create a complex class, method or functions, you may want to discuss it with other developers and the administrator first and then document the code thoroughly.
+
Among the developers, there is a wide variety of backgrounds and levels of Python experience. Due to this, it's important to take care to keep the code understandable without a high level of Python-specific knowledge. Using basic structured programming constructs (i.e., <code>def</code>, <code>if</code>, <code>while</code>, etc.) and simple classes rather than heavy object-orientation or more esoteric functional programming tricks is recommended. If you need to create a complex class, method or functions, you may want to discuss it with other developers and the administrator first and then document the code thoroughly.
  
=== Where is '''db''' defined? ===
+
=== Where Are the Globally Scoped Variables defined? ===
Whenever '''SQLparsing.py''' is imported, a database connection is created, and assigned to the variable '''db'''. SQLparsing.py is copied by the makefiles from common/ into all the other directories, and imported by more or less everything, often multiple times. This is may be suboptimal.
+
 
 +
Almost all CGI scripts which comprise the ISFDB system have a <code>from isfdb import *</code> statement at the top of the script. Module <code>isfdb</code> defines many all-uppercase variables like <code>COPYRIGHT</code>, <code>EURO_SIGN</code>, offset values for tuples retrieved from the SQL database, etc. It also sets up <code>SESSION</code>, an object which contains session-specific information like the name of the directory that the current CGI script resides in. In addition, module <code>isfdb</code> executes <code>from localdefs import *</code>, which imports installation-specific global variables like <code>HTMLHOST</code> and <code>WIKILOC</code>. Upon import, all of these variable become available to the invoking CGI script.
 +
 
 +
ISFDB scripts which interact with the SQL database, i.e. the vast majority of them, import functions from SQLparsing. When the import occurs, the SQLparsing module creates a database connection and assigns it to the global variable <code>db</code>, which is then used by individual CGI scripts and other modules to interact with the database. SQLparsing also retrieves a list of supported languages and assigns it to the globally scoped variable <code>LANGUAGES</code>.
  
 
=== Code Format ===
 
=== Code Format ===
*The code appears to use 'TAB' instead of 'SPACE SPACE SPACE SPACE' to indent the code. (Some online python tutorials indicate a preference for one or the other.) You should use TABS for this project to indent because Python uses the indent level to define code blocks and sub steps. Mixing tabs and spaces in a File/project can cause the compiler to misunderstand where the functions and loops start and stop.
+
 
*In other ways the code should probably adhere to [http://www.python.org/dev/peps/pep-0008/ PEP 8: Style Guide for Python Code]
+
==== Indentation ====
 +
 
 +
Older ISFDB modules tend to use tabs. Newer ISFDB modules tend to use 8 spaces. A few ISFDB modules use 4 spaces. Some modules use a mix of spaces and tabs, which can cause problems, especially if and when we migrate from Python 2 to Python 3.
 +
 
 +
* For new development, use 8 spaces.
 +
* When modifying existing modules which use either spaces OR tabs, use the current indentation method.
 +
* When modifying existing modules which use a mix of spaces and tabs, change the module to use 8 spaces. This may require additional testing to ensure that nothing got broken.
 +
 
 +
==== Other Standards ====
 +
 
 +
* When modifying existing code, use the naming conventions and other standards found within the module.
 +
* For new development, use [http://www.python.org/dev/peps/pep-0008/ PEP 8: Style Guide for Python Code] unless it goes ISFDB-wide coding conventions.
 +
 
 +
=== How to Add a New Cleanup Report ===
 +
 
 +
ISFDB has three background jobs, not counting the backups:
 +
 
 +
* Nightly job. It regenerates less computationally intensive [http://www.isfdb.org/cgi-bin/mod/cleanup.cgi?1 Cleanup Reports] and takes over 5 minutes to run.
 +
* Weekly job. It regenerates all [http://www.isfdb.org/cgi-bin/stats-and-tops.cgi Statistics and Top Lists] as well as ''all'' Cleanup Reports. It takes over 20 minutes to run.
 +
* Monthly job. It regenerates cleanup reports which take a very long time to run. At this time it is only used to regenerate the "Suspected Duplicate Authors" report. The job is currently suspended because the algorithm doesn't scale well and it takes many days to complete.
 +
 
 +
If you want to add another cleanup report, use the following steps:
 +
 
 +
# Develop a SQL query to find potentially problematic records. Your query should return only one column, which should contain the record ID of a suspicious record. Any subsequent columns will be ignored by the report generator. Note that you should only retrieve one record type (titles, pubs, series, etc) per report. If you need to return multiple record types, create one report per record type.
 +
# Add a new report to the bottom of module <code>nightly/nightly_update.py</code>. Set the <code>query</code> variable to the body of the SQL statement that you created in the previous step. Invoke <code>standardReport(query, NNN)</code> where NNN is the report number of your report. To determine the value of NNN, take the last report number used and add 1. When this module is run by the nightly job, it will extract the specified record IDs and add them to the "cleanup" table in the database.
 +
# In module <code>edit/cleanup_lib.py</code>, add the name of the new report to the dictionary <code>reports</code> in function <code>reportsDict</code>. Increment the last use key to get the key for your report -- it should be the same as the report number that you created in the previous step. In the same function, add this report number to the appropriate tuple of the <code>sections</code> list. For example, if you are developing a cleanup report that affects magazines, add the report number to the <code>Magazines</code> tuple. If the report is supposed to be accessed by editors without moderator privileges, add its number to the of the <code>non_moderator</code> tuple in the same function.
 +
# In module <code>edit/cleanup_report.py</code>, create a new function called <code>functionNNN</code> where NNN is the report number describe in the last two steps. The function should take no arguments, e.g. <code>def function555()</code>. Define a SQL query that contains the same logic as the query describe in the first step except that it also limits the search to the records stored in the table "cleanup" for this report number. To do this, add the following logic to the <code>WHERE</code> clause of the SQL statement: <code>and TABLE_NAME.RECORD_ID=cleanup.record_id and cleanup.report_type=NNN and cleanup.resolved IS NULL</code>, where TABLE_NAME is the table name of the record that you are extracting, RECORD_ID is the name of the column of the record ID and NNN is the report number. Display the retrieved data using other reports as an example. Use function <code>PrintTableColumns</code> to print table columns. Use functions <code>PrintSeriesRecord</code>, <code>PrintPublicationRecord</code>, <code>PrintTitleRecord</code>, <code>PrintAuthorRecord</code>, <code>PrintPublisherRecord</code> and <code>PrintPubSeriesRecord</code> to print simple rows consisting of two columns: row number and a link to the problematic database record. These functions also support an optional third column for "Ignore this record" links. See the function definitions for the parameters that they take.
 +
 
 +
=== How to Add a new Field to Title records ===
 +
 
 +
# Create a SQL script to add the new field to the titles tables
 +
# Modify the <code>load</code> and <code>cgi2obj</code> methods of the <code>Title</code> class
 +
# Add the new field to the Edit Title modules (<code>edit/edittitle.py</code>, <code>edit/submittitle.py</code>, <code>mod/ta_update.py</code>)
 +
# Add the new field to the <code>DisplayTitleEdit</code> function in <code>biblio/viewers.py</code>
 +
# Add the new field to <code>biblio/title.py</code>
 +
# Consider whether the field needs to be displayed in the "Content" section of the "Publication" display page, similar to non-genre or graphic. If so, modify <code>biblio/pl.py</code>
 +
# Consider whether the field should appear on "Summary/Series" pages, similar to non-genre or graphic
 +
# Consider whether the new field should be added to the "New Pub" data entry form, similar to non-genre or graphic
 +
# Add mouse-over help in <code>edit/isfdblib.py</code>. If the field has also been added to "NewPub", make sure to add it to two places in <code>edit/isfdblib.py</code>, one for "Title Help" and one for "Pub Help".
 +
# Account for the new field in the following module groups, including the data entry forms, the relevant </code>viewers.py</code> functions and the filers:
 +
#* Title Merge
 +
#* Title Unmerge
 +
#* Add Variant
 +
#* Variant Title
 +
# Consider adding the new field to the "Title" section of the "Advanced Search"
 +
 
 +
=== How to Add a New External ID Type ===
 +
 
 +
# Add the requested External ID Type to the MySQL table <code>identifier_types</code>. For example, here is the command that added KBR as a new External ID Type:
 +
#* <source enclose="div" lang=mysql>INSERT INTO identifier_types (identifier_type_name, identifier_type_full_name) VALUES ('KBR', 'De Belgische Bibliografie/La Bibliographie de Belgique');</source>
 +
# If the new External ID Type links to one or more third party URL, add that URL (or URLs) to the MySQL table <code>identifier_sites</code>, one URL per command. Use "%s" for the part of the URL which will be replaced with the actual External ID at run time. Use the value of <code>identifier_type_id</code> generated by the previous command. For example, here is the command that added the URL of De Belgische Bibliografie:
 +
#* <source enclose="div" lang=mysql>INSERT INTO identifier_sites (identifier_type_id, site_position, site_url) VALUES (19, 1, 'https://opac.kbr.be/Library/doc/SYRACUSE/%s/');</source>
 +
# If applicable, add a matching linking template to the function <code>ISFDBTemplates</code> in <code>common/library.py</code>. See the comments section at the beginning of the function for details. See an existing linking template like "ASIN" for an example.
 +
 
 +
=== How to Add a New Banner Image ===
 +
 
 +
# Make sure that the new image file contains a valid JPG image
 +
# Put a copy of the new image file in the <code>css</code> subdirectory
 +
# Change the name of the new JPG file to <code>IsfdbBannerNN</code> where "NN" is 1 higher than the highest currently existing file name
 +
# Add <code>IsfdbBannerNN.jpg</code> to <code>css/Makefile</code>
 +
# In <code>common/isfdb.py</code>, find the variable which contains the number of the last IsfdbBanner file and increment it by one to match NN
  
 
=== Duplicate Functions and Duplicate Filenames ===
 
=== Duplicate Functions and Duplicate Filenames ===
WARNING — There are duplicate file names and duplicate functions. The function PrintNavBar for instance, appears in /biblio/common.py (with 5 arguments) and in /edit/isfdblib.py (with 2 arguments) and again in /mod/isfdblib.py (with no arguments). Be sure to watch your directory of the file you are editing, and you cannot count on a function in one directory behaving the same when working in another directory.
+
WARNING — There are duplicate file names and duplicate functions. The function <code>PrintNavBar</code> for instance, appears in <code>/biblio/common.py</code> (with 5 arguments) and in <code>/edit/isfdblib.py</code> (with 2 arguments) and again in <code>/mod/isfdblib.py</code> (with no arguments). Be sure to watch your directory of the file you are editing, and you cannot count on a function in one directory behaving the same when working in another directory.
  
: Indeed. When looking for "SQLwikiLinkExists" it turns out we have five of them, and rather too many "SQLparsing.py" files. We could do with some comparisons and centralisation, although this obviously has possibly far-ranging effects and would need lots of regression testing. [[User:BLongley|BLongley]]
+
: Indeed. When looking for <code>SQLwikiLinkExists</code> it turns out we have five of them, and rather too many <code>SQLparsing.py</code> files. We could do with some comparisons and centralisation, although this obviously has possibly far-ranging effects and would need lots of regression testing. [[User:BLongley|BLongley]]
  
::Files living in common are master files and are copied to the other parts of the tree during the build process. The good news is, CVS won't let you commit the others, as they don't actually exist in those directories in CVS. TortoiseCVS distinguishes them as local files with a different icon.... —[[User:MartyD|MartyD]] 20:48, 14 June 2009 (UTC)
+
::Files living in common are master files and are copied to the other parts of the tree during the build process. The good news is, CVS won't let you commit the others, as they don't actually exist in those directories in CVS. TortoiseCVS distinguishes them as local files with a different icon.... —[[User:MartyD|MartyD]] 20:48, 14 June 2009 (UTC)
  
 
:::This isn't a case of common files. This is duplicate file and function naming. [[User:Kpulliam|Kevin]] 03:25, 15 June 2009 (UTC)
 
:::This isn't a case of common files. This is duplicate file and function naming. [[User:Kpulliam|Kevin]] 03:25, 15 June 2009 (UTC)
  
:I have begun the first step in the journey to fixing the PrintNavBar duplication problem. I've created a new common/navbar.py and made all of the other directories share it. We can slowly move NavBar things into it. —[[User:MartyD|MartyD]] 21:14, 5 July 2009 (UTC)
+
:I have begun the first step in the journey to fixing the <code>PrintNavBar</code> duplication problem. I've created a new <code>common/navbar.py</code> and made all of the other directories share it. We can slowly move NavBar things into it. —[[User:MartyD|MartyD]] 21:14, 5 July 2009 (UTC)
  
 
= Related Projects =
 
= Related Projects =
  
 
* [[Solr Powered ISFDB]]
 
* [[Solr Powered ISFDB]]
 +
* [https://pastebin.com/3dk8cC9R Rough list of author countries from ISFDB database]
 +
* [https://sf.ersatzculture.com/award-charts/ Charts showing SF&F award finalists and their rating counts on Goodreads] (award data from the ISFDB)

Revision as of 11:02, 16 September 2022

ISFDB Discussion Pages and Noticeboards
Before posting to this page, consider whether one of the other discussion pages or noticeboards might suit your needs better.
If you're looking for help remembering a book title, check out the resources in our FAQ.
Please also see our Help pages.
Help desk
Questions about doing a specific task, or how to correct information when the solution is not immediately obvious.
• New post • Archives
Research Assistance
Help with bibliographic projects.
• New post • Archives
Rules and standards
Discussions about the rules and standards, as well as questions about interpretation and application of those rules.
• New post • Rules changelog • Archives
Community Portal
General discussion about anything not covered by the more specialized noticeboards to the left.
• New post • Archives
Moderator noticeboard
Get the attention of moderators regarding submission questions.
 
• New post • Archives • Cancel submission
Roadmap: For the original discussion of Roadmap 2017 see this archived section. For the current implementation status, see What's New#Roadmap 2017.



Related resources:

This page serves as the hub for discussing ISFDB-related software development.

Developers and Testers

  • MartyD — developer
  • Kpulliam — developer (of meager ability) / Tester
  • Roglo — developer (inactive since mid-2009)
  • Ahasuerus — developer, tester and installer/administrator
  • Alvonruff — currently unavailable, but has full development and administrative access
  • Marc Kupper — has full administrative access and a partial development setup
  • JesseW — developer
  • Uzume — developer, tester, etc.

The following editors are currently in the process of setting up a local copy of the application:

Software Development Process

At this time the development process works as follows:

  • A Bug, Support Request ("SR") or Feature Request ("FR") is created in SourceForge. Anyone can do it, even "anonymous".
  • FRs should be discussed on the ISFDB:Community Portal and approved by the community before the work begins. Obvious bugs can be fixed and submitted without a prior discussion.
  • Once a developer decides to work on a Bug/SR/FR, s/he identifies the scripts that are affected and lists the Bug/SR/FR along with the scripts on the Development page under "Outstanding Changes". This helps avoid effort duplication.
  • The developer makes changes on his or her development server and tests them. S/he then sends to the ISFDB administrator (Ahasuerus since 2009), who tests them on his local development server. In some cases the administrator may ask another developer to test the changes.
  • If everything works fine, the administrator commits the changes to the SourceForge repository using the SVN "commit" command, e.g.:
    • svn commit -m "FR 1099 Add Last Activity date to 'Top Contributor/Moderator/etc' lists - Part 1"
      
  • The administrator gets the latest revision number from the SourceForge repository:
    • svn info --show-item=revision -r HEAD
      
  • The administrator creates a deployable tarball file from the modified source files, e.g:
    • tar -cvf ~/patches/3.tar biblio/toptaggers.py
      
      where '3' is the revision number retrieved in the previous step
  • The administrator copies the tarball to the ISFDB server and moves it to /home/avonruff/isfdb2/, where the main copy of the source code currently resides
  • The administrator untars the tarball and types make install (or make -B install if the patch added new scripts or otherwise requires a complete rebuild)
  • The administrator gzips the tarball and moves it to the archive area
  • The administrator marks the Bug(s)/SR(s)/FR(s) as "Fixed/Completed" in SourceForge
  • The administrator moves the completed change(s) from the list of Outstanding Changes on the Development page to the "Recent Patches" sub-page. "Recent Changes" covers all builds for the current year, so it's a useful page for developers to review.

Changes and Patches

Recent Patches

Patch Archive for 2009–2019

See Development/Recent Patches for the list of changes implemented recently.

Outstanding changes

Bug or Feature Description Modules and versions Developer Tester Date Passed Patch

Planned changes

Bug or Feature Description Modules and versions Developer Tester Date Passed Patch
SR 24 Static and dynamic content cannot be "rehomed" correctly
  • TBD
Uzume

Current Activity

HTTPS Migration

See Development/HTTPS, User:Alvonruff/HTTPS Notes, and User:Alvonruff/ISFDB Move. The auto-renewal of certs is still an open item, and I am generally unsatisfied with the cookie-cutter, copy-and-paste methodology I used to get the current HTTPS solution running. Some deeper expertise needs to be cultivated. --Alvonruff (talk) 11:01, 16 September 2022 (EDT)

MartyD

Concentrating on bugs, clean-up/consolidation, and small features. If anything ever comes of the tagging discussion at ISFDB:Community Portal/Archive/Archive14#Title type tags in bibliography display, I will revisit the tagging used, too.

Development Process

General Principles

The ISFDB code base is over 5MB in size and has a number of dependencies, which are not always obvious. For this reason, developers should follow the "if it ain't broken, don't fix it" principle. Developers should also try to address one problem at a time. If a feature or a bug fix requires mass changes, discuss it with other developers and the administrator first.

Coding style

Among the developers, there is a wide variety of backgrounds and levels of Python experience. Due to this, it's important to take care to keep the code understandable without a high level of Python-specific knowledge. Using basic structured programming constructs (i.e., def, if, while, etc.) and simple classes rather than heavy object-orientation or more esoteric functional programming tricks is recommended. If you need to create a complex class, method or functions, you may want to discuss it with other developers and the administrator first and then document the code thoroughly.

Where Are the Globally Scoped Variables defined?

Almost all CGI scripts which comprise the ISFDB system have a from isfdb import * statement at the top of the script. Module isfdb defines many all-uppercase variables like COPYRIGHT, EURO_SIGN, offset values for tuples retrieved from the SQL database, etc. It also sets up SESSION, an object which contains session-specific information like the name of the directory that the current CGI script resides in. In addition, module isfdb executes from localdefs import *, which imports installation-specific global variables like HTMLHOST and WIKILOC. Upon import, all of these variable become available to the invoking CGI script.

ISFDB scripts which interact with the SQL database, i.e. the vast majority of them, import functions from SQLparsing. When the import occurs, the SQLparsing module creates a database connection and assigns it to the global variable db, which is then used by individual CGI scripts and other modules to interact with the database. SQLparsing also retrieves a list of supported languages and assigns it to the globally scoped variable LANGUAGES.

Code Format

Indentation

Older ISFDB modules tend to use tabs. Newer ISFDB modules tend to use 8 spaces. A few ISFDB modules use 4 spaces. Some modules use a mix of spaces and tabs, which can cause problems, especially if and when we migrate from Python 2 to Python 3.

  • For new development, use 8 spaces.
  • When modifying existing modules which use either spaces OR tabs, use the current indentation method.
  • When modifying existing modules which use a mix of spaces and tabs, change the module to use 8 spaces. This may require additional testing to ensure that nothing got broken.

Other Standards

  • When modifying existing code, use the naming conventions and other standards found within the module.
  • For new development, use PEP 8: Style Guide for Python Code unless it goes ISFDB-wide coding conventions.

How to Add a New Cleanup Report

ISFDB has three background jobs, not counting the backups:

  • Nightly job. It regenerates less computationally intensive Cleanup Reports and takes over 5 minutes to run.
  • Weekly job. It regenerates all Statistics and Top Lists as well as all Cleanup Reports. It takes over 20 minutes to run.
  • Monthly job. It regenerates cleanup reports which take a very long time to run. At this time it is only used to regenerate the "Suspected Duplicate Authors" report. The job is currently suspended because the algorithm doesn't scale well and it takes many days to complete.

If you want to add another cleanup report, use the following steps:

  1. Develop a SQL query to find potentially problematic records. Your query should return only one column, which should contain the record ID of a suspicious record. Any subsequent columns will be ignored by the report generator. Note that you should only retrieve one record type (titles, pubs, series, etc) per report. If you need to return multiple record types, create one report per record type.
  2. Add a new report to the bottom of module nightly/nightly_update.py. Set the query variable to the body of the SQL statement that you created in the previous step. Invoke standardReport(query, NNN) where NNN is the report number of your report. To determine the value of NNN, take the last report number used and add 1. When this module is run by the nightly job, it will extract the specified record IDs and add them to the "cleanup" table in the database.
  3. In module edit/cleanup_lib.py, add the name of the new report to the dictionary reports in function reportsDict. Increment the last use key to get the key for your report -- it should be the same as the report number that you created in the previous step. In the same function, add this report number to the appropriate tuple of the sections list. For example, if you are developing a cleanup report that affects magazines, add the report number to the Magazines tuple. If the report is supposed to be accessed by editors without moderator privileges, add its number to the of the non_moderator tuple in the same function.
  4. In module edit/cleanup_report.py, create a new function called functionNNN where NNN is the report number describe in the last two steps. The function should take no arguments, e.g. def function555(). Define a SQL query that contains the same logic as the query describe in the first step except that it also limits the search to the records stored in the table "cleanup" for this report number. To do this, add the following logic to the WHERE clause of the SQL statement: and TABLE_NAME.RECORD_ID=cleanup.record_id and cleanup.report_type=NNN and cleanup.resolved IS NULL, where TABLE_NAME is the table name of the record that you are extracting, RECORD_ID is the name of the column of the record ID and NNN is the report number. Display the retrieved data using other reports as an example. Use function PrintTableColumns to print table columns. Use functions PrintSeriesRecord, PrintPublicationRecord, PrintTitleRecord, PrintAuthorRecord, PrintPublisherRecord and PrintPubSeriesRecord to print simple rows consisting of two columns: row number and a link to the problematic database record. These functions also support an optional third column for "Ignore this record" links. See the function definitions for the parameters that they take.

How to Add a new Field to Title records

  1. Create a SQL script to add the new field to the titles tables
  2. Modify the load and cgi2obj methods of the Title class
  3. Add the new field to the Edit Title modules (edit/edittitle.py, edit/submittitle.py, mod/ta_update.py)
  4. Add the new field to the DisplayTitleEdit function in biblio/viewers.py
  5. Add the new field to biblio/title.py
  6. Consider whether the field needs to be displayed in the "Content" section of the "Publication" display page, similar to non-genre or graphic. If so, modify biblio/pl.py
  7. Consider whether the field should appear on "Summary/Series" pages, similar to non-genre or graphic
  8. Consider whether the new field should be added to the "New Pub" data entry form, similar to non-genre or graphic
  9. Add mouse-over help in edit/isfdblib.py. If the field has also been added to "NewPub", make sure to add it to two places in edit/isfdblib.py, one for "Title Help" and one for "Pub Help".
  10. Account for the new field in the following module groups, including the data entry forms, the relevant viewers.py functions and the filers:
    • Title Merge
    • Title Unmerge
    • Add Variant
    • Variant Title
  11. Consider adding the new field to the "Title" section of the "Advanced Search"

How to Add a New External ID Type

  1. Add the requested External ID Type to the MySQL table identifier_types. For example, here is the command that added KBR as a new External ID Type:
    • INSERT INTO identifier_types (identifier_type_name, identifier_type_full_name) VALUES ('KBR', 'De Belgische Bibliografie/La Bibliographie de Belgique');
      
  2. If the new External ID Type links to one or more third party URL, add that URL (or URLs) to the MySQL table identifier_sites, one URL per command. Use "%s" for the part of the URL which will be replaced with the actual External ID at run time. Use the value of identifier_type_id generated by the previous command. For example, here is the command that added the URL of De Belgische Bibliografie:
    • INSERT INTO identifier_sites (identifier_type_id, site_position, site_url) VALUES (19, 1, 'https://opac.kbr.be/Library/doc/SYRACUSE/%s/');
      
  3. If applicable, add a matching linking template to the function ISFDBTemplates in common/library.py. See the comments section at the beginning of the function for details. See an existing linking template like "ASIN" for an example.

How to Add a New Banner Image

  1. Make sure that the new image file contains a valid JPG image
  2. Put a copy of the new image file in the css subdirectory
  3. Change the name of the new JPG file to IsfdbBannerNN where "NN" is 1 higher than the highest currently existing file name
  4. Add IsfdbBannerNN.jpg to css/Makefile
  5. In common/isfdb.py, find the variable which contains the number of the last IsfdbBanner file and increment it by one to match NN

Duplicate Functions and Duplicate Filenames

WARNING — There are duplicate file names and duplicate functions. The function PrintNavBar for instance, appears in /biblio/common.py (with 5 arguments) and in /edit/isfdblib.py (with 2 arguments) and again in /mod/isfdblib.py (with no arguments). Be sure to watch your directory of the file you are editing, and you cannot count on a function in one directory behaving the same when working in another directory.

Indeed. When looking for SQLwikiLinkExists it turns out we have five of them, and rather too many SQLparsing.py files. We could do with some comparisons and centralisation, although this obviously has possibly far-ranging effects and would need lots of regression testing. BLongley
Files living in common are master files and are copied to the other parts of the tree during the build process. The good news is, CVS won't let you commit the others, as they don't actually exist in those directories in CVS. TortoiseCVS distinguishes them as local files with a different icon.... —MartyD 20:48, 14 June 2009 (UTC)
This isn't a case of common files. This is duplicate file and function naming. Kevin 03:25, 15 June 2009 (UTC)
I have begun the first step in the journey to fixing the PrintNavBar duplication problem. I've created a new common/navbar.py and made all of the other directories share it. We can slowly move NavBar things into it. —MartyD 21:14, 5 July 2009 (UTC)

Related Projects