~netlandish/links

19f3da7f5aeebde1548dcb5dbe0d4502e053c144 — Peter Sanchez 20 days ago 36d70c8
Adding tags support to pinboard import
2 files changed, 56 insertions(+), 3 deletions(-)

M core/import.go
M models/org_link.go
M core/import.go => core/import.go +40 -1
@@ 40,6 40,7 @@ type importObj interface {
	GetHash() string
	GetTitle() string
	GetDescription() string
	GetTags() []string
	IsPublic() bool
	IsUnread() bool
	IsNote() bool


@@ 105,6 106,10 @@ func (p pinBoardObj) IsUnread() bool {
	return p.ToRead == "yes"
}

func (p pinBoardObj) GetTags() []string {
	return strings.Split(strings.TrimSpace(p.Tags), " ")
}

// Especific html object representation, used by Safari and Chrome
type htmlObj struct {
	Title string


@@ 154,6 159,10 @@ func (h htmlObj) IsUnread() bool {
	return false
}

func (h htmlObj) GetTags() []string {
	return []string{}
}

// This adapter struct is used to wrap a slice [n:m]
// of pinBoardObj or htmlObj and pass it
// as parameter to the importer functions


@@ 264,9 273,13 @@ func processOrgLinks(obj importObj, baseURLMap map[string]int,

	var linkType int
	if obj.IsNote() {
		// Hash is set in processBaseURLs
		linkType = models.NoteType
	} else {
		linkType = models.OrgLinkType
		if obj.GetHash() == "" {
			obj.SetHash(ksuid.New().String())
		}
	}

	return &models.OrgLink{


@@ 286,6 299,7 @@ func processOrgLinks(obj importObj, baseURLMap map[string]int,
func importOrgLinks(ctx context.Context, objAdapter *importAdapter, baseURLMap map[string]int,
	org *models.Organization, user *models.User, billEnabled bool) error {
	orgLinks := make([]*models.OrgLink, 0)
	hashTags := make(map[string][]string)

	switch objAdapter.GetType() {
	case pinBoardType:


@@ 293,6 307,7 @@ func importOrgLinks(ctx context.Context, objAdapter *importAdapter, baseURLMap m
			link := processOrgLinks(obj, baseURLMap, org, user, billEnabled)
			if link != nil {
				orgLinks = append(orgLinks, link)
				hashTags[link.Hash] = obj.GetTags()
			}
		}
	case htmlType:


@@ 300,13 315,37 @@ func importOrgLinks(ctx context.Context, objAdapter *importAdapter, baseURLMap m
			link := processOrgLinks(obj, baseURLMap, org, user, billEnabled)
			if link != nil {
				orgLinks = append(orgLinks, link)
				hashTags[link.Hash] = obj.GetTags()
			}
		}
	}
	if len(orgLinks) == 0 {
		return nil
	}
	return models.OrgLinkStoreBatch(ctx, orgLinks)
	err := models.OrgLinkStoreBatch(ctx, orgLinks)
	if err != nil {
		return err
	}

	// Process tags
	for _, link := range orgLinks {
		tags, ok := hashTags[link.Hash]
		if !ok {
			tags = []string{}
		}
		if len(tags) > 0 {
			tagIDs, err := links.ProcessTags(ctx, tags)
			if err != nil {
				return err
			}
			err = models.CreateBatchTagLinks(ctx, link.ID, tagIDs)
			if err != nil {
				return err
			}
		}

	}
	return nil
}

func ImportFromPinBoard(c echo.Context, src multipart.File,

M models/org_link.go => models/org_link.go +16 -2
@@ 274,10 274,24 @@ func OrgLinkStoreBatch(ctx context.Context, links []*OrgLink) error {
			batch = batch.Values(link.Title, link.URL, link.Description, link.BaseURLID, link.OrgID,
				link.UserID, link.Visibility, link.Hash, link.Type, link.Unread)
		}
		_, err := batch.
		rows, err := batch.
			Suffix(`RETURNING id`).
			PlaceholderFormat(sq.Dollar).
			RunWith(tx).
			ExecContext(ctx)
			QueryContext(ctx)
		if err != nil {
			return err
		}

		defer rows.Close()

		// Add ID's to new entries
		for _, link := range links {
			rows.Next()
			if err = rows.Scan(&link.ID); err != nil {
				return err
			}
		}
		return err
	})
	return err