import.go (view raw)
1//
2// Copyright (c) 2019 Ted Unangst <tedu@tedunangst.com>
3//
4// Permission to use, copy, modify, and distribute this software for any
5// purpose with or without fee is hereby granted, provided that the above
6// copyright notice and this permission notice appear in all copies.
7//
8// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
16package main
17
18import (
19 "encoding/json"
20 "fmt"
21 "io/ioutil"
22 "log"
23 "os"
24 "sort"
25 "strings"
26 "time"
27)
28
29func importMain(username, flavor, source string) {
30 switch flavor {
31 case "twitter":
32 importTwitter(username, source)
33 default:
34 log.Fatal("unknown source flavor")
35 }
36}
37
38func importTwitter(username, source string) {
39 user, err := butwhatabout(username)
40 if err != nil {
41 log.Fatal(err)
42 }
43
44 type Tweet struct {
45 ID_str string
46 Created_at string
47 Full_text string
48 In_reply_to_screen_name string
49 Entities struct {
50 Hashtags []struct {
51 Text string
52 }
53 Media []struct {
54 Url string
55 Media_url string
56 }
57 Urls []struct {
58 Url string
59 Expanded_url string
60 }
61 }
62 date time.Time
63 text string
64 }
65
66 var tweets []*Tweet
67 fd, err := os.Open(source + "/tweet.js")
68 if err != nil {
69 log.Fatal(err)
70 }
71 fd.Seek(25, 0)
72 dec := json.NewDecoder(fd)
73 err = dec.Decode(&tweets)
74 if err != nil {
75 log.Fatalf("error parsing json: %s", err)
76 }
77 fd.Close()
78 for _, t := range tweets {
79 t.date, _ = time.Parse("Mon Jan 02 15:04:05 -0700 2006", t.Created_at)
80 }
81 sort.Slice(tweets, func(i, j int) bool {
82 return tweets[i].date.Before(tweets[j].date)
83 })
84 for _, t := range tweets {
85 what := "honk"
86 if t.In_reply_to_screen_name != "" {
87 what = "tonk"
88 }
89 audience := []string{thewholeworld}
90 xid := fmt.Sprintf("%s/%s/%s", user.URL, honkSep, xfiltrate())
91 honk := Honk{
92 UserID: user.ID,
93 Username: user.Name,
94 What: what,
95 Honker: user.URL,
96 XID: xid,
97 Date: t.date,
98 Format: "markdown",
99 Audience: audience,
100 Convoy: "data:,acoustichonkytonk-" + xfiltrate(),
101 Public: true,
102 Whofore: 2,
103 }
104 noise := t.Full_text
105 for _, r := range t.Entities.Urls {
106 noise = strings.Replace(noise, r.Url, r.Expanded_url, -1)
107 }
108 for _, m := range t.Entities.Media {
109 u := m.Media_url
110 idx := strings.LastIndexByte(u, '/')
111 u = u[idx+1:]
112 fname := fmt.Sprintf("%s/tweet_media/%s-%s", source, t.ID_str, u)
113 data, err := ioutil.ReadFile(fname)
114 if err != nil {
115 log.Printf("error reading media: %s", fname)
116 continue
117 }
118 newurl := fmt.Sprintf("https://%s/d/%s", serverName, u)
119
120 fileid, err := savefile(u, u, u, newurl, "image/jpg", true, data)
121 if err != nil {
122 log.Printf("error saving media: %s", fname)
123 continue
124 }
125 donk := &Donk{
126 FileID: fileid,
127 }
128 honk.Donks = append(honk.Donks, donk)
129 noise = strings.Replace(noise, m.Url, "", -1)
130 }
131 for _, ht := range t.Entities.Hashtags {
132 honk.Onts = append(honk.Onts, "#"+ht.Text)
133 }
134 honk.Noise = noise
135 savehonk(&honk)
136 }
137}