A clean, Markdown-based publishing platform made for writers. Write together, and build a community. https://writefreely.org
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

116 lines
2.8 KiB

  1. /*
  2. * Copyright © 2018 A Bunch Tell LLC.
  3. *
  4. * This file is part of WriteFreely.
  5. *
  6. * WriteFreely is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU Affero General Public License, included
  8. * in the LICENSE file in this source code package.
  9. */
  10. package writefreely
  11. import (
  12. "github.com/writeas/web-core/log"
  13. "github.com/writeas/writefreely/config"
  14. "github.com/writefreely/go-nodeinfo"
  15. "strings"
  16. )
  17. type nodeInfoResolver struct {
  18. cfg *config.Config
  19. db *datastore
  20. }
  21. func nodeInfoConfig(db *datastore, cfg *config.Config) *nodeinfo.Config {
  22. name := cfg.App.SiteName
  23. desc := cfg.App.SiteDesc
  24. if desc == "" {
  25. desc = "Minimal, federated blogging platform."
  26. }
  27. if cfg.App.SingleUser {
  28. // Fetch blog information, instead
  29. coll, err := db.GetCollectionByID(1)
  30. if err == nil {
  31. desc = coll.Description
  32. }
  33. }
  34. return &nodeinfo.Config{
  35. BaseURL: cfg.App.Host,
  36. InfoURL: "/api/nodeinfo",
  37. Metadata: nodeinfo.Metadata{
  38. NodeName: name,
  39. NodeDescription: desc,
  40. Private: cfg.App.Private,
  41. Software: nodeinfo.SoftwareMeta{
  42. HomePage: softwareURL,
  43. GitHub: "https://github.com/writeas/writefreely",
  44. Follow: "https://writing.exchange/@write_as",
  45. },
  46. MaxBlogs: cfg.App.MaxBlogs,
  47. PublicReader: cfg.App.LocalTimeline,
  48. Invites: cfg.App.UserInvites != "",
  49. },
  50. Protocols: []nodeinfo.NodeProtocol{
  51. nodeinfo.ProtocolActivityPub,
  52. },
  53. Services: nodeinfo.Services{
  54. Inbound: []nodeinfo.NodeService{},
  55. Outbound: []nodeinfo.NodeService{
  56. nodeinfo.ServiceRSS,
  57. },
  58. },
  59. Software: nodeinfo.SoftwareInfo{
  60. Name: strings.ToLower(serverSoftware),
  61. Version: softwareVer,
  62. },
  63. }
  64. }
  65. func (r nodeInfoResolver) IsOpenRegistration() (bool, error) {
  66. return r.cfg.App.OpenRegistration, nil
  67. }
  68. func (r nodeInfoResolver) Usage() (nodeinfo.Usage, error) {
  69. var collCount, postCount int64
  70. var activeHalfYear, activeMonth int
  71. var err error
  72. collCount, err = r.db.GetTotalCollections()
  73. if err != nil {
  74. collCount = 0
  75. }
  76. postCount, err = r.db.GetTotalPosts()
  77. if err != nil {
  78. log.Error("Unable to fetch post counts: %v", err)
  79. }
  80. if r.cfg.App.PublicStats {
  81. // Display bi-yearly / monthly stats
  82. err = r.db.QueryRow(`SELECT COUNT(*) FROM (
  83. SELECT DISTINCT collection_id
  84. FROM posts
  85. INNER JOIN collections c
  86. ON collection_id = c.id
  87. WHERE collection_id IS NOT NULL
  88. AND updated > DATE_SUB(NOW(), INTERVAL 6 MONTH)) co`).Scan(&activeHalfYear)
  89. err = r.db.QueryRow(`SELECT COUNT(*) FROM (
  90. SELECT DISTINCT collection_id
  91. FROM posts
  92. INNER JOIN FROM collections c
  93. ON collection_id = c.id
  94. WHERE collection_id IS NOT NULL
  95. AND updated > DATE_SUB(NOW(), INTERVAL 1 MONTH)) co`).Scan(&activeMonth)
  96. }
  97. return nodeinfo.Usage{
  98. Users: nodeinfo.UsageUsers{
  99. Total: int(collCount),
  100. ActiveHalfYear: activeHalfYear,
  101. ActiveMonth: activeMonth,
  102. },
  103. LocalPosts: int(postCount),
  104. }, nil
  105. }