diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/grils/grils.go | 32 | ||||
-rw-r--r-- | modules/lists/lists.go | 249 |
2 files changed, 237 insertions, 44 deletions
diff --git a/modules/grils/grils.go b/modules/grils/grils.go index 0ba4c61..0fac5df 100644 --- a/modules/grils/grils.go +++ b/modules/grils/grils.go | |||
@@ -4,9 +4,7 @@ import ( | |||
4 | "fmt" | 4 | "fmt" |
5 | "log" | 5 | "log" |
6 | "net/http" | 6 | "net/http" |
7 | "regexp" | ||
8 | "strconv" | 7 | "strconv" |
9 | "strings" | ||
10 | "time" | 8 | "time" |
11 | 9 | ||
12 | "fagott.pw/charakterin" | 10 | "fagott.pw/charakterin" |
@@ -20,20 +18,6 @@ import ( | |||
20 | "github.com/julienschmidt/httprouter" | 18 | "github.com/julienschmidt/httprouter" |
21 | ) | 19 | ) |
22 | 20 | ||
23 | var ( | ||
24 | pgArrayReg = regexp.MustCompile(`(((?P<value>(([^",\\{}\s(NULL)])+|"([^"\\]|\\"|\\\\)*")))(,)?)`) | ||
25 | pgValueIdx int | ||
26 | ) | ||
27 | |||
28 | func findIdx() { | ||
29 | for i, subexp := range pgArrayReg.SubexpNames() { | ||
30 | if subexp == "value" { | ||
31 | pgValueIdx = i | ||
32 | break | ||
33 | } | ||
34 | } | ||
35 | } | ||
36 | |||
37 | type GrilsModule struct { | 21 | type GrilsModule struct { |
38 | g *grilist.Grilist | 22 | g *grilist.Grilist |
39 | c *cache.Cache | 23 | c *cache.Cache |
@@ -44,7 +28,6 @@ func (m *GrilsModule) Name() string { | |||
44 | } | 28 | } |
45 | 29 | ||
46 | func (m *GrilsModule) Init(g *grilist.Grilist) { | 30 | func (m *GrilsModule) Init(g *grilist.Grilist) { |
47 | findIdx() | ||
48 | m.g = g | 31 | m.g = g |
49 | m.g.Router.GET("/gril/:id", m.viewGril) | 32 | m.g.Router.GET("/gril/:id", m.viewGril) |
50 | m.g.Router.GET("/gril/:id/*rest", m.viewGril) | 33 | m.g.Router.GET("/gril/:id/*rest", m.viewGril) |
@@ -77,8 +60,8 @@ func (m *GrilsModule) getGrils(whereClause string, params ...interface{}) ([]*mo | |||
77 | gril.KanjiName = *kanjiName | 60 | gril.KanjiName = *kanjiName |
78 | } | 61 | } |
79 | 62 | ||
80 | gril.Tags = pgArray(tags) | 63 | gril.Tags = util.PGArray(tags) |
81 | gril.OtherNames = pgArray(otherNames) | 64 | gril.OtherNames = util.PGArray(otherNames) |
82 | 65 | ||
83 | m.c.Insert(gril.ID, gril) | 66 | m.c.Insert(gril.ID, gril) |
84 | 67 | ||
@@ -285,17 +268,6 @@ func (m *GrilsModule) viewGril(w http.ResponseWriter, r *http.Request, p httprou | |||
285 | }) | 268 | }) |
286 | } | 269 | } |
287 | 270 | ||
288 | func pgArray(array []byte) []string { | ||
289 | var results []string | ||
290 | matches := pgArrayReg.FindAllStringSubmatch(string(array), -1) | ||
291 | for _, match := range matches { | ||
292 | s := match[pgValueIdx] | ||
293 | s = strings.Trim(s, "\"") | ||
294 | results = append(results, s) | ||
295 | } | ||
296 | return results | ||
297 | } | ||
298 | |||
299 | func New() *GrilsModule { | 271 | func New() *GrilsModule { |
300 | return &GrilsModule{} | 272 | return &GrilsModule{} |
301 | } | 273 | } |
diff --git a/modules/lists/lists.go b/modules/lists/lists.go index 65919e8..387e48a 100644 --- a/modules/lists/lists.go +++ b/modules/lists/lists.go | |||
@@ -13,12 +13,14 @@ import ( | |||
13 | 13 | ||
14 | "fagott.pw/charakterin" | 14 | "fagott.pw/charakterin" |
15 | "fagott.pw/grilist/cache" | 15 | "fagott.pw/grilist/cache" |
16 | "fagott.pw/grilist/dataimport" | ||
16 | "fagott.pw/grilist/eventlogging" | 17 | "fagott.pw/grilist/eventlogging" |
17 | "fagott.pw/grilist/frontend" | 18 | "fagott.pw/grilist/frontend" |
18 | "fagott.pw/grilist/grilist" | 19 | "fagott.pw/grilist/grilist" |
19 | "fagott.pw/grilist/models" | 20 | "fagott.pw/grilist/models" |
20 | "fagott.pw/grilist/modules/grils" | 21 | "fagott.pw/grilist/modules/grils" |
21 | "fagott.pw/grilist/util" | 22 | "fagott.pw/grilist/util" |
23 | |||
22 | "github.com/julienschmidt/httprouter" | 24 | "github.com/julienschmidt/httprouter" |
23 | ) | 25 | ) |
24 | 26 | ||
@@ -66,6 +68,9 @@ func (m *Module) Init(g *grilist.Grilist) { | |||
66 | m.g.Router.GET("/list/:id/delete", m.deleteList) | 68 | m.g.Router.GET("/list/:id/delete", m.deleteList) |
67 | 69 | ||
68 | m.g.Router.GET("/api/lists/user", m.APIgetUserLists) | 70 | m.g.Router.GET("/api/lists/user", m.APIgetUserLists) |
71 | m.g.Router.GET("/api/import/anilist/favourites", m.apiAnilistGetFavourites) | ||
72 | m.g.Router.GET("/api/import/anilist/translate", m.apiAnilistTranslate) | ||
73 | m.g.Router.GET("/api/import/anilist/assign", m.apiAnilistAssign) | ||
69 | 74 | ||
70 | m.c = cache.New() | 75 | m.c = cache.New() |
71 | } | 76 | } |
@@ -78,7 +83,6 @@ func (m *Module) getListGrils(list *models.List) error { | |||
78 | 83 | ||
79 | defer rows.Close() | 84 | defer rows.Close() |
80 | list.Grils = list.Grils[:0] | 85 | list.Grils = list.Grils[:0] |
81 | var ids []int | ||
82 | for rows.Next() { | 86 | for rows.Next() { |
83 | var grilID int | 87 | var grilID int |
84 | lg := &models.ListGril{} | 88 | lg := &models.ListGril{} |
@@ -87,21 +91,16 @@ func (m *Module) getListGrils(list *models.List) error { | |||
87 | log.Println("error scanning row in getListGrils:", err) | 91 | log.Println("error scanning row in getListGrils:", err) |
88 | continue | 92 | continue |
89 | } | 93 | } |
90 | ids = append(ids, grilID) | ||
91 | 94 | ||
92 | list.Grils = append(list.Grils, lg) | 95 | gril, err := m.grils.FromID(grilID) |
93 | } | 96 | if err != nil { |
94 | 97 | log.Println("error getting listGril:", err) | |
95 | // grils holen | 98 | continue |
96 | grils, err := m.grils.FromIDs(ids) | 99 | } |
97 | if err != nil { | 100 | lg.Gril = gril |
98 | return err | ||
99 | } | ||
100 | 101 | ||
101 | for id, gril := range grils { | 102 | list.Grils = append(list.Grils, lg) |
102 | list.Grils[id].Gril = gril | ||
103 | } | 103 | } |
104 | |||
105 | sort.Sort(ListGrils(list.Grils)) | 104 | sort.Sort(ListGrils(list.Grils)) |
106 | return nil | 105 | return nil |
107 | } | 106 | } |
@@ -267,6 +266,18 @@ func (m *Module) viewList(w http.ResponseWriter, r *http.Request, p httprouter.P | |||
267 | data := m.g.Renderer.DefaultData() | 266 | data := m.g.Renderer.DefaultData() |
268 | data["user"] = user | 267 | data["user"] = user |
269 | data["list"] = list | 268 | data["list"] = list |
269 | data["mergeTemplateCard"] = frontend.Card{ | ||
270 | Image: "/assets/img/placeholder.png", | ||
271 | Actions: []frontend.Action{ | ||
272 | frontend.Action{ | ||
273 | Name: "Anguckieren", | ||
274 | Target: "_blank", | ||
275 | }, | ||
276 | frontend.Action{ | ||
277 | Name: "Auswählen", | ||
278 | }, | ||
279 | }, | ||
280 | } | ||
270 | if user != nil && user.ID == list.Owner.ID { | 281 | if user != nil && user.ID == list.Owner.ID { |
271 | data["isOwner"] = true | 282 | data["isOwner"] = true |
272 | } else { | 283 | } else { |
@@ -526,7 +537,7 @@ func (m *Module) addGrilToList(w http.ResponseWriter, r *http.Request, p httprou | |||
526 | } | 537 | } |
527 | 538 | ||
528 | // rein in die DB damit | 539 | // rein in die DB damit |
529 | _, err = m.g.DB.Query(`INSERT INTO grilist.lists_grils(list_id, gril_id, "order") VALUES($1, $2, $3)`, listID, grilID, rank) | 540 | _, err = m.g.DB.Exec(`INSERT INTO grilist.lists_grils(list_id, gril_id, "order") VALUES($1, $2, $3)`, listID, grilID, rank) |
530 | if err != nil { | 541 | if err != nil { |
531 | log.Println("error inserting gril into list:", err) | 542 | log.Println("error inserting gril into list:", err) |
532 | http.Error(w, "could not insert gril", 500) | 543 | http.Error(w, "could not insert gril", 500) |
@@ -725,6 +736,216 @@ func (m *Module) removeGrilFromList(w http.ResponseWriter, r *http.Request, p ht | |||
725 | }) | 736 | }) |
726 | } | 737 | } |
727 | 738 | ||
739 | func (m *Module) apiAnilistGetFavourites(w http.ResponseWriter, r *http.Request, p httprouter.Params) { | ||
740 | el := m.g.EventLogger(r) | ||
741 | user, err := m.g.Charakterin.GetUserFromRequest(r) | ||
742 | if err != nil { | ||
743 | http.Error(w, "Unauthorized", 401) | ||
744 | return | ||
745 | } | ||
746 | |||
747 | if user.AnilistClient == nil || !user.AnilistClient.IsCoupled { | ||
748 | http.Error(w, "Anilist not enabled", 500) | ||
749 | return | ||
750 | } | ||
751 | |||
752 | aniUser, err := user.AnilistClient.User() | ||
753 | if err != nil { | ||
754 | http.Error(w, fmt.Sprintf("%v", err), 500) | ||
755 | return | ||
756 | } | ||
757 | |||
758 | favs, err := user.AnilistClient.Favourites(aniUser.ID) | ||
759 | if err != nil { | ||
760 | http.Error(w, fmt.Sprintf("%v", err), 500) | ||
761 | return | ||
762 | } | ||
763 | |||
764 | el.FavImportAnilist(user, eventlogging.FavImportAnilistData{ | ||
765 | Favourites: favs, | ||
766 | }) | ||
767 | |||
768 | idList := "(" | ||
769 | ids := []*models.ForeignID{} | ||
770 | idMap := map[int]*models.ForeignID{} | ||
771 | for _, v := range favs.Characters { | ||
772 | id := &models.ForeignID{ | ||
773 | ID: v.ID, | ||
774 | } | ||
775 | ids = append(ids, id) | ||
776 | idMap[v.ID] = id | ||
777 | idList += strconv.Itoa(v.ID) + "," | ||
778 | } | ||
779 | idList = idList[:len(idList)-1] + ")" | ||
780 | rows, err := m.g.DB.Query(fmt.Sprintf("SELECT source_id, gril_id FROM grils_id_mappings WHERE source = $1 AND source_id in %s;", idList), models.DataSourceAnilist) | ||
781 | if err != nil { | ||
782 | http.Error(w, fmt.Sprintf("%v", err), 500) | ||
783 | return | ||
784 | } | ||
785 | defer rows.Close() | ||
786 | for rows.Next() { | ||
787 | var sID int | ||
788 | var id int | ||
789 | if err := rows.Scan(&sID, &id); err != nil { | ||
790 | http.Error(w, fmt.Sprintf("%v", err), 500) | ||
791 | return | ||
792 | } | ||
793 | idMap[sID].Mapped = id | ||
794 | } | ||
795 | |||
796 | idsData, err := json.Marshal(ids) | ||
797 | if err != nil { | ||
798 | http.Error(w, fmt.Sprintf("%v", err), 500) | ||
799 | return | ||
800 | } | ||
801 | |||
802 | w.WriteHeader(200) | ||
803 | w.Write(idsData) | ||
804 | } | ||
805 | |||
806 | func (m *Module) apiAnilistTranslate(w http.ResponseWriter, r *http.Request, p httprouter.Params) { | ||
807 | el := m.g.EventLogger(r) | ||
808 | user, err := m.g.Charakterin.GetUserFromRequest(r) | ||
809 | if err != nil { | ||
810 | http.Error(w, "Unauthorized", 401) | ||
811 | return | ||
812 | } | ||
813 | |||
814 | if user.AnilistClient == nil || !user.AnilistClient.IsCoupled { | ||
815 | http.Error(w, "Anilist not enabled", 500) | ||
816 | return | ||
817 | } | ||
818 | |||
819 | idParam := r.URL.Query().Get("id") | ||
820 | id, err := strconv.Atoi(idParam) | ||
821 | if err != nil { | ||
822 | http.Error(w, "invalid gril ID (type mismatch)", 400) | ||
823 | return | ||
824 | } | ||
825 | |||
826 | grilID := dataimport.FindGrilInDatabase(id, models.DataSourceAnilist) | ||
827 | if grilID != nil { | ||
828 | log.Println("Found gril by mapping") | ||
829 | data, err := json.Marshal(models.Merge{ | ||
830 | Targets: []models.MergeGril{ | ||
831 | models.MergeGril{ | ||
832 | ID: *grilID, | ||
833 | }, | ||
834 | }, | ||
835 | }) | ||
836 | if err != nil { | ||
837 | http.Error(w, fmt.Sprintf("%v", err), 500) | ||
838 | return | ||
839 | } | ||
840 | w.WriteHeader(200) | ||
841 | w.Write(data) | ||
842 | return | ||
843 | } | ||
844 | |||
845 | char, err := user.AnilistClient.CharacterPage(id) | ||
846 | if err != nil { | ||
847 | http.Error(w, fmt.Sprintf("%v", err), 500) | ||
848 | return | ||
849 | } | ||
850 | |||
851 | el.AnilistCharacterPage(user, eventlogging.AnilistCharacterPageData{ | ||
852 | CharacterPage: char, | ||
853 | }) | ||
854 | |||
855 | aniGril := dataimport.ConvertGrilAnilist(char) | ||
856 | similarGrils, err := dataimport.FindSimilarGrils(aniGril, models.DataSourceAnilist) | ||
857 | if err != nil { | ||
858 | http.Error(w, fmt.Sprintf("%v", err), 500) | ||
859 | return | ||
860 | } | ||
861 | |||
862 | merge := models.Merge{ | ||
863 | ID: char.ID, | ||
864 | Name: aniGril.RomajiName, | ||
865 | ImageURL: char.ThumbURL, | ||
866 | Targets: []models.MergeGril{}, | ||
867 | } | ||
868 | for _, sg := range similarGrils { | ||
869 | merge.Targets = append(merge.Targets, models.MergeGril{ | ||
870 | ID: sg.ID, | ||
871 | Name: sg.RomajiName, | ||
872 | ImageURL: sg.ImagePath(true), | ||
873 | }) | ||
874 | } | ||
875 | |||
876 | switch len(merge.Targets) { | ||
877 | case 0: | ||
878 | var iID int | ||
879 | if iID, err = dataimport.InsertGril(aniGril, models.DataSourceAnilist); err != nil { | ||
880 | http.Error(w, fmt.Sprintf("Import: %v", err), 500) | ||
881 | return | ||
882 | } | ||
883 | merge.Targets = append(merge.Targets, models.MergeGril{ | ||
884 | ID: iID, | ||
885 | }) | ||
886 | el.FavImportAnilistCreated(user, eventlogging.FavImportAnilistCreatedData{ | ||
887 | AnilistID: aniGril.ID, | ||
888 | AssignedID: iID, | ||
889 | }) | ||
890 | case 1: | ||
891 | if err := dataimport.AssignGril(char.ID, merge.Targets[0].ID, models.DataSourceAnilist); err != nil { | ||
892 | http.Error(w, fmt.Sprintf("Assign: %v", err), 500) | ||
893 | return | ||
894 | } | ||
895 | el.FavImportAnilistAssigned(user, eventlogging.FavImportAnilistAssignedData{ | ||
896 | AnilistID: char.ID, | ||
897 | AssignedID: merge.Targets[0].ID, | ||
898 | }) | ||
899 | } | ||
900 | |||
901 | data, err := json.Marshal(merge) | ||
902 | if err != nil { | ||
903 | http.Error(w, fmt.Sprintf("%v", err), 500) | ||
904 | return | ||
905 | } | ||
906 | |||
907 | w.WriteHeader(200) | ||
908 | w.Write(data) | ||
909 | } | ||
910 | |||
911 | func (m *Module) apiAnilistAssign(w http.ResponseWriter, r *http.Request, p httprouter.Params) { | ||
912 | el := m.g.EventLogger(r) | ||
913 | user, err := m.g.Charakterin.GetUserFromRequest(r) | ||
914 | if err != nil { | ||
915 | http.Error(w, "Unauthorized", 401) | ||
916 | return | ||
917 | } | ||
918 | |||
919 | if user.AnilistClient == nil || !user.AnilistClient.IsCoupled { | ||
920 | http.Error(w, "Anilist not enabled", 500) | ||
921 | return | ||
922 | } | ||
923 | |||
924 | idParam := r.URL.Query().Get("id") | ||
925 | id, err := strconv.Atoi(idParam) | ||
926 | if err != nil { | ||
927 | http.Error(w, "invalid gril ID (type mismatch)", 400) | ||
928 | return | ||
929 | } | ||
930 | targetParam := r.URL.Query().Get("target") | ||
931 | target, err := strconv.Atoi(targetParam) | ||
932 | if err != nil { | ||
933 | http.Error(w, "invalid target ID (type mismatch)", 400) | ||
934 | return | ||
935 | } | ||
936 | |||
937 | if err := dataimport.AssignGril(id, target, models.DataSourceAnilist); err != nil { | ||
938 | http.Error(w, fmt.Sprintf("%v", err), 500) | ||
939 | return | ||
940 | } | ||
941 | w.WriteHeader(200) | ||
942 | w.Write([]byte("OK")) | ||
943 | el.FavImportAnilistAssigned(user, eventlogging.FavImportAnilistAssignedData{ | ||
944 | AnilistID: id, | ||
945 | AssignedID: target, | ||
946 | }) | ||
947 | } | ||
948 | |||
728 | func (m *Module) APIgetUserLists(w http.ResponseWriter, r *http.Request, p httprouter.Params) { | 949 | func (m *Module) APIgetUserLists(w http.ResponseWriter, r *http.Request, p httprouter.Params) { |
729 | user, err := m.g.Charakterin.GetUserFromRequest(r) | 950 | user, err := m.g.Charakterin.GetUserFromRequest(r) |
730 | if err != nil { | 951 | if err != nil { |