mirror of
https://github.com/go-gitea/gitea.git
synced 2025-07-17 00:01:00 -04:00
Compare commits
No commits in common. "1195d66c15ad6ead1f464b5d7ae30308e1278780" and "7735da1c66c5a1511a2eac04b2a7f5c60b214c83" have entirely different histories.
1195d66c15
...
7735da1c66
@ -64,6 +64,11 @@ func (branches BranchList) LoadPusher(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
const (
|
||||
BranchOrderByNameAsc = "name ASC"
|
||||
BranchOrderByCommitTimeDesc = "commit_time DESC"
|
||||
)
|
||||
|
||||
type FindBranchOptions struct {
|
||||
db.ListOptions
|
||||
RepoID int64
|
||||
@ -97,8 +102,7 @@ func orderByBranches(sess *xorm.Session, opts FindBranchOptions) *xorm.Session {
|
||||
}
|
||||
|
||||
if opts.OrderBy == "" {
|
||||
// the commit_time might be the same, so add the "name" to make sure the order is stable
|
||||
opts.OrderBy = "commit_time DESC, name ASC"
|
||||
opts.OrderBy = BranchOrderByCommitTimeDesc
|
||||
}
|
||||
return sess.OrderBy(opts.OrderBy)
|
||||
}
|
||||
|
@ -33,19 +33,6 @@ func TestRepository_GetCollaborators(t *testing.T) {
|
||||
test(2)
|
||||
test(3)
|
||||
test(4)
|
||||
|
||||
// Test db.ListOptions
|
||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 22})
|
||||
|
||||
collaborators1, err := repo_model.GetCollaborators(db.DefaultContext, repo.ID, db.ListOptions{PageSize: 1, Page: 1})
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, collaborators1, 1)
|
||||
|
||||
collaborators2, err := repo_model.GetCollaborators(db.DefaultContext, repo.ID, db.ListOptions{PageSize: 1, Page: 2})
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, collaborators2, 1)
|
||||
|
||||
assert.NotEqualValues(t, collaborators1[0].ID, collaborators2[0].ID)
|
||||
}
|
||||
|
||||
func TestRepository_IsCollaborator(t *testing.T) {
|
||||
@ -79,80 +66,5 @@ func TestRepository_ChangeCollaborationAccessMode(t *testing.T) {
|
||||
|
||||
assert.NoError(t, repo_model.ChangeCollaborationAccessMode(db.DefaultContext, repo, unittest.NonexistentID, perm.AccessModeAdmin))
|
||||
|
||||
// Disvard invalid input.
|
||||
assert.NoError(t, repo_model.ChangeCollaborationAccessMode(db.DefaultContext, repo, 4, perm.AccessMode(unittest.NonexistentID)))
|
||||
|
||||
unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: repo.ID})
|
||||
}
|
||||
|
||||
func TestRepository_CountCollaborators(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4})
|
||||
count, err := repo_model.CountCollaborators(repo1.ID)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 2, count)
|
||||
|
||||
repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 22})
|
||||
count, err = repo_model.CountCollaborators(repo2.ID)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 2, count)
|
||||
|
||||
// Non-existent repository.
|
||||
count, err = repo_model.CountCollaborators(unittest.NonexistentID)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 0, count)
|
||||
}
|
||||
|
||||
func TestRepository_IsOwnerMemberCollaborator(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
|
||||
|
||||
// Organisation owner.
|
||||
actual, err := repo_model.IsOwnerMemberCollaborator(repo1, 2)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, actual)
|
||||
|
||||
// Team member.
|
||||
actual, err = repo_model.IsOwnerMemberCollaborator(repo1, 4)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, actual)
|
||||
|
||||
// Normal user.
|
||||
actual, err = repo_model.IsOwnerMemberCollaborator(repo1, 1)
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, actual)
|
||||
|
||||
repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4})
|
||||
|
||||
// Collaborator.
|
||||
actual, err = repo_model.IsOwnerMemberCollaborator(repo2, 4)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, actual)
|
||||
|
||||
repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 15})
|
||||
|
||||
// Repository owner.
|
||||
actual, err = repo_model.IsOwnerMemberCollaborator(repo3, 2)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, actual)
|
||||
}
|
||||
|
||||
func TestRepo_GetCollaboration(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4})
|
||||
|
||||
// Existing collaboration.
|
||||
collab, err := repo_model.GetCollaboration(db.DefaultContext, repo.ID, 4)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, collab)
|
||||
assert.EqualValues(t, 4, collab.UserID)
|
||||
assert.EqualValues(t, 4, collab.RepoID)
|
||||
|
||||
// Non-existing collaboration.
|
||||
collab, err = repo_model.GetCollaboration(db.DefaultContext, repo.ID, 1)
|
||||
assert.NoError(t, err)
|
||||
assert.Nil(t, collab)
|
||||
}
|
||||
|
@ -64,10 +64,6 @@ func NewUserRedirect(ctx context.Context, ID int64, oldUserName, newUserName str
|
||||
oldUserName = strings.ToLower(oldUserName)
|
||||
newUserName = strings.ToLower(newUserName)
|
||||
|
||||
if err := DeleteUserRedirect(ctx, oldUserName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := DeleteUserRedirect(ctx, newUserName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -5,11 +5,9 @@ package packages
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/url"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/storage"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
)
|
||||
@ -33,14 +31,6 @@ func (s *ContentStore) Get(key BlobHash256Key) (storage.Object, error) {
|
||||
return s.store.Open(KeyToRelativePath(key))
|
||||
}
|
||||
|
||||
func (s *ContentStore) ShouldServeDirect() bool {
|
||||
return setting.Packages.Storage.MinioConfig.ServeDirect
|
||||
}
|
||||
|
||||
func (s *ContentStore) GetServeDirectURL(key BlobHash256Key, filename string) (*url.URL, error) {
|
||||
return s.store.URL(KeyToRelativePath(key), filename)
|
||||
}
|
||||
|
||||
// FIXME: Workaround to be removed in v1.20
|
||||
// https://github.com/go-gitea/gitea/issues/19586
|
||||
func (s *ContentStore) Has(key BlobHash256Key) error {
|
||||
|
@ -383,7 +383,7 @@ hi_user_x=Ahoj <b>%s</b>,
|
||||
|
||||
activate_account=Prosíme, aktivujte si váš účet
|
||||
activate_account.title=%s, prosím aktivujte si váš účet
|
||||
activate_account.text_1=Ahoj <b>%[1]s</b>, děkujeme za registraci na %[2]s!
|
||||
activate_account.text_1=Ahoj <b>%[1]s</b>, děkujeme za registraci na %[2]!
|
||||
activate_account.text_2=Pro aktivaci vašeho účtu do <b>%s</b> klikněte na následující odkaz:
|
||||
|
||||
activate_email=Ověřte vaši e-mailovou adresu
|
||||
@ -402,8 +402,8 @@ reset_password.text=Klikněte prosím na následující odkaz pro obnovení vaš
|
||||
|
||||
register_success=Registrace byla úspěšná
|
||||
|
||||
issue_assigned.pull=@%[1]s vás přiřadil/a k požadavku na natažení %[2]s repozitáři %[3]s.
|
||||
issue_assigned.issue=@%[1]s vás přiřadil/a k úkolu %[2]s repozitáři %[3]s.
|
||||
issue_assigned.pull=@%[1]s vás přiřadil/a k požadavku na natažení %[2]v repozitáři %[3]s.
|
||||
issue_assigned.issue=@%[1]s vás přiřadil/a k úkolu %[2]v repozitáři %[3]s.
|
||||
|
||||
issue.x_mentioned_you=<b>@%s</b> vás zmínil/a:
|
||||
issue.action.force_push=<b>%[1]s</b> vynutil/a nahrání <b>%[2]s</b> z %[3]s do %[4]s.
|
||||
@ -2310,7 +2310,7 @@ members.member_role=Role člena:
|
||||
members.owner=Vlastník
|
||||
members.member=Člen
|
||||
members.remove=Smazat
|
||||
members.remove.detail=Odstranit %[1]s z %[2]s?
|
||||
members.remove.detail=Odstranit %[1]s z %[2]?
|
||||
members.leave=Opustit
|
||||
members.leave.detail=Opustit %s?
|
||||
members.invite_desc=Přidat nového člena do %s:
|
||||
|
@ -19,7 +19,6 @@ active_stopwatch=Aktive Zeiterfassung
|
||||
create_new=Erstellen…
|
||||
user_profile_and_more=Profil und Einstellungen…
|
||||
signed_in_as=Angemeldet als
|
||||
enable_javascript=Diese Website benötigt JavaScript.
|
||||
toc=Inhaltsverzeichnis
|
||||
licenses=Lizenzen
|
||||
return_to_gitea=Zurück zu Gitea
|
||||
@ -93,7 +92,6 @@ copy_url=URL kopieren
|
||||
copy_branch=Branchenname kopieren
|
||||
copy_success=Kopiert!
|
||||
copy_error=Kopieren fehlgeschlagen
|
||||
copy_type_unsupported=Dieser Dateityp kann nicht kopiert werden
|
||||
|
||||
write=Verfassen
|
||||
preview=Vorschau
|
||||
@ -106,42 +104,22 @@ error=Fehler
|
||||
error404=Die Seite, die du gerade versuchst aufzurufen, <strong>existiert entweder nicht</strong> oder <strong>du bist nicht berechtigt</strong>, diese anzusehen.
|
||||
|
||||
never=Niemals
|
||||
unknown=Unbekannt
|
||||
|
||||
rss_feed=RSS Feed
|
||||
|
||||
|
||||
artifacts=Artefakte
|
||||
|
||||
concept_system_global=Global
|
||||
concept_code_repository=Repository
|
||||
concept_user_organization=Organisation
|
||||
|
||||
show_log_seconds=Sekunden anzeigen
|
||||
|
||||
[aria]
|
||||
footer.software=Über die Software
|
||||
footer.links=Links
|
||||
|
||||
[heatmap]
|
||||
less=Weniger
|
||||
more=Mehr
|
||||
|
||||
[editor]
|
||||
buttons.heading.tooltip=Titel hinzufügen
|
||||
buttons.quote.tooltip=Text zitieren
|
||||
buttons.code.tooltip=Code hinzufügen
|
||||
buttons.link.tooltip=Link hinzufügen
|
||||
buttons.list.ordered.tooltip=Nummerierte Liste hinzufügen
|
||||
buttons.list.task.tooltip=Aufgabenliste hinzufügen
|
||||
buttons.mention.tooltip=Benutzer oder Team erwähnen
|
||||
buttons.ref.tooltip=Issue oder Pull-Request referenzieren
|
||||
buttons.enable_monospace_font=Monospace-Schrift aktivieren
|
||||
buttons.disable_monospace_font=Monospace-Schrift deaktivieren
|
||||
|
||||
[filter]
|
||||
string.asc=A–Z
|
||||
string.desc=Z–A
|
||||
|
||||
[error]
|
||||
occurred=Ein Fehler ist aufgetreten
|
||||
@ -250,7 +228,6 @@ install_btn_confirm=Gitea installieren
|
||||
test_git_failed=Fehler beim Test des „git“-Befehls: %v
|
||||
sqlite3_not_available=Diese Gitea-Version unterstützt SQLite3 nicht. Bitte lade die offizielle binäre Version von %s herunter (nicht die „gobuild“-Version).
|
||||
invalid_db_setting=Datenbankeinstellungen sind ungültig: %v
|
||||
invalid_db_table=Die Datenbanktabelle "%s" ist ungültig: %v
|
||||
invalid_repo_path=Repository-Verzeichnis ist ungültig: %v
|
||||
invalid_app_data_path=Der App-Daten-Pfad ist ungültig: %v
|
||||
run_user_not_match=Der „Ausführen als“-Benutzername ist nicht der aktuelle Benutzername: %s -> %s
|
||||
@ -268,7 +245,6 @@ default_enable_timetracking_popup=Zeiterfassung standardmäßig für neue Reposi
|
||||
no_reply_address=Versteckte E-Mail-Domain
|
||||
no_reply_address_helper=Domain-Name für Benutzer mit einer versteckten Emailadresse. Zum Beispiel wird der Benutzername „Joe“ in Git als „joe@noreply.example.org“ protokolliert, wenn die versteckte E-Mail-Domain „noreply.example.org“ festgelegt ist.
|
||||
password_algorithm=Passwort Hashing Algorithmus
|
||||
invalid_password_algorithm=Ungültiger Passwort-Hash-Algorithmus
|
||||
|
||||
[home]
|
||||
uname_holder=E-Mail-Adresse oder Benutzername
|
||||
@ -303,7 +279,6 @@ users=Benutzer
|
||||
organizations=Organisationen
|
||||
search=Suche
|
||||
code=Code
|
||||
search.type.tooltip=Suchmodus
|
||||
search.fuzzy=Ähnlich
|
||||
search.match=Genau
|
||||
code_search_unavailable=Derzeit ist die Code-Suche nicht verfügbar. Bitte wende dich an den Website-Administrator.
|
||||
@ -570,7 +545,6 @@ location=Standort
|
||||
update_theme=Theme ändern
|
||||
update_profile=Profil aktualisieren
|
||||
update_language=Sprache aktualisieren
|
||||
update_language_not_found=Sprache "%s" ist nicht verfügbar.
|
||||
update_language_success=Sprache wurde aktualisiert.
|
||||
update_profile_success=Dein Profil wurde aktualisiert.
|
||||
change_username=Dein Benutzername wurde geändert.
|
||||
@ -681,7 +655,6 @@ gpg_token_help=Du kannst eine Signatur wie folgt generieren:
|
||||
gpg_token_code=echo "%s" | gpg -a --default-key %s --detach-sig
|
||||
gpg_token_signature=GPG Textsignatur (armored signature)
|
||||
key_signature_gpg_placeholder=Beginnt mit '-----BEGIN PGP SIGNATURE-----'
|
||||
verify_gpg_key_success=GPG-Schlüssel "%s" wurde verifiziert.
|
||||
ssh_key_verified=Verifizierter Schlüssel
|
||||
ssh_key_verified_long=Der Schlüssel wurde mit einem Token verifiziert. Er kann verwendet werden, um Commits zu verifizieren, die mit irgendeiner für diesen Nutzer aktivierten E-Mail-Adresse und irgendeiner Identität dieses Schlüssels übereinstimmen.
|
||||
ssh_key_verify=Verifizieren
|
||||
@ -1002,7 +975,6 @@ download_archive=Repository herunterladen
|
||||
no_desc=Keine Beschreibung
|
||||
quick_guide=Kurzanleitung
|
||||
clone_this_repo=Dieses Repository klonen
|
||||
cite_this_repo=Dieses Repository zitieren
|
||||
create_new_repo_command=Erstelle ein neues Repository von der Kommandozeile aus
|
||||
push_exist_repo=Bestehendes Repository via Kommandozeile pushen
|
||||
empty_message=Dieses Repository hat keinen Inhalt.
|
||||
@ -1021,7 +993,6 @@ issues=Issues
|
||||
pulls=Pull-Requests
|
||||
project_board=Projekte
|
||||
packages=Pakete
|
||||
actions=Actions
|
||||
labels=Label
|
||||
org_labels_desc=Labels der Organisationsebene, die mit <strong>allen Repositories</strong> in dieser Organisation verwendet werden können
|
||||
org_labels_desc_manage=verwalten
|
||||
@ -1041,7 +1012,6 @@ file_view_rendered=Ansicht rendern
|
||||
file_view_raw=Originalformat anzeigen
|
||||
file_permalink=Permalink
|
||||
file_too_large=Die Datei ist zu groß zum Anzeigen.
|
||||
invisible_runes_header=`Diese Datei enthält unsichtbare Unicode-Zeichen!`
|
||||
ambiguous_character=`%[1]c [U+%04[1]X] kann mit %[2]c [U+%04[2]X] verwechselt werden`
|
||||
|
||||
escape_control_characters=Escapen
|
||||
@ -1062,7 +1032,6 @@ download_file=Datei herunterladen
|
||||
normal_view=Normale Ansicht
|
||||
line=zeile
|
||||
lines=Zeilen
|
||||
from_comment=(Kommentar)
|
||||
|
||||
editor.add_file=Datei hinzufügen
|
||||
editor.new_file=Neue Datei
|
||||
@ -1077,7 +1046,6 @@ editor.must_be_on_a_branch=Du musst dich in einem Branch befinden, um Änderunge
|
||||
editor.fork_before_edit=Du musst dieses Repository forken, um Änderungen an dieser Datei vorzuschlagen oder vorzunehmen.
|
||||
editor.delete_this_file=Datei löschen
|
||||
editor.must_have_write_access=Du benötigst Schreibzugriff, um Änderungen an dieser Datei vorzuschlagen oder vorzunehmen.
|
||||
editor.file_delete_success=Datei "%s" wurde gelöscht.
|
||||
editor.name_your_file=Dateinamen eingeben…
|
||||
editor.filename_help=Füge einen Ordner hinzu, indem du seinen Namen und anschließend '/' eingibst. Entferne einen Ordner indem du die Zurücktaste am Anfang des Feldes drückst.
|
||||
editor.or=oder
|
||||
@ -1713,7 +1681,6 @@ activity.git_stats_deletion_n=%d Löschungen
|
||||
|
||||
search=Suchen
|
||||
search.search_repo=Repository durchsuchen
|
||||
search.type.tooltip=Suchmodus
|
||||
search.fuzzy=Ähnlich
|
||||
search.match=Genau
|
||||
search.results=Suchergebnisse für „%s“ in <a href="%s"> %s</a>
|
||||
@ -2191,8 +2158,6 @@ branch.delete_html=Branch löschen
|
||||
branch.delete_desc=Das Löschen eines Branches ist permanent. Es <strong>KANN NICHT</strong> rückgängig gemacht werden. Fortfahren?
|
||||
branch.create_branch=Erstelle Branch <strong>%s</strong>
|
||||
branch.deleted_by=Von %s gelöscht
|
||||
branch.restore=Branch "%s" wiederherstellen
|
||||
branch.download=Branch "%s" herunterladen
|
||||
branch.included_desc=Dieser Branch ist im Standard-Branch enthalten
|
||||
branch.included=Enthalten
|
||||
branch.create_new_branch=Branch aus Branch erstellen:
|
||||
@ -2200,15 +2165,12 @@ branch.confirm_create_branch=Branch erstellen
|
||||
branch.confirm_rename_branch=Branch umbennen
|
||||
branch.create_branch_operation=Branch erstellen
|
||||
branch.new_branch=Neue Branch erstellen
|
||||
branch.new_branch_from=Neuen Branch von "%s" erstellen
|
||||
branch.renamed=Branch %s wurde in %s umbenannt.
|
||||
|
||||
tag.create_tag=Tag <strong>%s</strong> erstellen
|
||||
tag.create_tag_operation=Tag erstellen
|
||||
tag.confirm_create_tag=Tag erstellen
|
||||
tag.create_tag_from=Neuen Tag von "%s" erstellen
|
||||
|
||||
tag.create_success=Tag "%s" wurde erstellt.
|
||||
|
||||
topic.manage_topics=Themen verwalten
|
||||
topic.done=Fertig
|
||||
@ -2445,7 +2407,6 @@ users.created=Registriert am
|
||||
users.last_login=Letzte Anmeldung
|
||||
users.never_login=Hat sich noch nie eingeloggt
|
||||
users.send_register_notify=Benutzer-Registrierungsbenachrichtigung senden
|
||||
users.new_success=Der Account "%s" wurde erstellt.
|
||||
users.edit=Bearbeiten
|
||||
users.auth_source=Authentifizierungsquelle
|
||||
users.local=Lokal
|
||||
@ -2809,7 +2770,7 @@ monitor.queue.review=Konfiguration überprüfen
|
||||
monitor.queue.review_add=Worker hinzufügen/prüfen
|
||||
monitor.queue.settings.title=Pool-Einstellungen
|
||||
monitor.queue.settings.maxnumberworkers=Maximale Anzahl an Workern
|
||||
monitor.queue.settings.maxnumberworkers.placeholder=Derzeit %[1]s
|
||||
monitor.queue.settings.maxnumberworkers.placeholder=Derzeit %[1]v
|
||||
monitor.queue.settings.maxnumberworkers.error=Die Anzahl der Worker muss eine Zahl sein
|
||||
monitor.queue.settings.submit=Einstellungen aktualisieren
|
||||
monitor.queue.settings.changed=Einstellungen aktualisiert
|
||||
@ -3018,7 +2979,6 @@ settings.delete.description=Das Löschen eines Pakets ist dauerhaft und kann nic
|
||||
settings.delete.notice=Du bist dabei, %s (%s) zu löschen. Dieser Vorgang ist unwiderruflich. Bist du sicher?
|
||||
settings.delete.success=Das Paket wurde gelöscht.
|
||||
settings.delete.error=Löschen des Pakets fehlgeschlagen.
|
||||
owner.settings.cargo.initialize=Index initialisieren
|
||||
owner.settings.cleanuprules.enabled=Aktiviert
|
||||
|
||||
[secrets]
|
||||
@ -3026,10 +2986,8 @@ value=Wert
|
||||
name=Name
|
||||
|
||||
[actions]
|
||||
actions=Actions
|
||||
|
||||
|
||||
status.unknown=Unbekannt
|
||||
|
||||
runners.id=ID
|
||||
runners.name=Name
|
||||
@ -3039,16 +2997,10 @@ runners.labels=Labels
|
||||
runners.task_list.run=Ausführen
|
||||
runners.task_list.repository=Repository
|
||||
runners.task_list.commit=Commit
|
||||
runners.status.unspecified=Unbekannt
|
||||
runners.status.idle=Inaktiv
|
||||
runners.status.active=Aktiv
|
||||
runners.status.offline=Offline
|
||||
runners.version=Version
|
||||
|
||||
runs.all_workflows=Alle Workflows
|
||||
runs.commit=Commit
|
||||
runs.pushed_by=Gepushed von
|
||||
runs.no_matching_runner_helper=Kein passender Runner: %s
|
||||
|
||||
|
||||
[projects]
|
||||
|
@ -408,7 +408,7 @@ hi_user_x=Γειά σου <b>%s</b>,
|
||||
|
||||
activate_account=Παρακαλώ ενεργοποιήστε το λογαριασμό σας
|
||||
activate_account.title=%s, παρακαλώ ενεργοποιήστε το λογαριασμό σας
|
||||
activate_account.text_1=Γεια σας <b>%[1]s</b>, ευχαριστούμε για την εγγραφή στο %[2]s!
|
||||
activate_account.text_1=Γεια σας <b>%[1]s</b>, ευχαριστούμε για την εγγραφή στο %[2]!
|
||||
activate_account.text_2=Παρακαλούμε κάντε κλικ στον παρακάτω σύνδεσμο για να ενεργοποιήσετε το λογαριασμό σας μέσα σε <b>%s</b>:
|
||||
|
||||
activate_email=Επιβεβαιώστε τη διεύθυνση email σας
|
||||
@ -462,7 +462,7 @@ repo.collaborator.added.subject=%s σας πρόσθεσε στο %s
|
||||
repo.collaborator.added.text=Έχετε προστεθεί ως συνεργάτης του αποθετηρίου:
|
||||
|
||||
team_invite.subject=%[1]s σας προσκάλεσε να συμμετέχετε στον οργανισμό %[2]s
|
||||
team_invite.text_1=%[1]s σας προσκάλεσε να συμμετέχετε στην ομάδα %[2]s στον οργανισμός %[3]s.
|
||||
team_invite.text_1=%[1]s σας προσκάλεσε να συμμετέχετε στην ομάδα %[2]s στον οργανισμός %[3].
|
||||
team_invite.text_2=Παρακαλώ κάντε κλικ στον παρακάτω σύνδεσμο για να συμμετάσχετε στην ομάδα:
|
||||
team_invite.text_3=Σημείωση: Αυτή η πρόσκληση προοριζόταν για %[1]s. Αν δεν περιμένατε αυτή την πρόσκληση, μπορείτε να αγνοήσετε αυτό το email.
|
||||
|
||||
|
@ -2650,7 +2650,7 @@ dashboard.task.finished=Task: %[1]s started by %[2]s has finished
|
||||
dashboard.task.unknown=Unknown task: %[1]s
|
||||
dashboard.cron.started=Started Cron: %[1]s
|
||||
dashboard.cron.process=Cron: %[1]s
|
||||
dashboard.cron.cancelled=Cron: %[1]s cancelled: %[3]s
|
||||
dashboard.cron.cancelled=Cron: %s cancelled: %[3]s
|
||||
dashboard.cron.error=Error in Cron: %s: %[3]s
|
||||
dashboard.cron.finished=Cron: %[1]s has finished
|
||||
dashboard.delete_inactive_accounts = Delete all unactivated accounts
|
||||
|
@ -357,7 +357,7 @@ reset_password.text=لطفاً روی پیوند زیر کلیک کنید تا
|
||||
|
||||
register_success=ثبتنام با موفقیت انجام شد
|
||||
|
||||
issue_assigned.pull=@%[1]s به شما برای درخواست pull %[2]s در ریپازیتوری %[3]s محول شده.
|
||||
issue_assigned.pull=@%[1] به شما برای درخواست pull %[2] در ریپازیتوری %[3] محول شده.
|
||||
issue_assigned.issue=@%[1]s به شما واگذار شده است برای صدور %[2]s در انبار %[3]s.
|
||||
|
||||
issue.x_mentioned_you=<b>@%s</b> به شما اشاره کرد:
|
||||
|
@ -803,7 +803,7 @@ issues.action_milestone=Tímamót
|
||||
issues.action_milestone_no_select=Ekkert tímamót
|
||||
issues.action_assignee=Úthlutað að
|
||||
issues.opened_by=opnað %[1]s af <a href="%[2]s">%[3]s</a>
|
||||
issues.opened_by_fake=opnað %[1]s af %[2]s
|
||||
issues.opened_by_fake=opnað %[1] af %[2]s
|
||||
issues.previous=Fyrri
|
||||
issues.next=Áfram
|
||||
issues.open_title=Opið
|
||||
|
@ -438,7 +438,7 @@ repo.collaborator.added.subject=%s pievienoja Jūs repozitorijam %s
|
||||
repo.collaborator.added.text=Jūs tikāt pievienots kā līdzstrādnieks repozitorijam:
|
||||
|
||||
team_invite.subject=%[1]s uzaicināja Jūs pievienoties organizācijai %[2]s
|
||||
team_invite.text_1=%[1]s uzaicināja Jūs pievienoties komandai %[2]s organizācijā %[3]s.
|
||||
team_invite.text_1=%[1]s uzaicināja Jūs pievienoties komandai %[2] organizācijā %[3]s.
|
||||
team_invite.text_2=Uzspiediet uz šīs saites, lai pievienoties komandai:
|
||||
team_invite.text_3=Piezīme: Šis uzaicinājums ir paredzēts %[1]s. Ja uzskatāt, ka tas nav domāts Jums, varat ignorēt šo e-pastu.
|
||||
|
||||
|
@ -384,7 +384,7 @@ reset_password.text=Klik op de volgende link om je account te herstellen binnen
|
||||
register_success=Registratie succesvol
|
||||
|
||||
issue_assigned.pull=@%[1]s heeft u toegewezen aan de pull request %[2]s in repository %[3]s.
|
||||
issue_assigned.issue=@%[1]s heeft u toegewezen aan issue %[2]s in repository %[3]s.
|
||||
issue_assigned.issue=@%[1]heeft u toegewezen aan issue %[2]s in repository %[3]s.
|
||||
|
||||
issue.x_mentioned_you=<b>@%s</b> heeft u vermeld:
|
||||
issue.action.force_push=<b>%[1]s</b> heeft een force-push uitgevoerd <b>%[2]s</b> van %[3]s naar %[4]s.
|
||||
@ -392,7 +392,7 @@ issue.action.push_1=<b>@%[1]s</b> heeft %[3]d commits gepusht naar %[2]s
|
||||
issue.action.push_n=<b>@%[1]s</b> heeft %[3]d commits gepusht naar %[2]s
|
||||
issue.action.close=<b>@%[1]s</b> sloot #%[2]d.
|
||||
issue.action.reopen=<b>@%[1]s</b> heropend #%[2]d.
|
||||
issue.action.merge=<b>@%[1]s</b> heeft een merge uitgevoerd van #%[2]d naar %[3]s.
|
||||
issue.action.merge=<b>@%[1]</b> heeft een merge uitgevoerd van #%[2]d naar %[3]s.
|
||||
issue.action.approve=<b>@%[1]s</b> heeft deze pull request goedgekeurd.
|
||||
issue.action.reject=<b>@%[1]s</b> vraagt om wijzigingen op deze pull request.
|
||||
issue.action.review=<b>@%[1]s</b> heeft gereageerd op deze pull request.
|
||||
|
@ -2494,7 +2494,7 @@ monitor.queue.review=Przejrzyj konfigurację
|
||||
monitor.queue.review_add=Przejrzyj/Dodaj procesy pracujące
|
||||
monitor.queue.settings.title=Ustawienia Puli
|
||||
monitor.queue.settings.maxnumberworkers=Maksymalna liczba procesów pracujących
|
||||
monitor.queue.settings.maxnumberworkers.placeholder=Obecnie %[1]d
|
||||
monitor.queue.settings.maxnumberworkers.placeholder=Obecnie %[1]v
|
||||
monitor.queue.settings.maxnumberworkers.error=Maksymalna liczba procesów pracujących musi być liczbą
|
||||
monitor.queue.settings.submit=Aktualizuj ustawienia
|
||||
monitor.queue.settings.changed=Zaktualizowano ustawienia
|
||||
|
@ -437,7 +437,7 @@ reset_password.text=Por favor clique no link a seguir para recuperar sua conta e
|
||||
|
||||
register_success=Cadastro bem-sucedido
|
||||
|
||||
issue_assigned.pull=@%[1]s atribuiu a você o pull request %[2]s no repositório %[3]s.
|
||||
issue_assigned.pull=@%[1]atribuiu a você o pull request %[2]s no repositório %[3]s.
|
||||
issue_assigned.issue=@%[1]s atribuiu a você a issue %[2]s no repositório %[3]s.
|
||||
|
||||
issue.x_mentioned_you=<b>@%s</b> mencionou você:
|
||||
@ -1535,7 +1535,7 @@ issues.due_date_form_remove=Remover
|
||||
issues.due_date_not_writer=Você deve ter permissão de escrita no repositório para atualizar a data limite de uma issue.
|
||||
issues.due_date_not_set=Data limite não informada.
|
||||
issues.due_date_added=adicionou a data limite %s %s
|
||||
issues.due_date_modified=modificou a data limite de %[2]s para %[1]s %[3]s
|
||||
issues.due_date_modified=modificou a data limite de %[2]para %[1]s %[3]s
|
||||
issues.due_date_remove=removeu a data limite %s %s
|
||||
issues.due_date_overdue=Em atraso
|
||||
issues.due_date_invalid=A data limite é inválida ou está fora do intervalo. Por favor, use o formato 'dd/mm/aaaa'.
|
||||
@ -2557,7 +2557,7 @@ dashboard.clean_unbind_oauth_success=Todas as conexões de OAuth não vinculadas
|
||||
dashboard.task.started=Tarefa Iniciada: %[1]s
|
||||
dashboard.task.process=Tarefa: %[1]s
|
||||
dashboard.task.cancelled=Tarefa: %[1]s cancelada: %[3]s
|
||||
dashboard.task.error=Erro na Tarefa: %[1]s: %[3]s
|
||||
dashboard.task.error=Erro na Tarefa: %[1]: %[3]s
|
||||
dashboard.task.finished=Tarefa: %[1]s iniciada por %[2]s foi finalizada
|
||||
dashboard.task.unknown=Tarefa desconhecida: %[1]s
|
||||
dashboard.cron.started=Cron Iniciado: %[1]s
|
||||
|
@ -472,7 +472,7 @@ repo.transfer.body=Для того чтобы принять или отклон
|
||||
repo.collaborator.added.subject=%s добавил(а) вас в %s
|
||||
repo.collaborator.added.text=Вы были добавлены в качестве соавтора репозитория:
|
||||
|
||||
team_invite.subject=%[1]s приглашает вас присоединиться к организации %[2]s
|
||||
team_invite.subject=%[1] приглашает вас присоединиться к организации %[2]
|
||||
team_invite.text_1=%[1]s приглашает вас присоединиться к команде %[2]s в организации %[3]s.
|
||||
team_invite.text_2=Перейдите по ссылке, чтобы присоединиться к команде:
|
||||
team_invite.text_3=Примечание: Это приглашение было направлено для %[1]s. Если вы не ожидали этого приглашения, можете проигнорировать это письмо.
|
||||
|
@ -353,17 +353,17 @@ issue.action.push_1=<b>@%[1]s</b> pushed%[3]d%[2]s කිරීමට කැප
|
||||
issue.action.push_n=<b>@%[1]s</b> pushed%[3]d%[2]s දක්වා කැපේ
|
||||
issue.action.close=<b>@%[1]s</b> වසා #%[2]d.
|
||||
issue.action.reopen=<b>@%[1]s</b> නැවත විවෘත කරන ලද #%[2]d.
|
||||
issue.action.merge=<b>@%[1]s ගේ</b> ඒකාබද්ධ #%[2]d ඈ into%[3]s.
|
||||
issue.action.merge=<b>@%[1]ගේ</b> ඒකාබද්ධ #%[2]ඈ into%[3]s.
|
||||
issue.action.approve=<b>@%[1]s</b> මෙම අදින්න ඉල්ලීම අනුමත.
|
||||
issue.action.reject=<b>@%[1]s</b> මෙම අදින්න ඉල්ලීම මත වෙනස්කම් ඉල්ලා.
|
||||
issue.action.review=<b>@%[1]s</b> මෙම අදින්න ඉල්ලීම පිළිබඳව අදහස් දැක්වීය.
|
||||
issue.action.review_dismissed=<b>@%[1]s</b> මෙම අදින්න ඉල්ලීම සඳහා%[2]s සිට පසුගිය සමාලෝචනය බැහැර.
|
||||
issue.action.ready_for_review=<b>@%[1]s</b> සමාලෝචනය සඳහා සූදානම් මෙම අදින්න ඉල්ලීම සලකුණු.
|
||||
issue.action.new=<b>@%[1]s ගේ</b> නිර්මාණය #%[2]d ඈ.
|
||||
issue.action.new=<b>@%[1]ගේ</b> නිර්මාණය #%[2]ඈ.
|
||||
issue.in_tree_path=%sදී:
|
||||
|
||||
release.new.subject=%s %s නිදහස්
|
||||
release.new.text=<b>@%[1]s හි</b> නිකුතුව%[2]s හි %[3]s හි
|
||||
release.new.text=<b>@%[1]හි</b> නිකුතුව%[2]හි[3]හි
|
||||
release.title=සිරැසිය: %s
|
||||
release.note=සටහන:
|
||||
release.downloads=බාගැනීම්:
|
||||
@ -844,7 +844,7 @@ migrate.permission_denied_blocked=ඔබට අවසර නොලත් ධා
|
||||
migrate.invalid_lfs_endpoint=මෙම LFS අවසන් ලක්ෂ්යය වලංගු නොවේ.
|
||||
migrate.failed=සංක්රමණය අසාර්ථකයි: %v
|
||||
migrate.migrate_items_options=අමතර අයිතම සංක්රමණය කිරීම සඳහා ප්රවේශ ටෝකනය අවශ්ය වේ
|
||||
migrated_from=<a href="%[1]s">%[2]s සිට</a>දක්වා සංක්රමණය වී ඇත
|
||||
migrated_from=<a href="%[1]s">%[2]සිට</a>දක්වා සංක්රමණය වී ඇත
|
||||
migrated_from_fake=සංක්රමණය වූ ගෙම්%[1]s
|
||||
migrate.migrate=%sසිට සංක්රමණය
|
||||
migrate.migrating=<b>%s</b> සිට සංක්රමණය වීම...
|
||||
@ -1071,7 +1071,7 @@ issues.remove_ref_at=`ඉවත් කරන ලද යොමු <b>%s</b> %s`
|
||||
issues.add_ref_at=`එකතු කරන ලද යොමු <b>%s</b> %s`
|
||||
issues.delete_branch_at=`මකාදැමූ ශාඛාව <b>%s</b> %s`
|
||||
issues.filter_label=ලේබලය
|
||||
issues.filter_label_exclude=ලේබල බැහැර කිරීමට <code>alt</code> + <code>click/enter</code> භාවිත කරන්න
|
||||
issues.filter_label_exclude=Labels` ඉවත් කිරීමට <code>alt</code> + <code>ක්ලික් කරන්න/ඇතුළු කරන්න</code>
|
||||
issues.filter_label_no_select=සියලු ලේබල
|
||||
issues.filter_label_select_no_label=ලේබලයක් නැත
|
||||
issues.filter_milestone=සන්ධිස්ථානය
|
||||
@ -1127,7 +1127,7 @@ issues.reopen_comment_issue=අදහස් දක්වා විවෘත ක
|
||||
issues.create_comment=අදහස
|
||||
issues.closed_at=`මෙම ගැටළුව වසා <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.reopened_at=`මෙම ගැටළුව නැවත විවෘත කරන ලදි <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.ref_issue_from=<a href="%[3]s">මෙම නිකුතුව %[4]s හි</a> <a id="%[1]s" href="#%[1]s">%[2]s</a>
|
||||
issues.ref_issue_from=<a href="%[3]s">මෙම නිකුතුව%[4]හි</a> <a id="%[1]s" href="#%[1]s">%[2]s</a>
|
||||
issues.ref_pull_from=<a href="%[3]s">මෙම අදින්න ඉල්ලීම%[4]s</a> <a id="%[1]s" href="#%[1]s">%[2]s</a>
|
||||
issues.ref_closing_from=<a href="%[3]s">මෙම ගැටළුව වසා දමනු ඇත%[4]s මෙම ගැටළුව</a> <a id="%[1]s" href="#%[1]s">%[2]s</a>
|
||||
issues.ref_reopening_from=<a href="%[3]s">මෙම ගැටළුව නැවත විවෘත කරනු ඇත%[4]s මෙම ගැටළුව</a> <a id="%[1]s" href="#%[1]s">%[2]s</a>
|
||||
@ -1214,7 +1214,7 @@ issues.error_modifying_due_date=නියමිත දිනය වෙනස්
|
||||
issues.error_removing_due_date=නියමිත දිනය ඉවත් කිරීමට අපොහොසත් විය.
|
||||
issues.push_commit_1=එකතු %d කැප %s
|
||||
issues.push_commits_n=එකතු %d විවරයන් %s
|
||||
issues.force_push_codes=`බලය-pushed%[1]s සිට <a class="ui sha" href="%[3]s"><code>%[2]s</code></a> <a class="ui sha" href="%[5]s"><code>%[4]s ගේ</code></a> %[6]s`
|
||||
issues.force_push_codes=`බලය-pushed%[1]s සිට <a class="ui sha" href="%[3]s"><code>%[2]s</code></a> <a class="ui sha" href="%[5]s"><code>%[4]ගේ</code></a> %[6]s`
|
||||
issues.force_push_compare=සසඳන්න
|
||||
issues.due_date_form=Yyy-mm-dd
|
||||
issues.due_date_form_add=නියමිත දිනය එකතු කරන්න
|
||||
@ -2039,7 +2039,7 @@ members.member_role=සාමාජික කාර්යභාරය:
|
||||
members.owner=හිමිකරු
|
||||
members.member=සාමාජික
|
||||
members.remove=ඉවත් කරන්න
|
||||
members.remove.detail=%[1]s ගේ සිට%[2]s ගේ ඉවත්?
|
||||
members.remove.detail=%[1]ගේ සිට%[2]ගේ ඉවත්?
|
||||
members.leave=හැරයන්න
|
||||
members.leave.detail=%s හැරයනවාද?
|
||||
members.invite_desc=%sවෙත නව සාමාජිකයෙකු එක් කරන්න:
|
||||
@ -2111,7 +2111,7 @@ dashboard.clean_unbind_oauth=පිරිසිදු නොබැඳි OAUTH
|
||||
dashboard.clean_unbind_oauth_success=සියලුම නොබැඳි OAUTH සම්බන්ධතා මකා දමා ඇත.
|
||||
dashboard.task.started=ආරම්භ කාර්යය:%[1]s
|
||||
dashboard.task.process=කාර්යය:%[1]s
|
||||
dashboard.task.cancelled=කාර්යය: %[1]s ගේ අවලංගු: %[3]s ගේ
|
||||
dashboard.task.cancelled=කාර්යය:%[1]ගේ අවලංගු:%[3]ගේ
|
||||
dashboard.task.error=කාර්යයයේ දෝෂය:%[1]s:%[3]s
|
||||
dashboard.task.finished=කාර්යය:%[1]s[2]s විසින් ආරම්භ කර ඇත
|
||||
dashboard.task.unknown=නොදන්නා කාර්යය:%[1]s
|
||||
@ -2551,16 +2551,16 @@ comment_issue=`නිකුතුව පිළිබඳ අදහස් <a href=
|
||||
comment_pull=`අදින්න ඉල්ලීම මත අදහස් <a href="%[1]s">%[3]s #%[2]s</a>`
|
||||
merge_pull_request=`ඒකාබද්ධ අදින්න ඉල්ලීම <a href="%[1]s">%[3]s #%[2]s</a>`
|
||||
transfer_repo=මාරු කරන ලද ගබඩාව <code>%s</code> සිට <a href="%s">%s</a>
|
||||
push_tag=තල්ලු ටැගය <a href="%[2]s">%[3]s ගේ</a> <a href="%[1]s">%[4]s ගේ</a>
|
||||
delete_tag=මකාදැමුවා ටැගය%[2]s සිට <a href="%[1]s">%[3]s</a>
|
||||
delete_branch=මකාදැමූ ශාඛාව %[2]s සිට <a href="%[1]s">%[3]s</a>
|
||||
push_tag=තල්ලු ටැගය <a href="%[2]s">%[3]ගේ</a> <a href="%[1]s">%[4]ගේ</a>
|
||||
delete_tag=මකාදැමුවා ටැගය%[2]සිට <a href="%[1]s">%[3]s</a>
|
||||
delete_branch=මකාදැමූ ශාඛාව%[2]සිට <a href="%[1]s">%[3]s</a>
|
||||
compare_branch=සසඳන්න
|
||||
compare_commits=%d විවරයන් සසඳා බලන්න
|
||||
compare_commits_general=විවරයන් සසඳා බලන්න
|
||||
mirror_sync_push=සමමුහුර්ත <a href="%[2]s">%[3]s</a> ට <a href="%[1]s">%[4]s</a> කැඩපත සිට
|
||||
mirror_sync_create=සමමුහුර්ත නව යොමු <a href="%[2]s">%[3]s</a> සිට <a href="%[1]s">%[4]s</a> කැඩපත සිට
|
||||
mirror_sync_delete=සමමුහුර්ත සහ මකාදැමූ යොමු <code>%[2]s</code> හි <a href="%[1]s">%[3]s</a> කැඩපතෙන්
|
||||
approve_pull_request=`අනුමත <a href="%[1]s">%[3]s #%[2]s ගේ</a>`
|
||||
approve_pull_request=`අනුමත <a href="%[1]s">%[3]s #%[2]ගේ</a>`
|
||||
reject_pull_request=<a href="%[1]s">%[3]s #%[2]s</a>සඳහා යෝජිත වෙනස්කම්
|
||||
publish_release=`නිදහස් <a href="%[2]s"> "%[4]s" </a> හි <a href="%[1]s">%[3]s</a>`
|
||||
review_dismissed_reason=හේතුව:
|
||||
|
@ -382,7 +382,7 @@ reset_password.text=Pre obnovenie vašeho účtu kliknite, prosím, na nasledovn
|
||||
|
||||
register_success=Registrácia prebehla úspešne
|
||||
|
||||
issue_assigned.pull=@%[1]s vám pridelil pull request %[2]s repozitári %[3]s.
|
||||
issue_assigned.pull=@%[1]s vám pridelil pull request %[2] v repozitári %[3]s.
|
||||
issue_assigned.issue=@%[1]s vám pridelil úkol %[2]s v repozitári %[3]s.
|
||||
|
||||
issue.x_mentioned_you=<b>@%s</b> vás zmienil:
|
||||
@ -397,7 +397,7 @@ issue.action.reject=<b>@%[1]s</b> požadoval zmeny v tomto pull requeste.
|
||||
issue.action.review=<b>@%[1]s</b> okomentoval tento pull request.
|
||||
issue.action.review_dismissed=<b>@%[1]s</b> zamietol poslednú recenziu od %[2]s pre tento pull request.
|
||||
issue.action.ready_for_review=<b>@%[1]s</b> označil tento pull request ako pripravený na revíziu.
|
||||
issue.action.new=<b>@%[1]s</b> vytvoril/a #%[2]d.
|
||||
issue.action.new=<b>@%[1]</b> vytvoril/a #%[2]d.
|
||||
issue.in_tree_path=V %s:
|
||||
|
||||
release.new.subject=%s v %s vydané
|
||||
|
@ -461,10 +461,10 @@ repo.transfer.body=Kabul veya reddetmek için %s ziyaret edin veya görmezden ge
|
||||
repo.collaborator.added.subject=%s sizi %s ekledi
|
||||
repo.collaborator.added.text=Bu depo için katkıcı olarak eklendiniz:
|
||||
|
||||
team_invite.subject=%[1]s sizi %[2]s organizasyonuna katılmaya davet etti
|
||||
team_invite.text_1=%[1]s sizi %[3]s organizasyonundaki %[2]s takımına katılmaya davet etti.
|
||||
team_invite.subject=%[1] sizi %[2] organizasyonuna katılmaya davet etti
|
||||
team_invite.text_1=%[1] sizi %[3] organizasyonundaki %[2] takımına katılmaya davet etti.
|
||||
team_invite.text_2=Takıma katılmak lütfen aşağıdaki bağlantıya tıklayın:
|
||||
team_invite.text_3=Not: Bu davet %[1]s içindi. Bu daveti beklemiyorsanız, e-postayı yok sayabilirsiniz.
|
||||
team_invite.text_3=Not: Bu davet %[1] içindi. Bu daveti beklemiyorsanız, e-postayı yok sayabilirsiniz.
|
||||
|
||||
[modal]
|
||||
yes=Evet
|
||||
|
@ -1182,10 +1182,10 @@ issues.create_comment=Коментар
|
||||
issues.closed_at=`закрив цю задачу <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.reopened_at=`повторно відкрив цю задачу <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.commit_ref_at=`згадано цю задачу в коміті <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.ref_issue_from=`<a href="%[3]s">посилання на цю задачу %[4]s</a> <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.ref_issue_from=`<a href="%[3]s">посилання на цю задачу %[4]</a> <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.ref_pull_from=`<a href="%[3]s">послався на цей запит злиття %[4]s</a> <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.ref_closing_from=`<a href="%[3]s">згадав запит на злиття %[4]s, які закриють цю задачу</a> <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.ref_reopening_from=`<a href="%[3]s">згадав запит на злиття %[4]s, які повторно відкриють цю задачу</a> <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.ref_closing_from=`<a href="%[3]s">згадав запит на злиття %[4]с, які закриють цю задачу</a> <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.ref_reopening_from=`<a href="%[3]s">згадав запит на злиття %[4]с, які повторно відкриють цю задачу</a> <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.ref_closed_from=`<a href="%[3]s">закрив цю задачу %[4]s</a> <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.ref_reopened_from=`<a href="%[3]s">повторно відкрито цю задачу %[4]s</a> <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||
issues.ref_from=`із %[1]s`
|
||||
@ -1269,7 +1269,7 @@ issues.error_modifying_due_date=Не вдалося змінити дату за
|
||||
issues.error_removing_due_date=Не вдалося видалити дату завершення.
|
||||
issues.push_commit_1=додав %d коміт %s
|
||||
issues.push_commits_n=додав %d коміти(-ів) %s
|
||||
issues.force_push_codes=`примусово залито %[1]s з <a class="ui sha" href="%[3]s"><code>%[2]s</code></a> до <a class="ui sha" href="%[5]s"><code>%[4]s</code></a> %[6]s`
|
||||
issues.force_push_codes=`примусово залито %[1]s з <a class="ui sha" href="%[3]s"><code>%[2]</code></a> до <a class="ui sha" href="%[5]s"><code>%[4]s</code></a> %[6]s`
|
||||
issues.force_push_compare=Порівняти
|
||||
issues.due_date_form=рррр-мм-дд
|
||||
issues.due_date_form_add=Додати дату завершення
|
||||
@ -2613,7 +2613,7 @@ comment_issue=`прокоментував задачу <a href="%[1]s">%[3]s#%[2
|
||||
comment_pull=`прокоментував запит злиття <a href="%[1]s">%[3]s#%[2]s</a>`
|
||||
merge_pull_request=`прийняв запит злиття <a href="%[1]s">%[3]s#%[2]s</a>`
|
||||
transfer_repo=перенесено репозиторій <code>%s</code> у <a href="%s">%s</a>
|
||||
push_tag=створив мітку <a href="%[2]s">%[3]s</a> в <a href="%[1]s">%[4]s</a>
|
||||
push_tag=створив мітку <a href="%[2]s">%[3]</a> в <a href="%[1]s">%[4]s</a>
|
||||
delete_tag=видалено мітку %[2]s з <a href="%[1]s">%[3]s</a>
|
||||
delete_branch=видалено гілку %[2]s з <a href="%[1]s">%[3]s</a>
|
||||
compare_branch=Порівняти
|
||||
@ -2622,14 +2622,14 @@ compare_commits_general=Порівняти коміти
|
||||
mirror_sync_push=синхронізував коміти в <a href="%[2]s">%[3]s</a> в <a href="%[1]s">%[4]s</a> із дзеркала
|
||||
mirror_sync_create=синхронізував нове посилання <a href="%[2]s">%[3]s</a> в <a href="%[1]s">%[4]s</a> із дзеркала
|
||||
mirror_sync_delete=синхронізовано й видалено посилання <code>%[2]s</code> на <a href="%[1]s">%[3]s</a> із дзеркала
|
||||
approve_pull_request=`схвалив <a href="%[1]s">%[3]s#%[2]s</a>`
|
||||
approve_pull_request=`схвалив <a href="%[1]s">%[3]s#%[2]</a>`
|
||||
reject_pull_request=`запропонував зміни до <a href="%[1]s">%[3]s#%[2]s</a>`
|
||||
publish_release=`опублікував випуск <a href="%[2]s"> "%[4]s" </a> з <a href="%[1]s">%[3]s</a>`
|
||||
review_dismissed=`відхилив відгук від <b>%[4]s</b> для <a href="%[1]s">%[3]s#%[2]s</a>`
|
||||
review_dismissed=`відхилив відгук від <b>%[4]</b> для <a href="%[1]s">%[3]s#%[2]s</a>`
|
||||
review_dismissed_reason=Причина:
|
||||
create_branch=створив гілку <a href="%[2]s">%[3]s</a> в <a href="%[1]s">%[4]s</a>
|
||||
starred_repo=додав <a href="%[1]s">%[2]s</a> у обране
|
||||
watched_repo=почав слідкувати за <a href="%[1]s">%[2]s</a>
|
||||
watched_repo=почав слідкувати за <a href="%[1]s">%[2]</a>
|
||||
|
||||
[tool]
|
||||
now=зараз
|
||||
|
@ -68,7 +68,7 @@ func GetRepositoryFile(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
s, u, pf, err := packages_service.GetFileStreamByPackageVersion(
|
||||
s, pf, err := packages_service.GetFileStreamByPackageVersion(
|
||||
ctx,
|
||||
pv,
|
||||
&packages_service.PackageFileInfo{
|
||||
@ -84,8 +84,12 @@ func GetRepositoryFile(ctx *context.Context) {
|
||||
}
|
||||
return
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
helper.ServePackageFile(ctx, s, u, pf)
|
||||
ctx.ServeContent(s, &context.ServeHeaderOptions{
|
||||
Filename: pf.Name,
|
||||
LastModified: pf.CreatedUnix.AsLocalTime(),
|
||||
})
|
||||
}
|
||||
|
||||
func UploadPackageFile(ctx *context.Context) {
|
||||
@ -196,7 +200,7 @@ func DownloadPackageFile(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
s, u, pf, err := packages_service.GetPackageFileStream(ctx, pfs[0])
|
||||
s, pf, err := packages_service.GetPackageFileStream(ctx, pfs[0])
|
||||
if err != nil {
|
||||
if errors.Is(err, util.ErrNotExist) {
|
||||
apiError(ctx, http.StatusNotFound, err)
|
||||
@ -205,8 +209,12 @@ func DownloadPackageFile(ctx *context.Context) {
|
||||
}
|
||||
return
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
helper.ServePackageFile(ctx, s, u, pf)
|
||||
ctx.ServeContent(s, &context.ServeHeaderOptions{
|
||||
Filename: pf.Name,
|
||||
LastModified: pf.CreatedUnix.AsLocalTime(),
|
||||
})
|
||||
}
|
||||
|
||||
func DeletePackageFile(ctx *context.Context) {
|
||||
|
@ -165,7 +165,7 @@ func ListOwners(ctx *context.Context) {
|
||||
|
||||
// DownloadPackageFile serves the content of a package
|
||||
func DownloadPackageFile(ctx *context.Context) {
|
||||
s, u, pf, err := packages_service.GetFileStreamByPackageNameAndVersion(
|
||||
s, pf, err := packages_service.GetFileStreamByPackageNameAndVersion(
|
||||
ctx,
|
||||
&packages_service.PackageInfo{
|
||||
Owner: ctx.Package.Owner,
|
||||
@ -185,8 +185,12 @@ func DownloadPackageFile(ctx *context.Context) {
|
||||
apiError(ctx, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
helper.ServePackageFile(ctx, s, u, pf)
|
||||
ctx.ServeContent(s, &context.ServeHeaderOptions{
|
||||
Filename: pf.Name,
|
||||
LastModified: pf.CreatedUnix.AsLocalTime(),
|
||||
})
|
||||
}
|
||||
|
||||
// https://doc.rust-lang.org/cargo/reference/registries.html#publish
|
||||
|
@ -341,13 +341,17 @@ func DownloadPackage(ctx *context.Context) {
|
||||
|
||||
pf := pd.Files[0].File
|
||||
|
||||
s, u, _, err := packages_service.GetPackageFileStream(ctx, pf)
|
||||
s, _, err := packages_service.GetPackageFileStream(ctx, pf)
|
||||
if err != nil {
|
||||
apiError(ctx, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
helper.ServePackageFile(ctx, s, u, pf)
|
||||
ctx.ServeContent(s, &context.ServeHeaderOptions{
|
||||
Filename: pf.Name,
|
||||
LastModified: pf.CreatedUnix.AsLocalTime(),
|
||||
})
|
||||
}
|
||||
|
||||
// https://github.com/chef/chef/blob/main/knife/lib/chef/knife/supermarket_unshare.rb
|
||||
|
@ -162,7 +162,7 @@ func PackageMetadata(ctx *context.Context) {
|
||||
|
||||
// DownloadPackageFile serves the content of a package
|
||||
func DownloadPackageFile(ctx *context.Context) {
|
||||
s, u, pf, err := packages_service.GetFileStreamByPackageNameAndVersion(
|
||||
s, pf, err := packages_service.GetFileStreamByPackageNameAndVersion(
|
||||
ctx,
|
||||
&packages_service.PackageInfo{
|
||||
Owner: ctx.Package.Owner,
|
||||
@ -182,8 +182,12 @@ func DownloadPackageFile(ctx *context.Context) {
|
||||
apiError(ctx, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
helper.ServePackageFile(ctx, s, u, pf)
|
||||
ctx.ServeContent(s, &context.ServeHeaderOptions{
|
||||
Filename: pf.Name,
|
||||
LastModified: pf.CreatedUnix.AsLocalTime(),
|
||||
})
|
||||
}
|
||||
|
||||
// UploadPackage creates a new package
|
||||
|
@ -453,7 +453,7 @@ func downloadFile(ctx *context.Context, fileFilter container.Set[string], fileKe
|
||||
return
|
||||
}
|
||||
|
||||
s, u, pf, err := packages_service.GetFileStreamByPackageNameAndVersion(
|
||||
s, pf, err := packages_service.GetFileStreamByPackageNameAndVersion(
|
||||
ctx,
|
||||
&packages_service.PackageInfo{
|
||||
Owner: ctx.Package.Owner,
|
||||
@ -474,8 +474,12 @@ func downloadFile(ctx *context.Context, fileFilter container.Set[string], fileKe
|
||||
apiError(ctx, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
helper.ServePackageFile(ctx, s, u, pf)
|
||||
ctx.ServeContent(s, &context.ServeHeaderOptions{
|
||||
Filename: pf.Name,
|
||||
LastModified: pf.CreatedUnix.AsLocalTime(),
|
||||
})
|
||||
}
|
||||
|
||||
// DeleteRecipeV1 deletes the requested recipe(s)
|
||||
|
@ -292,11 +292,15 @@ func DownloadPackageFile(ctx *context.Context) {
|
||||
|
||||
pf := pfs[0]
|
||||
|
||||
s, u, _, err := packages_service.GetPackageFileStream(ctx, pf)
|
||||
s, _, err := packages_service.GetPackageFileStream(ctx, pf)
|
||||
if err != nil {
|
||||
apiError(ctx, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
helper.ServePackageFile(ctx, s, u, pf)
|
||||
ctx.ServeContent(s, &context.ServeHeaderOptions{
|
||||
Filename: pf.Name,
|
||||
LastModified: pf.CreatedUnix.AsLocalTime(),
|
||||
})
|
||||
}
|
||||
|
@ -482,7 +482,22 @@ func GetBlob(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
serveBlob(ctx, blob)
|
||||
s, _, err := packages_service.GetPackageFileStream(ctx, blob.File)
|
||||
if err != nil {
|
||||
apiError(ctx, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
setResponseHeaders(ctx.Resp, &containerHeaders{
|
||||
ContentDigest: blob.Properties.GetByName(container_module.PropertyDigest),
|
||||
ContentType: blob.Properties.GetByName(container_module.PropertyMediaType),
|
||||
ContentLength: blob.Blob.Size,
|
||||
Status: http.StatusOK,
|
||||
})
|
||||
if _, err := io.Copy(ctx.Resp, s); err != nil {
|
||||
log.Error("Error whilst copying content to response: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#deleting-blobs
|
||||
@ -621,7 +636,22 @@ func GetManifest(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
serveBlob(ctx, manifest)
|
||||
s, _, err := packages_service.GetPackageFileStream(ctx, manifest.File)
|
||||
if err != nil {
|
||||
apiError(ctx, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
setResponseHeaders(ctx.Resp, &containerHeaders{
|
||||
ContentDigest: manifest.Properties.GetByName(container_module.PropertyDigest),
|
||||
ContentType: manifest.Properties.GetByName(container_module.PropertyMediaType),
|
||||
ContentLength: manifest.Blob.Size,
|
||||
Status: http.StatusOK,
|
||||
})
|
||||
if _, err := io.Copy(ctx.Resp, s); err != nil {
|
||||
log.Error("Error whilst copying content to response: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#deleting-tags
|
||||
@ -656,36 +686,6 @@ func DeleteManifest(ctx *context.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
func serveBlob(ctx *context.Context, pfd *packages_model.PackageFileDescriptor) {
|
||||
s, u, _, err := packages_service.GetPackageBlobStream(ctx, pfd.File, pfd.Blob)
|
||||
if err != nil {
|
||||
apiError(ctx, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
headers := &containerHeaders{
|
||||
ContentDigest: pfd.Properties.GetByName(container_module.PropertyDigest),
|
||||
ContentType: pfd.Properties.GetByName(container_module.PropertyMediaType),
|
||||
ContentLength: pfd.Blob.Size,
|
||||
Status: http.StatusOK,
|
||||
}
|
||||
|
||||
if u != nil {
|
||||
headers.Status = http.StatusTemporaryRedirect
|
||||
headers.Location = u.String()
|
||||
|
||||
setResponseHeaders(ctx.Resp, headers)
|
||||
return
|
||||
}
|
||||
|
||||
defer s.Close()
|
||||
|
||||
setResponseHeaders(ctx.Resp, headers)
|
||||
if _, err := io.Copy(ctx.Resp, s); err != nil {
|
||||
log.Error("Error whilst copying content to response: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#content-discovery
|
||||
func GetTagList(ctx *context.Context) {
|
||||
image := ctx.Params("image")
|
||||
|
@ -249,7 +249,7 @@ func downloadPackageFile(ctx *context.Context, opts *cran_model.SearchOptions) {
|
||||
return
|
||||
}
|
||||
|
||||
s, u, _, err := packages_service.GetPackageFileStream(ctx, pf)
|
||||
s, _, err := packages_service.GetPackageFileStream(ctx, pf)
|
||||
if err != nil {
|
||||
if errors.Is(err, util.ErrNotExist) {
|
||||
apiError(ctx, http.StatusNotFound, err)
|
||||
@ -258,6 +258,10 @@ func downloadPackageFile(ctx *context.Context, opts *cran_model.SearchOptions) {
|
||||
}
|
||||
return
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
helper.ServePackageFile(ctx, s, u, pf)
|
||||
ctx.ServeContent(s, &context.ServeHeaderOptions{
|
||||
Filename: pf.Name,
|
||||
LastModified: pf.CreatedUnix.AsLocalTime(),
|
||||
})
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ func GetRepositoryFile(ctx *context.Context) {
|
||||
key += "|" + component + "|" + architecture
|
||||
}
|
||||
|
||||
s, u, pf, err := packages_service.GetFileStreamByPackageVersion(
|
||||
s, pf, err := packages_service.GetFileStreamByPackageVersion(
|
||||
ctx,
|
||||
pv,
|
||||
&packages_service.PackageFileInfo{
|
||||
@ -75,8 +75,12 @@ func GetRepositoryFile(ctx *context.Context) {
|
||||
}
|
||||
return
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
helper.ServePackageFile(ctx, s, u, pf)
|
||||
ctx.ServeContent(s, &context.ServeHeaderOptions{
|
||||
Filename: pf.Name,
|
||||
LastModified: pf.CreatedUnix.AsLocalTime(),
|
||||
})
|
||||
}
|
||||
|
||||
// https://wiki.debian.org/DebianRepository/Format#indices_acquisition_via_hashsums_.28by-hash.29
|
||||
@ -106,7 +110,7 @@ func GetRepositoryFileByHash(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
s, u, pf, err := packages_service.GetPackageFileStream(ctx, pfs[0])
|
||||
s, pf, err := packages_service.GetPackageFileStream(ctx, pfs[0])
|
||||
if err != nil {
|
||||
if errors.Is(err, util.ErrNotExist) {
|
||||
apiError(ctx, http.StatusNotFound, err)
|
||||
@ -115,8 +119,12 @@ func GetRepositoryFileByHash(ctx *context.Context) {
|
||||
}
|
||||
return
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
helper.ServePackageFile(ctx, s, u, pf)
|
||||
ctx.ServeContent(s, &context.ServeHeaderOptions{
|
||||
Filename: pf.Name,
|
||||
LastModified: pf.CreatedUnix.AsLocalTime(),
|
||||
})
|
||||
}
|
||||
|
||||
func UploadPackageFile(ctx *context.Context) {
|
||||
@ -209,7 +217,7 @@ func DownloadPackageFile(ctx *context.Context) {
|
||||
name := ctx.Params("name")
|
||||
version := ctx.Params("version")
|
||||
|
||||
s, u, pf, err := packages_service.GetFileStreamByPackageNameAndVersion(
|
||||
s, pf, err := packages_service.GetFileStreamByPackageNameAndVersion(
|
||||
ctx,
|
||||
&packages_service.PackageInfo{
|
||||
Owner: ctx.Package.Owner,
|
||||
@ -230,8 +238,9 @@ func DownloadPackageFile(ctx *context.Context) {
|
||||
}
|
||||
return
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
helper.ServePackageFile(ctx, s, u, pf, &context.ServeHeaderOptions{
|
||||
ctx.ServeContent(s, &context.ServeHeaderOptions{
|
||||
ContentType: "application/vnd.debian.binary-package",
|
||||
Filename: pf.Name,
|
||||
LastModified: pf.CreatedUnix.AsLocalTime(),
|
||||
|
@ -30,7 +30,7 @@ func apiError(ctx *context.Context, status int, obj interface{}) {
|
||||
|
||||
// DownloadPackageFile serves the specific generic package.
|
||||
func DownloadPackageFile(ctx *context.Context) {
|
||||
s, u, pf, err := packages_service.GetFileStreamByPackageNameAndVersion(
|
||||
s, pf, err := packages_service.GetFileStreamByPackageNameAndVersion(
|
||||
ctx,
|
||||
&packages_service.PackageInfo{
|
||||
Owner: ctx.Package.Owner,
|
||||
@ -50,8 +50,12 @@ func DownloadPackageFile(ctx *context.Context) {
|
||||
apiError(ctx, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
helper.ServePackageFile(ctx, s, u, pf)
|
||||
ctx.ServeContent(s, &context.ServeHeaderOptions{
|
||||
Filename: pf.Name,
|
||||
LastModified: pf.CreatedUnix.AsLocalTime(),
|
||||
})
|
||||
}
|
||||
|
||||
// UploadPackage uploads the specific generic package.
|
||||
|
@ -105,7 +105,7 @@ func DownloadPackageFile(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
s, u, _, err := packages_service.GetPackageFileStream(ctx, pfs[0])
|
||||
s, _, err := packages_service.GetPackageFileStream(ctx, pfs[0])
|
||||
if err != nil {
|
||||
if errors.Is(err, util.ErrNotExist) {
|
||||
apiError(ctx, http.StatusNotFound, err)
|
||||
@ -114,8 +114,12 @@ func DownloadPackageFile(ctx *context.Context) {
|
||||
}
|
||||
return
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
helper.ServePackageFile(ctx, s, u, pfs[0])
|
||||
ctx.ServeContent(s, &context.ServeHeaderOptions{
|
||||
Filename: pfs[0].Name,
|
||||
LastModified: pfs[0].CreatedUnix.AsLocalTime(),
|
||||
})
|
||||
}
|
||||
|
||||
func resolvePackage(ctx *context.Context, ownerID int64, name, version string) (*packages_model.PackageVersion, error) {
|
||||
|
@ -121,7 +121,7 @@ func DownloadPackageFile(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
s, u, pf, err := packages_service.GetFileStreamByPackageVersion(
|
||||
s, pf, err := packages_service.GetFileStreamByPackageVersion(
|
||||
ctx,
|
||||
pvs[0],
|
||||
&packages_service.PackageFileInfo{
|
||||
@ -136,8 +136,12 @@ func DownloadPackageFile(ctx *context.Context) {
|
||||
apiError(ctx, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
helper.ServePackageFile(ctx, s, u, pf)
|
||||
ctx.ServeContent(s, &context.ServeHeaderOptions{
|
||||
Filename: pf.Name,
|
||||
LastModified: pf.CreatedUnix.AsLocalTime(),
|
||||
})
|
||||
}
|
||||
|
||||
// UploadPackage creates a new package
|
||||
|
@ -5,11 +5,8 @@ package helper
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
packages_model "code.gitea.io/gitea/models/packages"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
@ -38,26 +35,3 @@ func LogAndProcessError(ctx *context.Context, status int, obj interface{}, cb fu
|
||||
cb(message)
|
||||
}
|
||||
}
|
||||
|
||||
// Serves the content of the package file
|
||||
// If the url is set it will redirect the request, otherwise the content is copied to the response.
|
||||
func ServePackageFile(ctx *context.Context, s io.ReadSeekCloser, u *url.URL, pf *packages_model.PackageFile, forceOpts ...*context.ServeHeaderOptions) {
|
||||
if u != nil {
|
||||
ctx.Redirect(u.String())
|
||||
return
|
||||
}
|
||||
|
||||
defer s.Close()
|
||||
|
||||
var opts *context.ServeHeaderOptions
|
||||
if len(forceOpts) > 0 {
|
||||
opts = forceOpts[0]
|
||||
} else {
|
||||
opts = &context.ServeHeaderOptions{
|
||||
Filename: pf.Name,
|
||||
LastModified: pf.CreatedUnix.AsLocalTime(),
|
||||
}
|
||||
}
|
||||
|
||||
ctx.ServeContent(s, opts)
|
||||
}
|
||||
|
@ -210,15 +210,21 @@ func servePackageFile(ctx *context.Context, params parameters, serveContent bool
|
||||
return
|
||||
}
|
||||
|
||||
s, u, _, err := packages_service.GetPackageBlobStream(ctx, pf, pb)
|
||||
s, err := packages_module.NewContentStore().Get(packages_module.BlobHash256Key(pb.HashSHA256))
|
||||
if err != nil {
|
||||
apiError(ctx, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
if pf.IsLead {
|
||||
if err := packages_model.IncrementDownloadCounter(ctx, pv.ID); err != nil {
|
||||
log.Error("Error incrementing download counter: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
opts.Filename = pf.Name
|
||||
|
||||
helper.ServePackageFile(ctx, s, u, pf, opts)
|
||||
ctx.ServeContent(s, opts)
|
||||
}
|
||||
|
||||
// UploadPackageFile adds a file to the package. If the package does not exist, it gets created.
|
||||
|
@ -83,7 +83,7 @@ func DownloadPackageFile(ctx *context.Context) {
|
||||
packageVersion := ctx.Params("version")
|
||||
filename := ctx.Params("filename")
|
||||
|
||||
s, u, pf, err := packages_service.GetFileStreamByPackageNameAndVersion(
|
||||
s, pf, err := packages_service.GetFileStreamByPackageNameAndVersion(
|
||||
ctx,
|
||||
&packages_service.PackageInfo{
|
||||
Owner: ctx.Package.Owner,
|
||||
@ -103,8 +103,12 @@ func DownloadPackageFile(ctx *context.Context) {
|
||||
apiError(ctx, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
helper.ServePackageFile(ctx, s, u, pf)
|
||||
ctx.ServeContent(s, &context.ServeHeaderOptions{
|
||||
Filename: pf.Name,
|
||||
LastModified: pf.CreatedUnix.AsLocalTime(),
|
||||
})
|
||||
}
|
||||
|
||||
// DownloadPackageFileByName finds the version and serves the contents of a package
|
||||
@ -130,7 +134,7 @@ func DownloadPackageFileByName(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
s, u, pf, err := packages_service.GetFileStreamByPackageVersion(
|
||||
s, pf, err := packages_service.GetFileStreamByPackageVersion(
|
||||
ctx,
|
||||
pvs[0],
|
||||
&packages_service.PackageFileInfo{
|
||||
@ -145,8 +149,12 @@ func DownloadPackageFileByName(ctx *context.Context) {
|
||||
apiError(ctx, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
helper.ServePackageFile(ctx, s, u, pf)
|
||||
ctx.ServeContent(s, &context.ServeHeaderOptions{
|
||||
Filename: pf.Name,
|
||||
LastModified: pf.CreatedUnix.AsLocalTime(),
|
||||
})
|
||||
}
|
||||
|
||||
// UploadPackage creates a new package
|
||||
|
@ -362,7 +362,7 @@ func DownloadPackageFile(ctx *context.Context) {
|
||||
packageVersion := ctx.Params("version")
|
||||
filename := ctx.Params("filename")
|
||||
|
||||
s, u, pf, err := packages_service.GetFileStreamByPackageNameAndVersion(
|
||||
s, pf, err := packages_service.GetFileStreamByPackageNameAndVersion(
|
||||
ctx,
|
||||
&packages_service.PackageInfo{
|
||||
Owner: ctx.Package.Owner,
|
||||
@ -382,8 +382,12 @@ func DownloadPackageFile(ctx *context.Context) {
|
||||
apiError(ctx, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
helper.ServePackageFile(ctx, s, u, pf)
|
||||
ctx.ServeContent(s, &context.ServeHeaderOptions{
|
||||
Filename: pf.Name,
|
||||
LastModified: pf.CreatedUnix.AsLocalTime(),
|
||||
})
|
||||
}
|
||||
|
||||
// UploadPackage creates a new package with the metadata contained in the uploaded nupgk file
|
||||
@ -596,7 +600,7 @@ func DownloadSymbolFile(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
s, u, pf, err := packages_service.GetPackageFileStream(ctx, pfs[0])
|
||||
s, pf, err := packages_service.GetPackageFileStream(ctx, pfs[0])
|
||||
if err != nil {
|
||||
if err == packages_model.ErrPackageNotExist || err == packages_model.ErrPackageFileNotExist {
|
||||
apiError(ctx, http.StatusNotFound, err)
|
||||
@ -605,8 +609,12 @@ func DownloadSymbolFile(ctx *context.Context) {
|
||||
apiError(ctx, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
helper.ServePackageFile(ctx, s, u, pf)
|
||||
ctx.ServeContent(s, &context.ServeHeaderOptions{
|
||||
Filename: pf.Name,
|
||||
LastModified: pf.CreatedUnix.AsLocalTime(),
|
||||
})
|
||||
}
|
||||
|
||||
// DeletePackage hard deletes the package
|
||||
|
@ -273,11 +273,15 @@ func DownloadPackageFile(ctx *context.Context) {
|
||||
|
||||
pf := pd.Files[0].File
|
||||
|
||||
s, u, _, err := packages_service.GetPackageFileStream(ctx, pf)
|
||||
s, _, err := packages_service.GetPackageFileStream(ctx, pf)
|
||||
if err != nil {
|
||||
apiError(ctx, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
helper.ServePackageFile(ctx, s, u, pf)
|
||||
ctx.ServeContent(s, &context.ServeHeaderOptions{
|
||||
Filename: pf.Name,
|
||||
LastModified: pf.CreatedUnix.AsLocalTime(),
|
||||
})
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ func DownloadPackageFile(ctx *context.Context) {
|
||||
packageVersion := ctx.Params("version")
|
||||
filename := ctx.Params("filename")
|
||||
|
||||
s, u, pf, err := packages_service.GetFileStreamByPackageNameAndVersion(
|
||||
s, pf, err := packages_service.GetFileStreamByPackageNameAndVersion(
|
||||
ctx,
|
||||
&packages_service.PackageInfo{
|
||||
Owner: ctx.Package.Owner,
|
||||
@ -100,8 +100,12 @@ func DownloadPackageFile(ctx *context.Context) {
|
||||
apiError(ctx, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
helper.ServePackageFile(ctx, s, u, pf)
|
||||
ctx.ServeContent(s, &context.ServeHeaderOptions{
|
||||
Filename: pf.Name,
|
||||
LastModified: pf.CreatedUnix.AsLocalTime(),
|
||||
})
|
||||
}
|
||||
|
||||
// UploadPackageFile adds a file to the package. If the package does not exist, it gets created.
|
||||
|
@ -65,7 +65,7 @@ func GetRepositoryFile(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
s, u, pf, err := packages_service.GetFileStreamByPackageVersion(
|
||||
s, pf, err := packages_service.GetFileStreamByPackageVersion(
|
||||
ctx,
|
||||
pv,
|
||||
&packages_service.PackageFileInfo{
|
||||
@ -80,8 +80,12 @@ func GetRepositoryFile(ctx *context.Context) {
|
||||
}
|
||||
return
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
helper.ServePackageFile(ctx, s, u, pf)
|
||||
ctx.ServeContent(s, &context.ServeHeaderOptions{
|
||||
Filename: pf.Name,
|
||||
LastModified: pf.CreatedUnix.AsLocalTime(),
|
||||
})
|
||||
}
|
||||
|
||||
func UploadPackageFile(ctx *context.Context) {
|
||||
@ -169,7 +173,7 @@ func DownloadPackageFile(ctx *context.Context) {
|
||||
name := ctx.Params("name")
|
||||
version := ctx.Params("version")
|
||||
|
||||
s, u, pf, err := packages_service.GetFileStreamByPackageNameAndVersion(
|
||||
s, pf, err := packages_service.GetFileStreamByPackageNameAndVersion(
|
||||
ctx,
|
||||
&packages_service.PackageInfo{
|
||||
Owner: ctx.Package.Owner,
|
||||
@ -189,8 +193,13 @@ func DownloadPackageFile(ctx *context.Context) {
|
||||
}
|
||||
return
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
helper.ServePackageFile(ctx, s, u, pf)
|
||||
ctx.ServeContent(s, &context.ServeHeaderOptions{
|
||||
ContentType: "application/x-rpm",
|
||||
Filename: pf.Name,
|
||||
LastModified: pf.CreatedUnix.AsLocalTime(),
|
||||
})
|
||||
}
|
||||
|
||||
func DeletePackageFile(webctx *context.Context) {
|
||||
|
@ -175,7 +175,7 @@ func DownloadPackageFile(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
s, u, pf, err := packages_service.GetFileStreamByPackageVersion(
|
||||
s, pf, err := packages_service.GetFileStreamByPackageVersion(
|
||||
ctx,
|
||||
pvs[0],
|
||||
&packages_service.PackageFileInfo{
|
||||
@ -190,8 +190,12 @@ func DownloadPackageFile(ctx *context.Context) {
|
||||
apiError(ctx, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
helper.ServePackageFile(ctx, s, u, pf)
|
||||
ctx.ServeContent(s, &context.ServeHeaderOptions{
|
||||
Filename: pf.Name,
|
||||
LastModified: pf.CreatedUnix.AsLocalTime(),
|
||||
})
|
||||
}
|
||||
|
||||
// UploadPackageFile adds a file to the package. If the package does not exist, it gets created.
|
||||
|
@ -397,17 +397,18 @@ func DownloadPackageFile(ctx *context.Context) {
|
||||
|
||||
pf := pd.Files[0].File
|
||||
|
||||
s, u, _, err := packages_service.GetPackageFileStream(ctx, pf)
|
||||
s, _, err := packages_service.GetPackageFileStream(ctx, pf)
|
||||
if err != nil {
|
||||
apiError(ctx, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
setResponseHeaders(ctx.Resp, &headers{
|
||||
Digest: pd.Files[0].Blob.HashSHA256,
|
||||
})
|
||||
|
||||
helper.ServePackageFile(ctx, s, u, pf, &context.ServeHeaderOptions{
|
||||
ctx.ServeContent(s, &context.ServeHeaderOptions{
|
||||
Filename: pf.Name,
|
||||
ContentType: "application/zip",
|
||||
LastModified: pf.CreatedUnix.AsLocalTime(),
|
||||
|
@ -216,7 +216,7 @@ func UploadPackageFile(ctx *context.Context) {
|
||||
}
|
||||
|
||||
func DownloadPackageFile(ctx *context.Context) {
|
||||
s, u, pf, err := packages_service.GetFileStreamByPackageNameAndVersion(
|
||||
s, pf, err := packages_service.GetFileStreamByPackageNameAndVersion(
|
||||
ctx,
|
||||
&packages_service.PackageInfo{
|
||||
Owner: ctx.Package.Owner,
|
||||
@ -236,6 +236,10 @@ func DownloadPackageFile(ctx *context.Context) {
|
||||
apiError(ctx, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
helper.ServePackageFile(ctx, s, u, pf)
|
||||
ctx.ServeContent(s, &context.ServeHeaderOptions{
|
||||
Filename: pf.Name,
|
||||
LastModified: pf.CreatedUnix.AsLocalTime(),
|
||||
})
|
||||
}
|
||||
|
@ -201,7 +201,7 @@ func SignInPost(ctx *context.Context) {
|
||||
|
||||
u, source, err := auth_service.UserSignIn(form.UserName, form.Password)
|
||||
if err != nil {
|
||||
if errors.Is(err, util.ErrNotExist) || errors.Is(err, util.ErrInvalidArgument) {
|
||||
if user_model.IsErrUserNotExist(err) || user_model.IsErrEmailAddressNotExist(err) {
|
||||
ctx.RenderWithErr(ctx.Tr("form.username_password_incorrect"), tplSignIn, &form)
|
||||
log.Info("Failed authentication attempt for %s from %s: %v", form.UserName, ctx.RemoteAddr(), err)
|
||||
} else if user_model.IsErrEmailAlreadyUsed(err) {
|
||||
|
@ -13,9 +13,7 @@ import (
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/modules/web"
|
||||
auth_service "code.gitea.io/gitea/services/auth"
|
||||
"code.gitea.io/gitea/services/auth/source/oauth2"
|
||||
@ -83,32 +81,6 @@ func LinkAccount(ctx *context.Context) {
|
||||
ctx.HTML(http.StatusOK, tplLinkAccount)
|
||||
}
|
||||
|
||||
func handleSignInError(ctx *context.Context, userName string, ptrForm any, tmpl base.TplName, invoker string, err error) {
|
||||
if errors.Is(err, util.ErrNotExist) {
|
||||
ctx.RenderWithErr(ctx.Tr("form.username_password_incorrect"), tmpl, ptrForm)
|
||||
} else if errors.Is(err, util.ErrInvalidArgument) {
|
||||
ctx.Data["user_exists"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("form.username_password_incorrect"), tmpl, ptrForm)
|
||||
} else if user_model.IsErrUserProhibitLogin(err) {
|
||||
ctx.Data["user_exists"] = true
|
||||
log.Info("Failed authentication attempt for %s from %s: %v", userName, ctx.RemoteAddr(), err)
|
||||
ctx.Data["Title"] = ctx.Tr("auth.prohibit_login")
|
||||
ctx.HTML(http.StatusOK, "user/auth/prohibit_login")
|
||||
} else if user_model.IsErrUserInactive(err) {
|
||||
ctx.Data["user_exists"] = true
|
||||
if setting.Service.RegisterEmailConfirm {
|
||||
ctx.Data["Title"] = ctx.Tr("auth.active_your_account")
|
||||
ctx.HTML(http.StatusOK, TplActivate)
|
||||
} else {
|
||||
log.Info("Failed authentication attempt for %s from %s: %v", userName, ctx.RemoteAddr(), err)
|
||||
ctx.Data["Title"] = ctx.Tr("auth.prohibit_login")
|
||||
ctx.HTML(http.StatusOK, "user/auth/prohibit_login")
|
||||
}
|
||||
} else {
|
||||
ctx.ServerError(invoker, err)
|
||||
}
|
||||
}
|
||||
|
||||
// LinkAccountPostSignIn handle the coupling of external account with another account using signIn
|
||||
func LinkAccountPostSignIn(ctx *context.Context) {
|
||||
signInForm := web.GetForm(ctx).(*forms.SignInForm)
|
||||
@ -144,7 +116,12 @@ func LinkAccountPostSignIn(ctx *context.Context) {
|
||||
|
||||
u, _, err := auth_service.UserSignIn(signInForm.UserName, signInForm.Password)
|
||||
if err != nil {
|
||||
handleSignInError(ctx, signInForm.UserName, &signInForm, tplLinkAccount, "UserLinkAccount", err)
|
||||
if user_model.IsErrUserNotExist(err) {
|
||||
ctx.Data["user_exists"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("form.username_password_incorrect"), tplLinkAccount, &signInForm)
|
||||
} else {
|
||||
ctx.ServerError("UserLinkAccount", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -282,7 +282,11 @@ func ConnectOpenIDPost(ctx *context.Context) {
|
||||
|
||||
u, _, err := auth.UserSignIn(form.UserName, form.Password)
|
||||
if err != nil {
|
||||
handleSignInError(ctx, form.UserName, &form, tplConnectOID, "ConnectOpenIDPost", err)
|
||||
if user_model.IsErrUserNotExist(err) {
|
||||
ctx.RenderWithErr(ctx.Tr("form.username_password_incorrect"), tplConnectOID, &form)
|
||||
} else {
|
||||
ctx.ServerError("ConnectOpenIDPost", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ func List(ctx *context.Context) {
|
||||
|
||||
func FetchActionTest(ctx *context.Context) {
|
||||
_ = ctx.Req.ParseForm()
|
||||
ctx.Flash.Info("fetch-action: " + ctx.Req.Method + " " + ctx.Req.RequestURI + "<br>" +
|
||||
ctx.Flash.Info(ctx.Req.Method + " " + ctx.Req.RequestURI + "<br>" +
|
||||
"Form: " + ctx.Req.Form.Encode() + "<br>" +
|
||||
"PostForm: " + ctx.Req.PostForm.Encode(),
|
||||
)
|
||||
@ -52,15 +52,5 @@ func Tmpl(ctx *context.Context) {
|
||||
ctx.Data["TimePast1y"] = now.Add(-1 * 366 * 86400 * time.Second)
|
||||
ctx.Data["TimeFuture1y"] = now.Add(1 * 366 * 86400 * time.Second)
|
||||
|
||||
if ctx.Req.Method == "POST" {
|
||||
_ = ctx.Req.ParseForm()
|
||||
ctx.Flash.Info("form: "+ctx.Req.Method+" "+ctx.Req.RequestURI+"<br>"+
|
||||
"Form: "+ctx.Req.Form.Encode()+"<br>"+
|
||||
"PostForm: "+ctx.Req.PostForm.Encode(),
|
||||
true,
|
||||
)
|
||||
time.Sleep(2 * time.Second)
|
||||
}
|
||||
|
||||
ctx.HTML(http.StatusOK, base.TplName("devtest"+path.Clean("/"+ctx.Params("sub"))))
|
||||
}
|
||||
|
@ -22,7 +22,6 @@ import (
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/modules/web"
|
||||
packages_helper "code.gitea.io/gitea/routers/api/packages/helper"
|
||||
shared_user "code.gitea.io/gitea/routers/web/shared/user"
|
||||
"code.gitea.io/gitea/services/forms"
|
||||
packages_service "code.gitea.io/gitea/services/packages"
|
||||
@ -444,11 +443,18 @@ func DownloadPackageFile(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
s, u, _, err := packages_service.GetPackageFileStream(ctx, pf)
|
||||
s, _, err := packages_service.GetPackageFileStream(
|
||||
ctx,
|
||||
pf,
|
||||
)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetPackageFileStream", err)
|
||||
return
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
packages_helper.ServePackageFile(ctx, s, u, pf)
|
||||
ctx.ServeContent(s, &context.ServeHeaderOptions{
|
||||
Filename: pf.Name,
|
||||
LastModified: pf.CreatedUnix.AsLocalTime(),
|
||||
})
|
||||
}
|
||||
|
@ -4,54 +4,19 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
)
|
||||
|
||||
// ErrUserPasswordNotSet represents a "ErrUserPasswordNotSet" kind of error.
|
||||
type ErrUserPasswordNotSet struct {
|
||||
UID int64
|
||||
Name string
|
||||
}
|
||||
|
||||
func (err ErrUserPasswordNotSet) Error() string {
|
||||
return fmt.Sprintf("user's password isn't set [uid: %d, name: %s]", err.UID, err.Name)
|
||||
}
|
||||
|
||||
// Unwrap unwraps this error as a ErrInvalidArgument error
|
||||
func (err ErrUserPasswordNotSet) Unwrap() error {
|
||||
return util.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// ErrUserPasswordInvalid represents a "ErrUserPasswordInvalid" kind of error.
|
||||
type ErrUserPasswordInvalid struct {
|
||||
UID int64
|
||||
Name string
|
||||
}
|
||||
|
||||
func (err ErrUserPasswordInvalid) Error() string {
|
||||
return fmt.Sprintf("user's password is invalid [uid: %d, name: %s]", err.UID, err.Name)
|
||||
}
|
||||
|
||||
// Unwrap unwraps this error as a ErrInvalidArgument error
|
||||
func (err ErrUserPasswordInvalid) Unwrap() error {
|
||||
return util.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// Authenticate authenticates the provided user against the DB
|
||||
func Authenticate(user *user_model.User, login, password string) (*user_model.User, error) {
|
||||
if user == nil {
|
||||
return nil, user_model.ErrUserNotExist{Name: login}
|
||||
}
|
||||
|
||||
if !user.IsPasswordSet() {
|
||||
return nil, ErrUserPasswordNotSet{UID: user.ID, Name: user.Name}
|
||||
} else if !user.ValidatePassword(password) {
|
||||
return nil, ErrUserPasswordInvalid{UID: user.ID, Name: user.Name}
|
||||
if !user.IsPasswordSet() || !user.ValidatePassword(password) {
|
||||
return nil, user_model.ErrUserNotExist{UID: user.ID, Name: user.Name}
|
||||
}
|
||||
|
||||
// Update password hash if server password hash algorithm have changed
|
||||
|
@ -9,7 +9,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
@ -21,7 +20,6 @@ import (
|
||||
"code.gitea.io/gitea/modules/notification"
|
||||
packages_module "code.gitea.io/gitea/modules/packages"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/storage"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
)
|
||||
|
||||
@ -564,62 +562,70 @@ func DeletePackageFile(ctx context.Context, pf *packages_model.PackageFile) erro
|
||||
}
|
||||
|
||||
// GetFileStreamByPackageNameAndVersion returns the content of the specific package file
|
||||
func GetFileStreamByPackageNameAndVersion(ctx context.Context, pvi *PackageInfo, pfi *PackageFileInfo) (io.ReadSeekCloser, *url.URL, *packages_model.PackageFile, error) {
|
||||
func GetFileStreamByPackageNameAndVersion(ctx context.Context, pvi *PackageInfo, pfi *PackageFileInfo) (io.ReadSeekCloser, *packages_model.PackageFile, error) {
|
||||
log.Trace("Getting package file stream: %v, %v, %s, %s, %s, %s", pvi.Owner.ID, pvi.PackageType, pvi.Name, pvi.Version, pfi.Filename, pfi.CompositeKey)
|
||||
|
||||
pv, err := packages_model.GetVersionByNameAndVersion(ctx, pvi.Owner.ID, pvi.PackageType, pvi.Name, pvi.Version)
|
||||
if err != nil {
|
||||
if err == packages_model.ErrPackageNotExist {
|
||||
return nil, nil, nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
log.Error("Error getting package: %v", err)
|
||||
return nil, nil, nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return GetFileStreamByPackageVersion(ctx, pv, pfi)
|
||||
}
|
||||
|
||||
// GetFileStreamByPackageVersionAndFileID returns the content of the specific package file
|
||||
func GetFileStreamByPackageVersionAndFileID(ctx context.Context, owner *user_model.User, versionID, fileID int64) (io.ReadSeekCloser, *packages_model.PackageFile, error) {
|
||||
log.Trace("Getting package file stream: %v, %v, %v", owner.ID, versionID, fileID)
|
||||
|
||||
pv, err := packages_model.GetVersionByID(ctx, versionID)
|
||||
if err != nil {
|
||||
if err != packages_model.ErrPackageNotExist {
|
||||
log.Error("Error getting package version: %v", err)
|
||||
}
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
p, err := packages_model.GetPackageByID(ctx, pv.PackageID)
|
||||
if err != nil {
|
||||
log.Error("Error getting package: %v", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if p.OwnerID != owner.ID {
|
||||
return nil, nil, packages_model.ErrPackageNotExist
|
||||
}
|
||||
|
||||
pf, err := packages_model.GetFileForVersionByID(ctx, versionID, fileID)
|
||||
if err != nil {
|
||||
log.Error("Error getting file: %v", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return GetPackageFileStream(ctx, pf)
|
||||
}
|
||||
|
||||
// GetFileStreamByPackageVersion returns the content of the specific package file
|
||||
func GetFileStreamByPackageVersion(ctx context.Context, pv *packages_model.PackageVersion, pfi *PackageFileInfo) (io.ReadSeekCloser, *url.URL, *packages_model.PackageFile, error) {
|
||||
func GetFileStreamByPackageVersion(ctx context.Context, pv *packages_model.PackageVersion, pfi *PackageFileInfo) (io.ReadSeekCloser, *packages_model.PackageFile, error) {
|
||||
pf, err := packages_model.GetFileForVersionByName(ctx, pv.ID, pfi.Filename, pfi.CompositeKey)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return GetPackageFileStream(ctx, pf)
|
||||
}
|
||||
|
||||
// GetPackageFileStream returns the content of the specific package file
|
||||
func GetPackageFileStream(ctx context.Context, pf *packages_model.PackageFile) (io.ReadSeekCloser, *url.URL, *packages_model.PackageFile, error) {
|
||||
func GetPackageFileStream(ctx context.Context, pf *packages_model.PackageFile) (io.ReadSeekCloser, *packages_model.PackageFile, error) {
|
||||
pb, err := packages_model.GetBlobByID(ctx, pf.BlobID)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
return GetPackageBlobStream(ctx, pf, pb)
|
||||
}
|
||||
|
||||
// GetPackageBlobStream returns the content of the specific package blob
|
||||
// If the storage supports direct serving and it's enabled, only the direct serving url is returned.
|
||||
func GetPackageBlobStream(ctx context.Context, pf *packages_model.PackageFile, pb *packages_model.PackageBlob) (io.ReadSeekCloser, *url.URL, *packages_model.PackageFile, error) {
|
||||
key := packages_module.BlobHash256Key(pb.HashSHA256)
|
||||
|
||||
cs := packages_module.NewContentStore()
|
||||
|
||||
var s io.ReadSeekCloser
|
||||
var u *url.URL
|
||||
var err error
|
||||
|
||||
if cs.ShouldServeDirect() {
|
||||
u, err = cs.GetServeDirectURL(key, pf.Name)
|
||||
if err != nil && !errors.Is(err, storage.ErrURLNotSupported) {
|
||||
log.Error("Error getting serve direct url: %v", err)
|
||||
}
|
||||
}
|
||||
if u == nil {
|
||||
s, err = cs.Get(key)
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
s, err := packages_module.NewContentStore().Get(packages_module.BlobHash256Key(pb.HashSHA256))
|
||||
if err == nil {
|
||||
if pf.IsLead {
|
||||
if err := packages_model.IncrementDownloadCounter(ctx, pf.VersionID); err != nil {
|
||||
@ -627,7 +633,7 @@ func GetPackageBlobStream(ctx context.Context, pf *packages_model.PackageFile, p
|
||||
}
|
||||
}
|
||||
}
|
||||
return s, u, pf, err
|
||||
return s, pf, err
|
||||
}
|
||||
|
||||
// RemoveAllPackages for User
|
||||
|
@ -1,18 +1,5 @@
|
||||
{{template "base/head" .}}
|
||||
<div class="page-content devtest ui container">
|
||||
{{template "base/alert" .}}
|
||||
|
||||
<button class="show-modal" data-modal="#test-modal-form">show modal form</button>
|
||||
<div id="test-modal-form" class="ui mini modal">
|
||||
<div class="header">Form dialog</div>
|
||||
<form class="content" method="post">
|
||||
<div class="ui input"><input name="user_input"></div>
|
||||
{{template "base/modal_actions_confirm" (dict "locale" $.locale "ModalButtonTypes" "confirm")}}
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="divider"></div>
|
||||
|
||||
<div class="ui g-modal-confirm modal" id="test-modal-default">
|
||||
<div class="header">{{svg "octicon-file"}} Default dialog <span>title</span></div>
|
||||
<div class="content">
|
||||
|
@ -39,26 +39,32 @@
|
||||
{{.locale.Tr "settings.manage_emails"}}
|
||||
</h4>
|
||||
<div class="ui attached segment">
|
||||
<div class="ui list">
|
||||
<div class="ui email list">
|
||||
{{if $.EnableNotifyMail}}
|
||||
<div class="item">
|
||||
<div class="gt-mb-3">{{.locale.Tr "settings.email_desc"}}</div>
|
||||
<form action="{{AppSubUrl}}/user/settings/account/email" class="ui form" method="post">
|
||||
{{$.CsrfTokenHtml}}
|
||||
<input name="_method" type="hidden" value="NOTIFICATION">
|
||||
<div class="gt-df gt-fw gt-gap-3">
|
||||
<div class="ui selection dropdown">
|
||||
<input name="preference" type="hidden" value="{{.EmailNotificationsPreference}}">
|
||||
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||
<div class="text"></div>
|
||||
<div class="menu">
|
||||
<div data-value="enabled" class="{{if eq .EmailNotificationsPreference "enabled"}}active selected {{end}}item">{{$.locale.Tr "settings.email_notifications.enable"}}</div>
|
||||
<div data-value="andyourown" class="{{if eq .EmailNotificationsPreference "andyourown"}}active selected {{end}}item">{{$.locale.Tr "settings.email_notifications.andyourown"}}</div>
|
||||
<div data-value="onmention" class="{{if eq .EmailNotificationsPreference "onmention"}}active selected {{end}}item">{{$.locale.Tr "settings.email_notifications.onmention"}}</div>
|
||||
<div data-value="disabled" class="{{if eq .EmailNotificationsPreference "disabled"}}active selected {{end}}item">{{$.locale.Tr "settings.email_notifications.disable"}}</div>
|
||||
{{.locale.Tr "settings.email_desc"}}
|
||||
<div class="right floated content">
|
||||
<div class="field">
|
||||
<button class="ui green button">{{$.locale.Tr "settings.email_notifications.submit"}}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right floated content">
|
||||
{{$.CsrfTokenHtml}}
|
||||
<input name="_method" type="hidden" value="NOTIFICATION">
|
||||
<div class="field">
|
||||
<div class="ui selection dropdown" tabindex="0">
|
||||
<input name="preference" type="hidden" value="{{.EmailNotificationsPreference}}">
|
||||
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||
<div class="text"></div>
|
||||
<div class="menu">
|
||||
<div data-value="enabled" class="{{if eq .EmailNotificationsPreference "enabled"}}active selected {{end}}item">{{$.locale.Tr "settings.email_notifications.enable"}}</div>
|
||||
<div data-value="andyourown" class="{{if eq .EmailNotificationsPreference "andyourown"}}active selected {{end}}item">{{$.locale.Tr "settings.email_notifications.andyourown"}}</div>
|
||||
<div data-value="onmention" class="{{if eq .EmailNotificationsPreference "onmention"}}active selected {{end}}item">{{$.locale.Tr "settings.email_notifications.onmention"}}</div>
|
||||
<div data-value="disabled" class="{{if eq .EmailNotificationsPreference "disabled"}}active selected {{end}}item">{{$.locale.Tr "settings.email_notifications.disable"}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="ui green button">{{$.locale.Tr "settings.email_notifications.submit"}}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@ -96,7 +102,7 @@
|
||||
</form>
|
||||
</div>
|
||||
{{end}}
|
||||
<div class="content gt-py-3">
|
||||
<div class="content">
|
||||
<strong>{{.Email}}</strong>
|
||||
{{if .IsPrimary}}
|
||||
<div class="ui primary label">{{$.locale.Tr "settings.primary"}}</div>
|
||||
|
@ -22,19 +22,7 @@
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
<div class="ui g-modal-confirm delete modal" id="remove-gitea-oauth2-application">
|
||||
<div class="header">
|
||||
{{svg "octicon-trash"}}
|
||||
{{.locale.Tr "settings.remove_oauth2_application"}}
|
||||
</div>
|
||||
<div class="content">
|
||||
<p>{{.locale.Tr "settings.oauth2_application_remove_description"}}</p>
|
||||
</div>
|
||||
{{template "base/modal_actions_confirm" .}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ui attached bottom segment">
|
||||
<h5 class="ui top header">
|
||||
{{.locale.Tr "settings.create_oauth2_application"}}
|
||||
@ -58,3 +46,14 @@
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="ui g-modal-confirm delete modal" id="remove-gitea-oauth2-application">
|
||||
<div class="header">
|
||||
{{svg "octicon-trash"}}
|
||||
{{.locale.Tr "settings.remove_oauth2_application"}}
|
||||
</div>
|
||||
<div class="content">
|
||||
<p>{{.locale.Tr "settings.oauth2_application_remove_description"}}</p>
|
||||
</div>
|
||||
{{template "base/modal_actions_confirm" .}}
|
||||
</div>
|
||||
|
@ -26,15 +26,15 @@
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
<div class="ui g-modal-confirm delete modal" id="revoke-gitea-oauth2-grant">
|
||||
<div class="header">
|
||||
{{svg "octicon-shield" 16 "gt-mr-2"}}
|
||||
{{.locale.Tr "settings.revoke_oauth2_grant"}}
|
||||
</div>
|
||||
<div class="content">
|
||||
<p>{{.locale.Tr "settings.revoke_oauth2_grant_description"}}</p>
|
||||
</div>
|
||||
{{template "base/modal_actions_confirm" .}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ui g-modal-confirm delete modal" id="revoke-gitea-oauth2-grant">
|
||||
<div class="header">
|
||||
{{svg "octicon-shield" 16 "gt-mr-2"}}
|
||||
{{.locale.Tr "settings.revoke_oauth2_grant"}}
|
||||
</div>
|
||||
<div class="content">
|
||||
<p>{{.locale.Tr "settings.revoke_oauth2_grant_description"}}</p>
|
||||
</div>
|
||||
{{template "base/modal_actions_confirm" .}}
|
||||
</div>
|
||||
|
@ -39,16 +39,16 @@
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ui g-modal-confirm delete modal" id="delete-account-link">
|
||||
<div class="header">
|
||||
{{svg "octicon-trash"}}
|
||||
{{.locale.Tr "settings.remove_account_link"}}
|
||||
</div>
|
||||
<div class="content">
|
||||
<p>{{.locale.Tr "settings.remove_account_link_desc"}}</p>
|
||||
</div>
|
||||
{{template "base/modal_actions_confirm" .}}
|
||||
<div class="ui g-modal-confirm delete modal" id="delete-account-link">
|
||||
<div class="header">
|
||||
{{svg "octicon-trash"}}
|
||||
{{.locale.Tr "settings.remove_account_link"}}
|
||||
</div>
|
||||
<div class="content">
|
||||
<p>{{.locale.Tr "settings.remove_account_link_desc"}}</p>
|
||||
</div>
|
||||
{{template "base/modal_actions_confirm" .}}
|
||||
</div>
|
||||
{{end}}
|
||||
|
@ -48,15 +48,15 @@
|
||||
{{.locale.Tr "settings.add_openid"}}
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div class="ui g-modal-confirm delete modal" id="delete-openid">
|
||||
<div class="header">
|
||||
{{svg "octicon-trash"}}
|
||||
{{.locale.Tr "settings.openid_deletion"}}
|
||||
</div>
|
||||
<div class="content">
|
||||
<p>{{.locale.Tr "settings.openid_deletion_desc"}}</p>
|
||||
</div>
|
||||
{{template "base/modal_actions_confirm" .}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ui g-modal-confirm delete modal" id="delete-openid">
|
||||
<div class="header">
|
||||
{{svg "octicon-trash"}}
|
||||
{{.locale.Tr "settings.openid_deletion"}}
|
||||
</div>
|
||||
<div class="content">
|
||||
<p>{{.locale.Tr "settings.openid_deletion_desc"}}</p>
|
||||
</div>
|
||||
{{template "base/modal_actions_confirm" .}}
|
||||
</div>
|
||||
|
@ -21,15 +21,15 @@
|
||||
<a class="ui green button" href="{{AppSubUrl}}/user/settings/security/two_factor/enroll">{{$.locale.Tr "settings.twofa_enroll"}}</a>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
<div class="ui g-modal-confirm delete modal" id="disable-twofa">
|
||||
<div class="header">
|
||||
{{svg "octicon-trash"}}
|
||||
{{.locale.Tr "settings.twofa_disable"}}
|
||||
</div>
|
||||
<div class="content">
|
||||
<p>{{.locale.Tr "settings.twofa_disable_desc"}}</p>
|
||||
</div>
|
||||
{{template "base/modal_actions_confirm" .}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ui g-modal-confirm delete modal" id="disable-twofa">
|
||||
<div class="header">
|
||||
{{svg "octicon-trash"}}
|
||||
{{.locale.Tr "settings.twofa_disable"}}
|
||||
</div>
|
||||
<div class="content">
|
||||
<p>{{.locale.Tr "settings.twofa_disable_desc"}}</p>
|
||||
</div>
|
||||
{{template "base/modal_actions_confirm" .}}
|
||||
</div>
|
||||
|
@ -24,14 +24,15 @@
|
||||
</div>
|
||||
<button id="register-webauthn" class="ui green button">{{svg "octicon-key"}} {{.locale.Tr "settings.webauthn_register_key"}}</button>
|
||||
</div>
|
||||
<div class="ui g-modal-confirm delete modal" id="delete-registration">
|
||||
<div class="header">
|
||||
{{svg "octicon-trash"}}
|
||||
{{.locale.Tr "settings.webauthn_delete_key"}}
|
||||
</div>
|
||||
<div class="content">
|
||||
<p>{{.locale.Tr "settings.webauthn_delete_key_desc"}}</p>
|
||||
</div>
|
||||
{{template "base/modal_actions_confirm" .}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ui g-modal-confirm delete modal" id="delete-registration">
|
||||
<div class="header">
|
||||
{{svg "octicon-trash"}}
|
||||
{{.locale.Tr "settings.webauthn_delete_key"}}
|
||||
</div>
|
||||
<div class="content">
|
||||
<p>{{.locale.Tr "settings.webauthn_delete_key_desc"}}</p>
|
||||
</div>
|
||||
{{template "base/modal_actions_confirm" .}}
|
||||
</div>
|
||||
|
@ -6,7 +6,6 @@ package integration
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
@ -140,42 +139,6 @@ func TestPackageGeneric(t *testing.T) {
|
||||
req = NewRequest(t, "GET", url+"/dummy.bin")
|
||||
MakeRequest(t, req, http.StatusUnauthorized)
|
||||
})
|
||||
|
||||
t.Run("ServeDirect", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
if setting.Packages.Storage.Type != setting.MinioStorageType {
|
||||
t.Skip("Test skipped for non-Minio-storage.")
|
||||
return
|
||||
}
|
||||
|
||||
if !setting.Packages.Storage.MinioConfig.ServeDirect {
|
||||
old := setting.Packages.Storage.MinioConfig.ServeDirect
|
||||
defer func() {
|
||||
setting.Packages.Storage.MinioConfig.ServeDirect = old
|
||||
}()
|
||||
|
||||
setting.Packages.Storage.MinioConfig.ServeDirect = true
|
||||
}
|
||||
|
||||
req := NewRequest(t, "GET", url+"/"+filename)
|
||||
resp := MakeRequest(t, req, http.StatusSeeOther)
|
||||
|
||||
checkDownloadCount(3)
|
||||
|
||||
location := resp.Header().Get("Location")
|
||||
assert.NotEmpty(t, location)
|
||||
|
||||
resp2, err := (&http.Client{}).Get(location)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, http.StatusOK, resp2.StatusCode)
|
||||
|
||||
body, err := io.ReadAll(resp2.Body)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, content, body)
|
||||
|
||||
checkDownloadCount(3)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("Delete", func(t *testing.T) {
|
||||
|
@ -375,6 +375,16 @@ progress::-moz-progress-bar {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
.svg {
|
||||
display: inline-block;
|
||||
vertical-align: text-top;
|
||||
fill: currentcolor;
|
||||
}
|
||||
|
||||
.middle .svg {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.unselectable,
|
||||
.button,
|
||||
.lines-num,
|
||||
|
@ -10,7 +10,6 @@
|
||||
@import "./modules/navbar.css";
|
||||
@import "./modules/toast.css";
|
||||
@import "./modules/divider.css";
|
||||
@import "./modules/svg.css";
|
||||
|
||||
@import "./shared/issuelist.css";
|
||||
@import "./shared/milestone.css";
|
||||
|
@ -1,41 +0,0 @@
|
||||
.svg {
|
||||
display: inline-block;
|
||||
vertical-align: text-top;
|
||||
fill: currentcolor;
|
||||
}
|
||||
|
||||
.middle .svg {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
/* prevent SVGs from shrinking, like in space-starved flexboxes. the sizes
|
||||
here are cherry-picked for our use cases, feel free to add more. after
|
||||
https://developer.mozilla.org/en-US/docs/Web/CSS/attr#type-or-unit is
|
||||
supported in browsers, use `attr(width px)` instead for a generic
|
||||
solution. */
|
||||
|
||||
.svg[height="12"] { min-height: 12px; }
|
||||
.svg[height="13"] { min-height: 13px; }
|
||||
.svg[height="14"] { min-height: 14px; }
|
||||
.svg[height="15"] { min-height: 15px; }
|
||||
.svg[height="16"] { min-height: 16px; }
|
||||
.svg[height="18"] { min-height: 18px; }
|
||||
.svg[height="20"] { min-height: 20px; }
|
||||
.svg[height="22"] { min-height: 22px; }
|
||||
.svg[height="24"] { min-height: 24px; }
|
||||
.svg[height="36"] { min-height: 36px; }
|
||||
.svg[height="48"] { min-height: 48px; }
|
||||
.svg[height="56"] { min-height: 56px; }
|
||||
|
||||
.svg[width="12"] { min-width: 12px; }
|
||||
.svg[width="13"] { min-width: 13px; }
|
||||
.svg[width="14"] { min-width: 14px; }
|
||||
.svg[width="15"] { min-width: 15px; }
|
||||
.svg[width="16"] { min-width: 16px; }
|
||||
.svg[width="18"] { min-width: 18px; }
|
||||
.svg[width="20"] { min-width: 20px; }
|
||||
.svg[width="22"] { min-width: 22px; }
|
||||
.svg[width="24"] { min-width: 24px; }
|
||||
.svg[width="36"] { min-width: 36px; }
|
||||
.svg[width="48"] { min-width: 48px; }
|
||||
.svg[width="56"] { min-width: 56px; }
|
@ -2358,6 +2358,10 @@
|
||||
color: var(--color-text-light-2);
|
||||
}
|
||||
|
||||
.settings .list.email > .item:not(:first-child) {
|
||||
min-height: 60px;
|
||||
}
|
||||
|
||||
.settings .list.collaborator > .item {
|
||||
padding: 0;
|
||||
}
|
||||
|
@ -1,26 +0,0 @@
|
||||
import $ from 'jquery';
|
||||
|
||||
const fomanticModalFn = $.fn.modal;
|
||||
|
||||
// use our own `$.fn.modal` to patch Fomantic's modal module
|
||||
export function initAriaModalPatch() {
|
||||
if ($.fn.modal === ariaModalFn) throw new Error('initAriaModalPatch could only be called once');
|
||||
$.fn.modal = ariaModalFn;
|
||||
ariaModalFn.settings = fomanticModalFn.settings;
|
||||
}
|
||||
|
||||
// the patched `$.fn.modal` modal function
|
||||
// * it does the one-time attaching on the first call
|
||||
function ariaModalFn(...args) {
|
||||
const ret = fomanticModalFn.apply(this, args);
|
||||
if (args[0] === 'show' || args[0]?.autoShow) {
|
||||
for (const el of this) {
|
||||
// If there is a form in the modal, there might be a "cancel" button before "ok" button (all buttons are "type=submit" by default).
|
||||
// In such case, the "Enter" key will trigger the "cancel" button instead of "ok" button, then the dialog will be closed.
|
||||
// It breaks the user experience - the "Enter" key should confirm the dialog and submit the form.
|
||||
// So, all "cancel" buttons without "[type]" must be marked as "type=button".
|
||||
$(el).find('form button.cancel:not([type])').attr('type', 'button');
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
import $ from 'jquery';
|
||||
import {initAriaCheckboxPatch} from './aria/checkbox.js';
|
||||
import {initAriaDropdownPatch} from './aria/dropdown.js';
|
||||
import {initAriaModalPatch} from './aria/modal.js';
|
||||
import {svg} from '../svg.js';
|
||||
|
||||
export const fomanticMobileScreen = window.matchMedia('only screen and (max-width: 767.98px)');
|
||||
@ -27,7 +26,6 @@ export function initGiteaFomantic() {
|
||||
// Use the patches to improve accessibility, these patches are designed to be as independent as possible, make it easy to modify or remove in the future.
|
||||
initAriaCheckboxPatch();
|
||||
initAriaDropdownPatch();
|
||||
initAriaModalPatch();
|
||||
}
|
||||
|
||||
function initFomanticApiPatch() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user