fuckingfixes
This commit is contained in:
parent
3b9bf95247
commit
24d45a139e
@ -2,6 +2,7 @@ package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha1"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
@ -332,14 +333,15 @@ type ChunkInfo struct {
|
||||
}
|
||||
|
||||
type UploadResponse struct {
|
||||
FileHash string `json:"file_hash"`
|
||||
Message string `json:"message"`
|
||||
TorrentHash string `json:"torrent_hash,omitempty"`
|
||||
MagnetLink string `json:"magnet_link,omitempty"`
|
||||
NostrEventID string `json:"nostr_event_id,omitempty"`
|
||||
NIP71EventID string `json:"nip71_event_id,omitempty"`
|
||||
StreamingURL string `json:"streaming_url,omitempty"`
|
||||
HLSURL string `json:"hls_url,omitempty"`
|
||||
FileHash string `json:"file_hash"`
|
||||
Message string `json:"message"`
|
||||
TorrentHash string `json:"torrent_hash,omitempty"`
|
||||
TorrentInfoHash string `json:"torrent_info_hash,omitempty"`
|
||||
MagnetLink string `json:"magnet_link,omitempty"`
|
||||
NostrEventID string `json:"nostr_event_id,omitempty"`
|
||||
NIP71EventID string `json:"nip71_event_id,omitempty"`
|
||||
StreamingURL string `json:"streaming_url,omitempty"`
|
||||
HLSURL string `json:"hls_url,omitempty"`
|
||||
}
|
||||
|
||||
func NewGateway(cfg *config.Config, storage *storage.Backend) *Gateway {
|
||||
@ -977,18 +979,25 @@ func (g *Gateway) handleTorrentUpload(w http.ResponseWriter, r *http.Request, fi
|
||||
})
|
||||
}
|
||||
|
||||
// Create torrent pieces from chunk hashes
|
||||
// Create torrent pieces from actual chunk data with proper SHA-1 hashes
|
||||
pieces := make([]torrent.PieceInfo, len(chunkHashes))
|
||||
for i, chunkHash := range chunkHashes {
|
||||
// Convert hex string to bytes for torrent hash
|
||||
hashBytes := make([]byte, 20)
|
||||
copy(hashBytes, []byte(chunkHash)[:20])
|
||||
// Get actual chunk data and calculate SHA-1 hash
|
||||
chunkData, err := g.blossomClient.Get(chunkHash)
|
||||
if err != nil {
|
||||
g.writeError(w, http.StatusInternalServerError, "Failed to get chunk data", ErrorTypeInternal,
|
||||
fmt.Sprintf("Failed to get chunk %s: %v", chunkHash, err))
|
||||
return
|
||||
}
|
||||
|
||||
// Calculate actual SHA-1 hash of chunk data
|
||||
sha1Hash := sha1.Sum(chunkData)
|
||||
|
||||
pieces[i] = torrent.PieceInfo{
|
||||
Index: i,
|
||||
Hash: [20]byte(hashBytes),
|
||||
Hash: sha1Hash, // Actual SHA-1 hash
|
||||
SHA256: chunkHash,
|
||||
Length: int(g.config.GetChunkSize()),
|
||||
Length: len(chunkData), // Actual chunk size
|
||||
}
|
||||
}
|
||||
|
||||
@ -1168,12 +1177,13 @@ func (g *Gateway) handleTorrentUpload(w http.ResponseWriter, r *http.Request, fi
|
||||
|
||||
// Send success response for torrent
|
||||
response := UploadResponse{
|
||||
FileHash: metadata.Hash,
|
||||
Message: "File uploaded successfully as torrent",
|
||||
TorrentHash: torrentInfo.InfoHash,
|
||||
MagnetLink: torrentInfo.Magnet,
|
||||
NostrEventID: nostrEventID,
|
||||
NIP71EventID: nip71EventID,
|
||||
FileHash: metadata.Hash, // SHA-256 file hash
|
||||
Message: "File uploaded successfully as torrent",
|
||||
TorrentHash: torrentInfo.InfoHash, // Same as TorrentInfoHash (legacy)
|
||||
TorrentInfoHash: torrentInfo.InfoHash, // SHA-1 info hash for magnets
|
||||
MagnetLink: torrentInfo.Magnet, // Already correct
|
||||
NostrEventID: nostrEventID,
|
||||
NIP71EventID: nip71EventID,
|
||||
}
|
||||
|
||||
// Add streaming URL if it's a video
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"time"
|
||||
|
||||
"torrentGateway/internal/config"
|
||||
"github.com/anacrolix/torrent/bencode"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -219,16 +220,34 @@ func (d *DHT) bootstrap() {
|
||||
}
|
||||
}
|
||||
|
||||
// generateTransactionID generates a transaction ID for DHT messages
|
||||
func (d *DHT) generateTransactionID() string {
|
||||
return fmt.Sprintf("%d", time.Now().UnixNano()%10000)
|
||||
}
|
||||
|
||||
// sendPing sends a ping message to a node
|
||||
func (d *DHT) sendPing(addr *net.UDPAddr) error {
|
||||
// Simplified ping message (in real implementation, would use bencode)
|
||||
message := []byte("ping")
|
||||
// Create proper DHT ping message
|
||||
msg := map[string]interface{}{
|
||||
"t": d.generateTransactionID(),
|
||||
"y": "q",
|
||||
"q": "ping",
|
||||
"a": map[string]interface{}{
|
||||
"id": string(d.nodeID[:]),
|
||||
},
|
||||
}
|
||||
|
||||
_, err := d.conn.WriteToUDP(message, addr)
|
||||
data, err := bencode.Marshal(msg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = d.conn.WriteToUDP(data, addr)
|
||||
if err == nil {
|
||||
d.statsMu.Lock()
|
||||
d.stats.PacketsSent++
|
||||
d.statsMu.Unlock()
|
||||
log.Printf("Sent DHT ping to %s", addr)
|
||||
}
|
||||
|
||||
return err
|
||||
|
@ -30,8 +30,13 @@ type PieceInfo struct {
|
||||
}
|
||||
|
||||
func CreateTorrent(fileInfo FileInfo, trackers []string, gatewayURL string, dhtNodes [][]interface{}) (*TorrentInfo, error) {
|
||||
// Calculate piece length based on file size (following BUD-10 spec)
|
||||
pieceLength := calculatePieceLength(fileInfo.Size)
|
||||
// Use actual piece size from first piece instead of calculated
|
||||
var actualPieceLength int64
|
||||
if len(fileInfo.Pieces) > 0 {
|
||||
actualPieceLength = int64(fileInfo.Pieces[0].Length)
|
||||
} else {
|
||||
return nil, fmt.Errorf("no pieces provided")
|
||||
}
|
||||
|
||||
// Create pieces buffer - concatenated SHA-1 hashes
|
||||
var pieces []byte
|
||||
@ -43,7 +48,7 @@ func CreateTorrent(fileInfo FileInfo, trackers []string, gatewayURL string, dhtN
|
||||
info := metainfo.Info{
|
||||
Name: fileInfo.Name,
|
||||
Length: fileInfo.Size,
|
||||
PieceLength: pieceLength,
|
||||
PieceLength: actualPieceLength, // Use ACTUAL size
|
||||
Pieces: pieces,
|
||||
}
|
||||
|
||||
|
@ -1388,6 +1388,43 @@ button:hover, .action-btn:hover {
|
||||
color: var(--accent-primary);
|
||||
}
|
||||
|
||||
/* Nostr share link styles */
|
||||
.share-link.nostr-link {
|
||||
background: linear-gradient(135deg, #8b5cf6 0%, #6366f1 100%);
|
||||
padding: 15px;
|
||||
border-radius: 8px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.share-link.nostr-link label {
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.share-link.nostr-link small {
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
font-size: 0.85em;
|
||||
display: block;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.share-link .open-btn {
|
||||
background: #6366f1;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 8px 16px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
margin-left: 5px;
|
||||
font-family: inherit;
|
||||
font-size: 10px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.share-link .open-btn:hover {
|
||||
background: #4f46e5;
|
||||
}
|
||||
|
||||
/* File Details Modal */
|
||||
.file-preview-large {
|
||||
text-align: center;
|
||||
|
@ -616,8 +616,8 @@ class GatewayUI {
|
||||
|
||||
// Use torrent info hash for magnet link if available, otherwise use file hash
|
||||
let magnetHash = hash;
|
||||
if (fileData && fileData.torrent_info && fileData.torrent_info.InfoHash) {
|
||||
magnetHash = fileData.torrent_info.InfoHash;
|
||||
if (fileData && fileData.torrent_hash) {
|
||||
magnetHash = fileData.torrent_hash;
|
||||
console.log('Using torrent InfoHash for magnet:', magnetHash);
|
||||
} else {
|
||||
console.log('No torrent InfoHash found, using file hash:', magnetHash);
|
||||
@ -635,6 +635,11 @@ class GatewayUI {
|
||||
links.hls = `${baseUrl}/api/stream/${hash}/playlist.m3u8`;
|
||||
}
|
||||
|
||||
// Add NIP-71 Nostr link if available
|
||||
if (fileData && fileData.nip71_share_link) {
|
||||
links.nostr = fileData.nip71_share_link;
|
||||
}
|
||||
|
||||
this.showShareModal(name, links);
|
||||
} catch (error) {
|
||||
console.error('Failed to get file metadata:', error);
|
||||
@ -671,22 +676,38 @@ class GatewayUI {
|
||||
const linkTypes = [
|
||||
{ key: 'direct', label: 'Direct Download', icon: '⬇️' },
|
||||
{ key: 'torrent', label: 'Torrent File', icon: '🧲' },
|
||||
{ key: 'magnet', label: 'Magnet Link', icon: '🧲' },
|
||||
{ key: 'magnet', label: 'Magnet Link', icon: '🔗' },
|
||||
{ key: 'stream', label: 'Stream Video', icon: '▶️' },
|
||||
{ key: 'hls', label: 'HLS Playlist', icon: '📺' }
|
||||
{ key: 'hls', label: 'HLS Playlist', icon: '📺' },
|
||||
{ key: 'nostr', label: 'Share on Nostr', icon: '⚡' }
|
||||
];
|
||||
|
||||
linksContainer.innerHTML = linkTypes
|
||||
.filter(type => links[type.key])
|
||||
.map(type => `
|
||||
<div class="share-link">
|
||||
<label>${type.icon} ${type.label}</label>
|
||||
<div class="input-group">
|
||||
<input type="text" value="${links[type.key]}" readonly>
|
||||
<button onclick="copyToClipboard('${links[type.key].replace(/'/g, '\\\'')}')" class="copy-btn">Copy</button>
|
||||
.map(type => {
|
||||
if (type.key === 'nostr') {
|
||||
return `
|
||||
<div class="share-link nostr-link">
|
||||
<label>${type.icon} ${type.label}</label>
|
||||
<div class="input-group">
|
||||
<input type="text" value="${links[type.key]}" readonly>
|
||||
<button onclick="copyToClipboard('${links[type.key].replace(/'/g, '\\\'')}')" class="copy-btn">Copy</button>
|
||||
<button onclick="window.open('https://njump.me/${links[type.key]}', '_blank')" class="open-btn">Open</button>
|
||||
</div>
|
||||
<small>Opens in Nostr clients or web viewer</small>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
return `
|
||||
<div class="share-link">
|
||||
<label>${type.icon} ${type.label}</label>
|
||||
<div class="input-group">
|
||||
<input type="text" value="${links[type.key]}" readonly>
|
||||
<button onclick="copyToClipboard('${links[type.key].replace(/'/g, '\\\'')}')" class="copy-btn">Copy</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`).join('');
|
||||
`;
|
||||
}).join('');
|
||||
|
||||
modal.style.display = 'block';
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user