Skip to content
Snippets Groups Projects
Commit 5c54be20 authored by Daniel Lyons's avatar Daniel Lyons
Browse files

Initial import of Go version of contacts-wrest

parent b191f52a
No related branches found
No related tags found
2 merge requests!1452Merge 2.8.2 to main,!1421Go contacts wrest
module ssa/contacts_wrest
go 1.18
require (
github.com/fsnotify/fsnotify v1.5.4 // indirect
github.com/go-sql-driver/mysql v1.7.1 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/magiconair/properties v1.8.6 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pelletier/go-toml/v2 v2.0.5 // indirect
github.com/spf13/afero v1.9.2 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.13.0 // indirect
github.com/subosito/gotenv v1.4.1 // indirect
gitlab.nrao.edu/ssa/gocapo v0.0.0-20230307183307-91ffd4356566 // indirect
golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8 // indirect
golang.org/x/text v0.3.7 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
package main
import (
wrest "ssa/contacts_wrest/pkg/contacts_wrest"
)
func main() {
wrest.RetrieveContacts("13B-014")
}
//
//
//def main():
//"""
//Retrieves contact email addresses from the OPT and PST database for a given project
//
//:return:
//"""
//parser = argparse.ArgumentParser(description="Retrieve contact email addresses from the OPT and PST database")
//parser.add_argument("project_code", help="Project code of the project to look up the contactable authors for")
//ns = parser.parse_args()
//
//# Retrieve project contacts' email addresses freom my.nrao.edu
//emails = ProjectContactsWrester(ns.project_code).retrieve_contacts()
//
//# Display them
//json.dump(emails, sys.stdout)
/*
* Copyright (C) 2022 Associated Universities, Inc. Washington DC, USA.
*
* This file is part of NRAO Workspaces.
*
* Workspaces is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Workspaces is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Workspaces. If not, see <https://www.gnu.org/licenses/>.
*/
package wrest
import (
"database/sql"
"fmt"
"gitlab.nrao.edu/ssa/gocapo/capo/config"
"gitlab.nrao.edu/ssa/gocapo/helpers"
"os"
"strconv"
"strings"
)
type DbInfo struct {
Host string
Port int
User string
Password string
Dbname string
IsSsl bool
}
func InitDbInfo() DbInfo {
return DbInfo{
Host: "",
Port: 0,
User: "",
Password: "",
Dbname: "",
IsSsl: false,
}
}
/**
* Pull the login information for the database from a properties file
*
* @param db_info a DbInfo type with information to connect to the database
* @return a DbInfo type holding db_info's data with the User and Password
* fields populated
**/
func getDbLoginFromProperties(connectionInfo DbInfo, prefix string, urlName string) DbInfo {
prop, err := config.InitConfig(os.Getenv("CAPO_PROFILE"), helpers.DefaultCapoPath)
if err != nil {
println("Unable to initialize the CAPO configuration!")
panic(err)
}
settings := prop.SettingsForPrefix(prefix)
connectionInfo.User = settings.GetString("username")
connectionInfo.Password = settings.GetString("password")
url := settings.GetString(urlName)
fmt.Printf("Got username %v and url %v\n", connectionInfo.User, url)
url = strings.TrimPrefix(url, "jdbc:postgresql://")
url = strings.TrimPrefix(url, "jdbc:mysql://")
splitUrl := strings.Split(url, "/")
connectionInfo.Host = splitUrl[0]
connectionInfo.Dbname = splitUrl[1]
splitHostPort := strings.Split(connectionInfo.Host, ":")
connectionInfo.Host = splitHostPort[0]
if len(splitHostPort) > 1 {
connectionInfo.Port, _ = strconv.Atoi(splitHostPort[1])
} else {
connectionInfo.Port = 5432
}
connectionInfo.IsSsl = false
return connectionInfo
}
// GetConnection
// Establish a connection to the database
func GetPostgresConnection(dbInfo DbInfo, prefix string, urlName string) *sql.DB {
// Get db info and build string to get connection
dbInfo = getDbLoginFromProperties(dbInfo, prefix, urlName)
sslMode := "disable"
if dbInfo.IsSsl {
sslMode = "require"
}
connInfo := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=%s", dbInfo.Host, dbInfo.Port, dbInfo.User, dbInfo.Password, dbInfo.Dbname, sslMode)
db, err := sql.Open("postgres", connInfo)
if err != nil {
fmt.Printf("Unable to open the database connection to %s@%s!\n", dbInfo.Dbname, dbInfo.Host)
panic(err)
}
err = db.Ping()
if err != nil {
fmt.Printf("Unable to ping the database connection for %s@%s\n", dbInfo.Dbname, dbInfo.Host)
panic(err)
}
return db
}
func GetMySQLConnection(dbInfo DbInfo, prefix string, urlName string) *sql.DB {
// Get db info and build string to get connection
dbInfo = getDbLoginFromProperties(dbInfo, prefix, urlName)
connInfo := fmt.Sprintf("%s:%s@tcp(%s)/%s", dbInfo.User, dbInfo.Password, dbInfo.Host, dbInfo.Dbname)
db, err := sql.Open("mysql", connInfo)
if err != nil {
fmt.Printf("Unable to open the database connection to %s@%s!\n", dbInfo.Dbname, dbInfo.Host)
panic(err)
}
err = db.Ping()
if err != nil {
fmt.Printf("Unable to ping the database connection for %s@%s\n", dbInfo.Dbname, dbInfo.Host)
panic(err)
}
return db
}
/*
* Copyright (C) 2022 Associated Universities, Inc. Washington DC, USA.
*
* This file is part of NRAO Workspaces.
*
* Workspaces is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Workspaces is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Workspaces. If not, see <https://www.gnu.org/licenses/>.
*/
/*
Package wrest
Looks up contact authors for a given project.
If this tool isn't working, the same information can be obtained by logging
into the OPT, opening the project in question, and clicking on the coauthors.
*/
package wrest
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
_ "github.com/lib/pq"
"gitlab.nrao.edu/ssa/gocapo/capo/config"
"strings"
)
//getCapoConfig
/**
* Create a CapoConfig instance from a CAPO property file
*
* @param input A CapoInput instance encapsulating the requested profile and path
* @return a CapoConfig instance
**/
func getCapoConfig(capoProfile string, capoPath string) config.CapoConfig {
properties, err := config.InitConfig(capoProfile, capoPath)
if err != nil {
println("Unable to load CAPO properties")
panic(err)
}
return properties
}
// Retrieve the contacts
func RetrieveContacts(projectCode string) {
// Get the designated contact(s) for this project.
// step 1: retrieve the contact author globalIDs from the OPT
//var globalIds = getGlobalIds(projectCode)
globalIds := RetrieveGlobalIds(projectCode)
for _, globalId := range globalIds {
fmt.Printf("Got global ID %v\n", globalId)
}
// step 2: look up email addresses in the my.nrao.edu database
emails := RetrieveEmailsForGlobalIds(globalIds)
for _, email := range emails {
fmt.Printf("Got email %v\n", email)
}
}
func RetrieveGlobalIds(projectCode string) []int {
// connect to the database
connectionInfo := InitDbInfo()
connection := GetPostgresConnection(connectionInfo, "edu.nrao.ssa.project.db", "url")
// build the query
query := `select globalid
from project
join projectauthor p on project.pi = p.id
where projectcode = $1 and receivesemail
union
select globalid
from project
join projectauthor p on project.contactauthor = p.id
where projectcode = $1 and receivesemail
union
select globalid
from project
join coauthors c on project.id = c.project_id
join projectauthor p on c.projectauthor_id = p.id
where projectcode = $1 and receivesemail`
// close the database when we're done
defer func(connection *sql.DB) {
err := connection.Close()
if err != nil {
println("Unable to close the database connection!")
panic(err)
}
}(connection)
rows, err := connection.Query(query, projectCode)
if err != nil {
println("Unable to execute the project code query!")
panic(err)
}
// this is a guess; the append method will extend it as necessary
globalIds := make([]int, 0)
defer rows.Close()
for rows.Next() {
globalId := 0
err := rows.Scan(&globalId)
if err != nil {
println("Unable to scan the global ID from the query!")
panic(err)
}
globalIds = append(globalIds, globalId)
}
return globalIds
}
func RetrieveEmailsForGlobalIds(globalIds []int) []string {
// Now that we have the global IDs, we can use them to look up contacts' email addresses
connectionInfo := InitDbInfo()
connection := GetMySQLConnection(connectionInfo, "my.nrao.jdbc", "URL")
// build the IN list, this is so gross
inClause := strings.Trim(strings.Join(strings.Fields(fmt.Sprint(globalIds)), ","), "[]")
// build the query
query := fmt.Sprintf(`select email
from email
where person_id IN (%s) and defaultEmail`, inClause)
// close the database when we're done
defer func(connection *sql.DB) {
err := connection.Close()
if err != nil {
println("Unable to close the database connection!")
panic(err)
}
}(connection)
rows, err := connection.Query(query)
if err != nil {
println("Unable to execute the project code query!")
panic(err)
}
emails := make([]string, 0)
defer rows.Close()
for rows.Next() {
var email string
err := rows.Scan(&email)
if err != nil {
println("Unable to scan the global ID from the query!")
panic(err)
}
emails = append(emails, email)
}
return emails
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment