grim/youtrack-import
Clone
Summary
Browse
Changes
Graph
Use the built in mime stuff to figure out the content type for attachments
2020-01-14, Gary Kramlich
4763018b25c8
Use the built in mime stuff to figure out the content type for attachments
package
youtrack
import
(
"bytes"
"encoding/xml"
"fmt"
"net/http"
"time"
)
type
Issue
struct
{
Number
int
`yt:"numberInProject"`
Summary
string
`yt:"summary"`
Description
string
`yt:"description"`
Created
time
.
Time
`yt:"created"`
Updated
time
.
Time
`yt:"updated"`
UpdatedBy
string
`yt:"updaterName"`
Resolved
time
.
Time
`yt:"resolved"`
Reporter
string
`yt:"reporter"`
Assignee
string
Voters
[]
string
`yt:"voterName"`
Watchers
[]
string
`yt:"watcherName"`
PermittedGroup
string
`yt:"permittedGroup"`
Markdown
bool
Version
string
Subsystem
string
Priority
string
`yt:"priority"`
Type
string
`yt:"type"`
State
string
`yt:"state"`
Comments
[]
Comment
Attachments
[]
*
Attachment
}
func
(
i
*
Issue
)
encode
()
xmlIssue
{
x
:=
xmlIssue
{}
// required fields
x
.
AddField
(
"numberInProject"
,
fmt
.
Sprintf
(
"%d"
,
i
.
Number
))
x
.
AddField
(
"summary"
,
i
.
Summary
)
x
.
AddField
(
"reporterName"
,
i
.
Reporter
)
x
.
AddField
(
"Assignee"
,
i
.
Assignee
)
x
.
AddField
(
"Type"
,
i
.
Type
)
x
.
AddField
(
"Priority"
,
i
.
Priority
)
x
.
AddField
(
"State"
,
i
.
State
)
// optional fields
if
i
.
Markdown
{
x
.
AddField
(
"markdown"
,
"true"
)
}
if
!
i
.
Created
.
IsZero
()
{
x
.
AddField
(
"created"
,
formatTimeString
(
i
.
Created
))
}
if
i
.
Description
!=
""
{
x
.
AddField
(
"description"
,
i
.
Description
)
}
if
!
i
.
Updated
.
IsZero
()
{
x
.
AddField
(
"updated"
,
formatTimeString
(
i
.
Updated
))
}
if
i
.
UpdatedBy
!=
""
{
x
.
AddField
(
"updaterName"
,
i
.
UpdatedBy
)
}
if
!
i
.
Resolved
.
IsZero
()
{
x
.
AddField
(
"resolved"
,
fmt
.
Sprintf
(
"%d"
,
i
.
Resolved
.
Unix
()))
}
if
len
(
i
.
Voters
)
>
0
{
x
.
AddFieldSlice
(
"voterName"
,
i
.
Voters
)
}
if
len
(
i
.
Watchers
)
>
0
{
x
.
AddFieldSlice
(
"watcherName"
,
i
.
Watchers
)
}
if
i
.
PermittedGroup
!=
""
{
x
.
AddField
(
"permittedGroup"
,
i
.
PermittedGroup
)
}
if
i
.
Version
!=
""
{
x
.
AddField
(
"Fix Versions"
,
i
.
Version
)
}
if
i
.
Subsystem
!=
""
{
x
.
AddField
(
"Subsystem"
,
i
.
Subsystem
)
}
sortComments
(
i
.
Comments
)
for
_
,
c
:=
range
i
.
Comments
{
x
.
AddComment
(
c
.
Author
,
c
.
Text
,
c
.
Created
,
c
.
Updated
,
c
.
Markdown
)
}
return
x
}
func
(
c
*
Client
)
importIssuesRange
(
p
*
Project
,
s
,
e
int
)
error
{
issues
:=
&
xmlIssues
{}
issues
.
Issues
=
make
([]
xmlIssue
,
e
-
s
)
for
i
:=
s
;
i
<
e
;
i
++
{
issues
.
Issues
[
i
-
s
]
=
p
.
Issues
[
i
].
encode
()
}
// convert the datastructure to an xml string
data
,
err
:=
xml
.
Marshal
(
issues
)
if
err
!=
nil
{
return
err
}
// create the reader for the put request
putBody
:=
bytes
.
NewReader
(
data
)
resp
,
err
:=
c
.
xmlRequest
(
http
.
MethodPut
,
c
.
uri
+
"/import/"
+
p
.
ID
+
"/issues"
,
putBody
,
)
if
err
!=
nil
{
return
err
}
defer
resp
.
Body
.
Close
()
return
c
.
validateXmlImportReport
(
[]
int
{
http
.
StatusOK
,
http
.
StatusBadRequest
},
resp
,
)
}
func
(
c
*
Client
)
ImportIssues
(
p
*
Project
)
error
{
r
:=
10
for
s
:=
0
;
s
<
len
(
p
.
Issues
);
s
+=
r
{
e
:=
s
+
r
if
e
>
len
(
p
.
Issues
)
{
e
=
len
(
p
.
Issues
)
}
fmt
.
Printf
(
"importing issues %d-%d ... "
,
s
,
e
-
1
)
if
err
:=
c
.
importIssuesRange
(
p
,
s
,
e
);
err
!=
nil
{
fmt
.
Printf
(
"failed.\n"
)
return
err
}
fmt
.
Printf
(
"done.\n"
)
}
return
nil
}