start importer from disqus

This commit is contained in:
Eugene
2017-12-24 02:43:56 -06:00
parent 5a1577d7db
commit 3fa4ab418d
6 changed files with 222 additions and 4 deletions
+3 -1
View File
@@ -3,4 +3,6 @@
target
/logs/
/target/
/var/
/var/
debug
debug.test
+98
View File
@@ -0,0 +1,98 @@
package migrator
import (
"encoding/xml"
"io"
"io/ioutil"
"log"
"time"
"github.com/pkg/errors"
"github.com/umputun/remark/app/store"
)
// Disqus implements Importer from disqus xml
type Disqus struct {
DataStore store.Interface
}
type disqusXML struct {
Threads []disqusThread `xml:"thread"`
Comments []disqusComment `xml:"post"`
}
type disqusThread struct {
UID string `xml:"id,attr"`
Forum string `xml:"forum"`
Link string `xml:"link"`
Title string `xml:"title"`
Message string `xml:"message"`
CreateAt time.Time `xml:"createdAt"`
AuthorNmae string `xml:"author>name"`
AuthorEmail string `xml:"author>email"`
Anonymous bool `xml:"author>isAnonymous"`
IP string `xml:"ipAddress"`
Closed bool `xml:"isClosed"`
Deleted bool `xml:"isDeleted"`
}
type disqusComment struct {
UID string `xml:"id,attr"`
ID string `xml:"id"`
Message string `xml:"message"`
CreatedAt time.Time `xml:"createdAt"`
AuthorEmail string `xml:"author>email"`
AuthorName string `xml:"author>name"`
AuthorUserName string `xml:"author>username"`
IP string `xml:"ipAddress"`
Tid uid `xml:"thread"`
Pid uid `xml:"parent"`
}
type uid struct {
Val string `xml:"id,attr"`
}
// Import from disqus and save to store
func (d Disqus) Import(r io.Reader) (err error) {
data, err := ioutil.ReadAll(r)
if err != nil {
return errors.Wrap(err, "failed to read data")
}
dxml := disqusXML{}
if err = xml.Unmarshal(data, &dxml); err != nil {
return errors.Wrap(err, "can't unmarshal disqus xml")
}
failed := 0
for _, c := range d.convert(dxml) {
if _, err = d.DataStore.Create(c); err != nil {
failed++
}
}
if failed > 0 {
return errors.Errorf("failed to save %d comments", failed)
}
return nil
}
func (d Disqus) convert(dxml disqusXML) (comments []store.Comment) {
postsMap := map[string]string{} // tid:url
log.Printf("[DEBUG] convert %d posts, %d comments", len(dxml.Threads), len(dxml.Comments))
for _, thread := range dxml.Threads {
postsMap[thread.UID] = thread.Link
}
for _, comment := range dxml.Comments {
c := store.Comment{
ID: comment.ID,
Locator: store.Locator{URL: postsMap[comment.Tid.Val]},
User: store.User{ID: comment.AuthorUserName, Name: comment.AuthorName, IP: comment.IP},
Text: comment.Message,
Timestamp: comment.CreatedAt,
ParentID: comment.Pid.Val,
}
comments = append(comments, c)
}
return comments
}
+111
View File
@@ -0,0 +1,111 @@
package migrator
import (
"strings"
"testing"
"github.com/stretchr/testify/assert"
)
func TestA(t *testing.T) {
d := Disqus{}
err := d.Import(strings.NewReader(xmlTest))
assert.Nil(t, err)
}
var xmlTest = `
<?xml version="1.0" encoding="utf-8"?>
<disqus xmlns="http://disqus.com" xmlns:dsq="http://disqus.com/disqus-internals" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://disqus.com/api/schemas/1.0/disqus.xsd http://disqus.com/api/schemas/1.0/disqus-internals.xsd">
<thread dsq:id="247918464">
<id/>
<forum>radiot</forum>
<category dsq:id="707279"/>
<link>http://radio-t.umputun.com/2011/03/229_8880.html</link>
<title>Радио-Т: Радио-Т 229</title>
<message/>
<createdAt>2011-03-07T20:46:25Z</createdAt>
<author>
<email>umputun@gmail.com</email>
<name>Umputun</name>
<isAnonymous>false</isAnonymous>
<username>umputun</username>
</author>
<ipAddress>98.212.28.115</ipAddress>
<isClosed>false</isClosed>
<isDeleted>false</isDeleted>
</thread>
<thread dsq:id="247937687">
<id>http://www.radio-t.com/p/2011/03/05/podcast-229/</id>
<forum>radiot</forum>
<category dsq:id="707279"/>
<link>https://radio-t.com/p/2011/03/05/podcast-229/</link>
<title>Радио-Т: Радио-Т 229</title>
<message/>
<createdAt>2011-03-07T21:17:17Z</createdAt>
<author>
<email>umputun@gmail.com</email>
<name>Umputun</name>
<isAnonymous>false</isAnonymous>
<username>umputun</username>
</author>
<ipAddress>80.250.214.235</ipAddress>
<isClosed>true</isClosed>
<isDeleted>false</isDeleted>
</thread>
<post dsq:id="299619020">
<id>3565798471341011339</id>
<message>
<![CDATA[<p>Недавно посмотрел фильм про Джобса и Aple. Тот он еще был перец. <a href="http://alex-bestbusiness.com/" rel="nofollow noopener" title="http://alex-bestbusiness.com/">http://alex-bestbusiness.com/</a></p>]]>
</message>
<createdAt>2011-08-31T15:16:29Z</createdAt>
<isDeleted>false</isDeleted>
<isSpam>false</isSpam>
<author>
<email/>
<name>Alexander Puzatykh</name>
<isAnonymous>false</isAnonymous>
<username>facebook-1787732238</username>
</author>
<ipAddress>178.234.205.125</ipAddress>
<thread dsq:id="247937687"/>
</post>
<post dsq:id="299744309">
<id>3029154520436241933</id>
<message>
<![CDATA[<p>Microsoft показал проводник Windows 8 с ленточным интерфейсом.</p><p><a href="http://blogs.msdn.com/b/b8/archive/2011/08/29/improvements-in-windows-explorer.aspx" rel="nofollow noopener" title="http://blogs.msdn.com/b/b8/archive/2011/08/29/improvements-in-windows-explorer.aspx">http://blogs.msdn.com/b/b8/...</a> </p>]]>
</message>
<createdAt>2011-08-31T17:44:22Z</createdAt>
<isDeleted>false</isDeleted>
<isSpam>false</isSpam>
<author>
<email>mihail.merkulov@gmail.com</email>
<name>mikhailmerkulov</name>
<isAnonymous>false</isAnonymous>
<username>mikhailmerkulov</username>
</author>
<ipAddress>195.234.75.139</ipAddress>
<thread dsq:id="247937687"/>
</post>
<post dsq:id="299986072">
<id>6580890074280459209</id>
<message>
<![CDATA[<p>Google App Engine скоро выходит из превью статуса.</p><p>Сейчас письмо пришло от гугла.</p><p>Для платных приложений использущих High Replication Datastore (HRD) будет 99.95% uptime SLA.<br>Будут Премьер аккаунты за 500 баксов/месяц с оперативной поддержкой и любым количеством приложений на аккаунте (+ плата за потребленные ресурсы).<br>В связи с переходом на новую систему оплаты, обещают снизить бесплатные квоты.<br>Всем кто включит биллинг до 31 октября, обещают 50 баксов :)</p>]]>
</message>
<createdAt>2011-08-31T22:48:43Z</createdAt>
<isDeleted>false</isDeleted>
<isSpam>false</isSpam>
<author>
<email>unikier@gmail.com</email>
<name>Dmitry Shapoval</name>
<isAnonymous>false</isAnonymous>
<username>google-74b9e7568ef6860e93862c5d7752b657</username>
</author>
<ipAddress>89.113.25.139</ipAddress>
<thread dsq:id="247937687"/>
</post>
</disqus>
`
+8
View File
@@ -0,0 +1,8 @@
package migrator
import "io"
// Importer defines interface to convert posts from external sources
type Importer interface {
Import(r io.Reader) error
}
+1 -2
View File
@@ -4,11 +4,10 @@ import (
"encoding/json"
"fmt"
"log"
"sort"
"strings"
"time"
"sort"
"github.com/boltdb/bolt"
"github.com/pkg/errors"
)
+1 -1
View File
@@ -8,7 +8,7 @@ import (
"time"
)
// Comment represents a single comment with optinal reference to its parent
// Comment represents a single comment with optional reference to its parent
type Comment struct {
ID string `json:"id"`
ParentID string `json:"pid"`