grim/youtrack-import

a90131f168a3
Parents 33ea22a7724f
Children 15b75b07a58a
A first pass at getting attachments imported from trac
--- a/trac/tickets.go Wed Jul 08 05:40:55 2020 -0500
+++ b/trac/tickets.go Mon Jul 27 21:13:18 2020 -0500
@@ -1,8 +1,12 @@
package trac
import (
+ "crypto/sha1"
"database/sql"
"fmt"
+ "os"
+ "path/filepath"
+ "regexp"
"strings"
"keep.imfreedom.org/grim/youtrack-import/youtrack"
@@ -27,8 +31,9 @@
Description string `db:"description"`
Keywords sql.NullString `db:"keywords"`
- Changes []ticketChange
- Customs []ticketCustom
+ Changes []*ticketChange
+ Customs []*ticketCustom
+ Attachments []*ticketAttachment
}
type ticketChange struct {
@@ -43,7 +48,17 @@
type ticketCustom struct {
Ticket int `db:"ticket"`
Name sql.NullString `db:"name"`
- Value sql.NullString `db`
+ Value sql.NullString `db:"value"`
+}
+
+type ticketAttachment struct {
+ Filename string `db:"filename"`
+ Size int64 `db:"size"`
+ Time int64 `db:"time"`
+ Description sql.NullString `db:"description"`
+ Author string `db:"author"`
+
+ path string
}
var (
@@ -71,6 +86,11 @@
"minor": "Normal",
"trivial": "Minor",
}
+
+ // trac uses a crap regex for extensions that's missing - among other
+ // things, so we just use the same regex to figure out the extension for
+ // attachments.
+ attachmentRegex = regexp.MustCompile(`\.[A-Za-z0-9]+$`)
)
func (t *ticket) toYoutrack(users map[string]*youtrack.User, unknownUser string) (*youtrack.Issue, error) {
@@ -178,6 +198,12 @@
issue.Comments = append(issue.Comments, comment)
}
+ // add all of the attachments
+ issue.Attachments = make([]*youtrack.Attachment, len(t.Attachments))
+ for idx, attachment := range t.Attachments {
+ issue.Attachments[idx] = attachment.toYouTrack(t, users, unknownUser)
+ }
+
return issue, nil
}
@@ -210,6 +236,11 @@
if err != nil {
return nil, err
}
+
+ // Load all attachments
+ if err := e.loadAttachments(ticket, users, unknownUser); err != nil {
+ return nil, err
+ }
}
issues := make([]*youtrack.Issue, len(tickets))
@@ -224,3 +255,58 @@
return issues, nil
}
+
+func (e *environment) loadAttachments(t *ticket, users map[string]*youtrack.User, unknownUser string) error {
+ err := e.db.Select(
+ &t.Attachments,
+ `SELECT
+ filename, size, time, description, author
+ FROM trac_pidgin.attachment
+ WHERE id=$1 AND type='ticket'
+ ORDER BY time ASC`,
+ t.ID,
+ )
+ if err != nil {
+ return err
+ }
+
+ // we figure out all the filenames here as we have the environment which we
+ // need to figure out the path.
+ for _, attachment := range t.Attachments {
+ // figure out the path for the filename
+ parent_sum := fmt.Sprintf("%02x", sha1.Sum([]byte(fmt.Sprintf("%d", t.ID))))
+ filename_sum := fmt.Sprintf("%02x", sha1.Sum([]byte(attachment.Filename)))
+ ext := attachmentRegex.Find([]byte(attachment.Filename))
+
+ attachment.path = filepath.Join(
+ e.path,
+ "files",
+ "attachments",
+ "ticket",
+ parent_sum[:3],
+ parent_sum,
+ filename_sum+string(ext),
+ )
+ }
+
+ return nil
+}
+
+func (ta *ticketAttachment) toYouTrack(t *ticket, users map[string]*youtrack.User, unknownUser string) *youtrack.Attachment {
+ // map the owner
+ author := mapUser(ta.Author, unknownUser, users)
+
+ // create the youtrack attachment
+ a := youtrack.NewAttachment(t.ID, author, convertTime(ta.Time))
+
+ // open the file from the attachment which is already an absolute path on
+ // disk.
+ file, err := os.Open(ta.path)
+ if err != nil {
+ panic(err)
+ }
+
+ a.AddFile(file, ta.Filename)
+
+ return a
+}