fuckingfixes
This commit is contained in:
parent
3b9bf95247
commit
24d45a139e
@ -2,6 +2,7 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"crypto/sha1"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -335,6 +336,7 @@ type UploadResponse struct {
|
|||||||
FileHash string `json:"file_hash"`
|
FileHash string `json:"file_hash"`
|
||||||
Message string `json:"message"`
|
Message string `json:"message"`
|
||||||
TorrentHash string `json:"torrent_hash,omitempty"`
|
TorrentHash string `json:"torrent_hash,omitempty"`
|
||||||
|
TorrentInfoHash string `json:"torrent_info_hash,omitempty"`
|
||||||
MagnetLink string `json:"magnet_link,omitempty"`
|
MagnetLink string `json:"magnet_link,omitempty"`
|
||||||
NostrEventID string `json:"nostr_event_id,omitempty"`
|
NostrEventID string `json:"nostr_event_id,omitempty"`
|
||||||
NIP71EventID string `json:"nip71_event_id,omitempty"`
|
NIP71EventID string `json:"nip71_event_id,omitempty"`
|
||||||
@ -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))
|
pieces := make([]torrent.PieceInfo, len(chunkHashes))
|
||||||
for i, chunkHash := range chunkHashes {
|
for i, chunkHash := range chunkHashes {
|
||||||
// Convert hex string to bytes for torrent hash
|
// Get actual chunk data and calculate SHA-1 hash
|
||||||
hashBytes := make([]byte, 20)
|
chunkData, err := g.blossomClient.Get(chunkHash)
|
||||||
copy(hashBytes, []byte(chunkHash)[:20])
|
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{
|
pieces[i] = torrent.PieceInfo{
|
||||||
Index: i,
|
Index: i,
|
||||||
Hash: [20]byte(hashBytes),
|
Hash: sha1Hash, // Actual SHA-1 hash
|
||||||
SHA256: chunkHash,
|
SHA256: chunkHash,
|
||||||
Length: int(g.config.GetChunkSize()),
|
Length: len(chunkData), // Actual chunk size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1168,10 +1177,11 @@ func (g *Gateway) handleTorrentUpload(w http.ResponseWriter, r *http.Request, fi
|
|||||||
|
|
||||||
// Send success response for torrent
|
// Send success response for torrent
|
||||||
response := UploadResponse{
|
response := UploadResponse{
|
||||||
FileHash: metadata.Hash,
|
FileHash: metadata.Hash, // SHA-256 file hash
|
||||||
Message: "File uploaded successfully as torrent",
|
Message: "File uploaded successfully as torrent",
|
||||||
TorrentHash: torrentInfo.InfoHash,
|
TorrentHash: torrentInfo.InfoHash, // Same as TorrentInfoHash (legacy)
|
||||||
MagnetLink: torrentInfo.Magnet,
|
TorrentInfoHash: torrentInfo.InfoHash, // SHA-1 info hash for magnets
|
||||||
|
MagnetLink: torrentInfo.Magnet, // Already correct
|
||||||
NostrEventID: nostrEventID,
|
NostrEventID: nostrEventID,
|
||||||
NIP71EventID: nip71EventID,
|
NIP71EventID: nip71EventID,
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"torrentGateway/internal/config"
|
"torrentGateway/internal/config"
|
||||||
|
"github.com/anacrolix/torrent/bencode"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
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
|
// sendPing sends a ping message to a node
|
||||||
func (d *DHT) sendPing(addr *net.UDPAddr) error {
|
func (d *DHT) sendPing(addr *net.UDPAddr) error {
|
||||||
// Simplified ping message (in real implementation, would use bencode)
|
// Create proper DHT ping message
|
||||||
message := []byte("ping")
|
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 {
|
if err == nil {
|
||||||
d.statsMu.Lock()
|
d.statsMu.Lock()
|
||||||
d.stats.PacketsSent++
|
d.stats.PacketsSent++
|
||||||
d.statsMu.Unlock()
|
d.statsMu.Unlock()
|
||||||
|
log.Printf("Sent DHT ping to %s", addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
|
@ -30,8 +30,13 @@ type PieceInfo struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func CreateTorrent(fileInfo FileInfo, trackers []string, gatewayURL string, dhtNodes [][]interface{}) (*TorrentInfo, error) {
|
func CreateTorrent(fileInfo FileInfo, trackers []string, gatewayURL string, dhtNodes [][]interface{}) (*TorrentInfo, error) {
|
||||||
// Calculate piece length based on file size (following BUD-10 spec)
|
// Use actual piece size from first piece instead of calculated
|
||||||
pieceLength := calculatePieceLength(fileInfo.Size)
|
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
|
// Create pieces buffer - concatenated SHA-1 hashes
|
||||||
var pieces []byte
|
var pieces []byte
|
||||||
@ -43,7 +48,7 @@ func CreateTorrent(fileInfo FileInfo, trackers []string, gatewayURL string, dhtN
|
|||||||
info := metainfo.Info{
|
info := metainfo.Info{
|
||||||
Name: fileInfo.Name,
|
Name: fileInfo.Name,
|
||||||
Length: fileInfo.Size,
|
Length: fileInfo.Size,
|
||||||
PieceLength: pieceLength,
|
PieceLength: actualPieceLength, // Use ACTUAL size
|
||||||
Pieces: pieces,
|
Pieces: pieces,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1388,6 +1388,43 @@ button:hover, .action-btn:hover {
|
|||||||
color: var(--accent-primary);
|
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 Details Modal */
|
||||||
.file-preview-large {
|
.file-preview-large {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
@ -616,8 +616,8 @@ class GatewayUI {
|
|||||||
|
|
||||||
// Use torrent info hash for magnet link if available, otherwise use file hash
|
// Use torrent info hash for magnet link if available, otherwise use file hash
|
||||||
let magnetHash = hash;
|
let magnetHash = hash;
|
||||||
if (fileData && fileData.torrent_info && fileData.torrent_info.InfoHash) {
|
if (fileData && fileData.torrent_hash) {
|
||||||
magnetHash = fileData.torrent_info.InfoHash;
|
magnetHash = fileData.torrent_hash;
|
||||||
console.log('Using torrent InfoHash for magnet:', magnetHash);
|
console.log('Using torrent InfoHash for magnet:', magnetHash);
|
||||||
} else {
|
} else {
|
||||||
console.log('No torrent InfoHash found, using file hash:', magnetHash);
|
console.log('No torrent InfoHash found, using file hash:', magnetHash);
|
||||||
@ -635,6 +635,11 @@ class GatewayUI {
|
|||||||
links.hls = `${baseUrl}/api/stream/${hash}/playlist.m3u8`;
|
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);
|
this.showShareModal(name, links);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to get file metadata:', error);
|
console.error('Failed to get file metadata:', error);
|
||||||
@ -671,14 +676,29 @@ class GatewayUI {
|
|||||||
const linkTypes = [
|
const linkTypes = [
|
||||||
{ key: 'direct', label: 'Direct Download', icon: '⬇️' },
|
{ key: 'direct', label: 'Direct Download', icon: '⬇️' },
|
||||||
{ key: 'torrent', label: 'Torrent File', 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: '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
|
linksContainer.innerHTML = linkTypes
|
||||||
.filter(type => links[type.key])
|
.filter(type => links[type.key])
|
||||||
.map(type => `
|
.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">
|
<div class="share-link">
|
||||||
<label>${type.icon} ${type.label}</label>
|
<label>${type.icon} ${type.label}</label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
@ -686,7 +706,8 @@ class GatewayUI {
|
|||||||
<button onclick="copyToClipboard('${links[type.key].replace(/'/g, '\\\'')}')" class="copy-btn">Copy</button>
|
<button onclick="copyToClipboard('${links[type.key].replace(/'/g, '\\\'')}')" class="copy-btn">Copy</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`).join('');
|
`;
|
||||||
|
}).join('');
|
||||||
|
|
||||||
modal.style.display = 'block';
|
modal.style.display = 'block';
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user